diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 4f7c9f0..49f0718 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -89,6 +89,12 @@
             android:entryValues="@array/prefs_suggestion_visibility_values"
             android:entries="@array/prefs_suggestion_visibilities"
             android:defaultValue="@string/prefs_suggestion_visibility_default_value" />
+        <CheckBoxPreference
+            android:key="pref_key_use_personalized_dicts"
+            android:title="@string/use_personalized_dicts"
+            android:summary="@string/use_personalized_dicts_summary"
+            android:persistent="true"
+            android:defaultValue="true" />
     </PreferenceCategory>
     <PreferenceCategory
         android:title="@string/gesture_typing_category"
@@ -134,12 +140,6 @@
                 android:persistent="true"
                 android:defaultValue="true" />
             <CheckBoxPreference
-                android:key="pref_key_use_personalized_dicts"
-                android:title="@string/use_personalized_dicts"
-                android:summary="@string/use_personalized_dicts_summary"
-                android:persistent="true"
-                android:defaultValue="true" />
-            <CheckBoxPreference
                 android:key="pref_key_use_double_space_period"
                 android:title="@string/use_double_space_period"
                 android:summary="@string/use_double_space_period_summary"
diff --git a/java/res/xml/rowkeys_armenian_phonetic2.xml b/java/res/xml/rowkeys_armenian_phonetic2.xml
index 5dcabc3..3764d0d 100644
--- a/java/res/xml/rowkeys_armenian_phonetic2.xml
+++ b/java/res/xml/rowkeys_armenian_phonetic2.xml
@@ -34,6 +34,7 @@
     <Key
         latin:keyLabel="&#x0565;"
         latin:moreKeys="&#x0587;"
+        latin:keyHintLabel="&#x0587;"
         latin:keyLabelFlags="fontNormal" />
     <!-- U+057C: "ռ" ARMENIAN SMALL LETTER RA -->
     <Key
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index fb84f1d..53b4485 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -187,7 +187,7 @@
         final MainKeyboardView keyboardView = mKeyboardView;
         final Keyboard oldKeyboard = keyboardView.getKeyboard();
         keyboardView.setKeyboard(keyboard);
-        mCurrentInputView.setKeyboardGeometry(keyboard.mTopPadding);
+        mCurrentInputView.setKeyboardTopPadding(keyboard.mTopPadding);
         keyboardView.setKeyPreviewPopupEnabled(
                 Settings.readKeyPreviewPopupEnabled(mPrefs, mResources),
                 Settings.readKeyPreviewPopupDismissDelay(mPrefs, mResources));
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index a2528e0..e23d5a7 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -167,10 +167,10 @@
     private static boolean sInGesture = false;
     private static long sGestureFirstDownTime;
     private static TimeRecorder sTimeRecorder;
-    private static final InputPointers sAggregratedPointers = new InputPointers(
+    private static final InputPointers sAggregatedPointers = new InputPointers(
             GestureStroke.DEFAULT_CAPACITY);
-    private static int sLastRecognitionPointSize = 0; // synchronized using sAggregratedPointers
-    private static long sLastRecognitionTime = 0; // synchronized using sAggregratedPointers
+    private static int sLastRecognitionPointSize = 0; // synchronized using sAggregatedPointers
+    private static long sLastRecognitionTime = 0; // synchronized using sAggregatedPointers
 
     static final class BogusMoveEventDetector {
         // Move these thresholds to resource.
@@ -737,8 +737,8 @@
             Log.d(TAG, String.format("[%d] onStartBatchInput", mPointerId));
         }
         sInGesture = true;
-        synchronized (sAggregratedPointers) {
-            sAggregratedPointers.reset();
+        synchronized (sAggregatedPointers) {
+            sAggregatedPointers.reset();
             sLastRecognitionPointSize = 0;
             sLastRecognitionTime = 0;
             sListener.onStartBatchInput();
@@ -769,10 +769,10 @@
     }
 
     private void updateBatchInput(final long eventTime) {
-        synchronized (sAggregratedPointers) {
+        synchronized (sAggregatedPointers) {
             final GestureStroke stroke = mGestureStrokeWithPreviewPoints;
-            stroke.appendIncrementalBatchPoints(sAggregratedPointers);
-            final int size = sAggregratedPointers.getPointerSize();
+            stroke.appendIncrementalBatchPoints(sAggregatedPointers);
+            final int size = sAggregatedPointers.getPointerSize();
             if (size > sLastRecognitionPointSize
                     && stroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) {
                 if (DEBUG_LISTENER) {
@@ -780,18 +780,18 @@
                             size));
                 }
                 sTimerProxy.startUpdateBatchInputTimer(this);
-                sListener.onUpdateBatchInput(sAggregratedPointers);
+                sListener.onUpdateBatchInput(sAggregatedPointers);
                 // The listener may change the size of the pointers (when auto-committing
                 // for example), so we need to get the size from the pointers again.
-                sLastRecognitionPointSize = sAggregratedPointers.getPointerSize();
+                sLastRecognitionPointSize = sAggregatedPointers.getPointerSize();
                 sLastRecognitionTime = eventTime;
             }
         }
     }
 
     private void mayEndBatchInput(final long eventTime) {
-        synchronized (sAggregratedPointers) {
-            mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregratedPointers);
+        synchronized (sAggregatedPointers) {
+            mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregatedPointers);
             if (getActivePointerTrackerCount() == 1) {
                 sInGesture = false;
                 sTimeRecorder.onEndBatchInput(eventTime);
@@ -799,9 +799,9 @@
                 if (!mIsTrackingForActionDisabled) {
                     if (DEBUG_LISTENER) {
                         Log.d(TAG, String.format("[%d] onEndBatchInput   : batchPoints=%d",
-                                mPointerId, sAggregratedPointers.getPointerSize()));
+                                mPointerId, sAggregatedPointers.getPointerSize()));
                     }
-                    sListener.onEndBatchInput(sAggregratedPointers);
+                    sListener.onEndBatchInput(sAggregatedPointers);
                 }
             }
         }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index f708c2c..9f33fcc 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -1811,7 +1811,7 @@
         // U+055A: "՚" ARMENIAN APOSTROPHE
         // U+055B: "՛" ARMENIAN EMPHASIS MARK
         // U+055F: "՟" ARMENIAN ABBREVIATION MARK
-        /* 59 */ "!fixedColumnOrder!8,!,?,\\,,.,\u058A,\u055C,\u055D,\u055E,:,;,@,\u0559,\u055A,\u055B,\u055F",
+        /* 59 */ "!fixedColumnOrder!8,!,?,\u0559,\u055A,.,\u055C,\\,,\u055E,:,;,\u055F,\u00AB,\u00BB,\u058A,\u055D,\u055B",
         /* 60~ */
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
         null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java
index 81ccf83..76b0912 100644
--- a/java/src/com/android/inputmethod/latin/InputView.java
+++ b/java/src/com/android/inputmethod/latin/InputView.java
@@ -23,87 +23,203 @@
 import android.view.View;
 import android.widget.LinearLayout;
 
-public final class InputView extends LinearLayout {
-    private View mSuggestionStripView;
-    private View mKeyboardView;
-    private int mKeyboardTopPadding;
+import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.latin.suggestions.MoreSuggestionsView;
+import com.android.inputmethod.latin.suggestions.SuggestionStripView;
 
-    private boolean mIsForwardingEvent;
+public final class InputView extends LinearLayout {
     private final Rect mInputViewRect = new Rect();
-    private final Rect mEventForwardingRect = new Rect();
-    private final Rect mEventReceivingRect = new Rect();
+    private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder;
+    private MoreSuggestionsViewCanceler mMoreSuggestionsViewCanceler;
 
     public InputView(final Context context, final AttributeSet attrs) {
         super(context, attrs, 0);
     }
 
-    public void setKeyboardGeometry(final int keyboardTopPadding) {
-        mKeyboardTopPadding = keyboardTopPadding;
-    }
-
     @Override
     protected void onFinishInflate() {
-        mSuggestionStripView = findViewById(R.id.suggestion_strip_view);
-        mKeyboardView = findViewById(R.id.keyboard_view);
+        final SuggestionStripView suggestionStripView =
+                (SuggestionStripView)findViewById(R.id.suggestion_strip_view);
+        final MainKeyboardView mainKeyboardView =
+                (MainKeyboardView)findViewById(R.id.keyboard_view);
+        mKeyboardTopPaddingForwarder = new KeyboardTopPaddingForwarder(
+                mainKeyboardView, suggestionStripView);
+        mMoreSuggestionsViewCanceler = new MoreSuggestionsViewCanceler(
+                mainKeyboardView, suggestionStripView);
+    }
+
+    public void setKeyboardTopPadding(final int keyboardTopPadding) {
+        mKeyboardTopPaddingForwarder.setKeyboardTopPadding(keyboardTopPadding);
     }
 
     @Override
     public boolean dispatchTouchEvent(final MotionEvent me) {
-        if (mSuggestionStripView.getVisibility() != VISIBLE
-                || mKeyboardView.getVisibility() != VISIBLE) {
-            return super.dispatchTouchEvent(me);
-        }
-
-        // The touch events that hit the top padding of keyboard should be forwarded to
-        // {@link SuggestionStripView}.
         final Rect rect = mInputViewRect;
-        this.getGlobalVisibleRect(rect);
+        getGlobalVisibleRect(rect);
         final int x = (int)me.getX() + rect.left;
         final int y = (int)me.getY() + rect.top;
 
-        final Rect forwardingRect = mEventForwardingRect;
-        mKeyboardView.getGlobalVisibleRect(forwardingRect);
-        if (!mIsForwardingEvent && !forwardingRect.contains(x, y)) {
-            return super.dispatchTouchEvent(me);
+        // The touch events that hit the top padding of keyboard should be
+        // forwarded to {@link SuggestionStripView}.
+        if (mKeyboardTopPaddingForwarder.dispatchTouchEvent(x, y, me)) {
+            return true;
+        }
+        // To cancel {@link MoreSuggestionsView}, we should intercept a touch event to
+        // {@link MainKeyboardView} and dismiss the {@link MoreSuggestionsView}.
+        if (mMoreSuggestionsViewCanceler.dispatchTouchEvent(x, y, me)) {
+            return true;
+        }
+        return super.dispatchTouchEvent(me);
+    }
+
+    /**
+     * This class forwards series of {@link MotionEvent}s from <code>Forwarder</code> view to
+     * <code>Receiver</code> view.
+     *
+     * @param <Sender> a {@link View} that may send a {@link MotionEvent} to <Receiver>.
+     * @param <Receiver> a {@link View} that receives forwarded {@link MotionEvent} from
+     *     <Forwarder>.
+     */
+    private static abstract class MotionEventForwarder<Sender extends View, Receiver extends View> {
+        protected final Sender mSenderView;
+        protected final Receiver mReceiverView;
+
+        private boolean mIsForwardingEvent;
+        protected final Rect mEventSendingRect = new Rect();
+        protected final Rect mEventReceivingRect = new Rect();
+
+        public MotionEventForwarder(final Sender senderView, final Receiver receiverView) {
+            mSenderView = senderView;
+            mReceiverView = receiverView;
         }
 
-        final int forwardingLimitY = forwardingRect.top + mKeyboardTopPadding;
-        boolean sendToTarget = false;
+        // Return true if a touch event of global coordinate x, y needs to be forwarded.
+        protected abstract boolean needsToForward(final int x, final int y);
 
-        switch (me.getAction()) {
-        case MotionEvent.ACTION_DOWN:
-            if (y < forwardingLimitY) {
-                // This down event and further move and up events should be forwarded to the target.
-                mIsForwardingEvent = true;
-                sendToTarget = true;
+        // Translate global x-coordinate to <code>Receiver</code> local coordinate.
+        protected int translateX(final int x) {
+            return x - mEventReceivingRect.left;
+        }
+
+        // Translate global y-coordinate to <code>Receiver</code> local coordinate.
+        protected int translateY(final int y) {
+            return y - mEventReceivingRect.top;
+        }
+
+        // Callback when a {@link MotionEvent} is forwarded.
+        protected void onForwardingEvent(final MotionEvent me) {}
+
+        // Dispatches a {@link MotioneEvent} to <code>Receiver</code> if needed and returns true.
+        // Otherwise returns false.
+        public boolean dispatchTouchEvent(final int x, final int y, final MotionEvent me) {
+            // Forwards a {link MotionEvent} only if both <code>Sender</code> and
+            // <code>Receiver</code> are visible.
+            if (mSenderView.getVisibility() != View.VISIBLE ||
+                    mReceiverView.getVisibility() != View.VISIBLE) {
+                return false;
             }
-            break;
-        case MotionEvent.ACTION_MOVE:
-            sendToTarget = mIsForwardingEvent;
-            break;
-        case MotionEvent.ACTION_UP:
-        case MotionEvent.ACTION_CANCEL:
-            sendToTarget = mIsForwardingEvent;
-            mIsForwardingEvent = false;
-            break;
+            final Rect sendingRect = mEventSendingRect;
+            mSenderView.getGlobalVisibleRect(sendingRect);
+            if (!mIsForwardingEvent && !sendingRect.contains(x, y)) {
+                return false;
+            }
+
+            boolean shouldForwardToReceiver = false;
+
+            switch (me.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                // If the down event happens in the forwarding area, successive {@link MotionEvent}s
+                // should be forwarded.
+                if (needsToForward(x, y)) {
+                    mIsForwardingEvent = true;
+                    shouldForwardToReceiver = true;
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                shouldForwardToReceiver = mIsForwardingEvent;
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                shouldForwardToReceiver = mIsForwardingEvent;
+                mIsForwardingEvent = false;
+                break;
+            }
+
+            if (!shouldForwardToReceiver) {
+                return false;
+            }
+
+            final Rect receivingRect = mEventReceivingRect;
+            mReceiverView.getGlobalVisibleRect(receivingRect);
+            // Translate global coordinates to <code>Receiver</code> local coordinates.
+            me.setLocation(translateX(x), translateY(y));
+            mReceiverView.dispatchTouchEvent(me);
+            onForwardingEvent(me);
+            return true;
+        }
+    }
+
+    /**
+     * This class forwards {@link MotionEvent}s happened in the top padding of
+     * {@link MainKeyboardView} to {@link SuggestionStripView}.
+     */
+    private static class KeyboardTopPaddingForwarder
+            extends MotionEventForwarder<MainKeyboardView, SuggestionStripView> {
+        private int mKeyboardTopPadding;
+
+        public KeyboardTopPaddingForwarder(final MainKeyboardView mainKeyboardView,
+                final SuggestionStripView suggestionStripView) {
+            super(mainKeyboardView, suggestionStripView);
         }
 
-        if (!sendToTarget) {
-            return super.dispatchTouchEvent(me);
+        public void setKeyboardTopPadding(final int keyboardTopPadding) {
+            mKeyboardTopPadding = keyboardTopPadding;
         }
 
-        final Rect receivingRect = mEventReceivingRect;
-        mSuggestionStripView.getGlobalVisibleRect(receivingRect);
-        final int translatedX = x - receivingRect.left;
-        final int translatedY;
-        if (y < forwardingLimitY) {
-            // The forwarded event should have coordinates that are inside of the target.
-            translatedY = Math.min(y - receivingRect.top, receivingRect.height() - 1);
-        } else {
-            translatedY = y - receivingRect.top;
+        private boolean isInKeyboardTopPadding(final int y) {
+            return y < mEventSendingRect.top + mKeyboardTopPadding;
         }
-        me.setLocation(translatedX, translatedY);
-        mSuggestionStripView.dispatchTouchEvent(me);
-        return true;
+
+        @Override
+        protected boolean needsToForward(final int x, final int y) {
+            return isInKeyboardTopPadding(y);
+        }
+
+        @Override
+        protected int translateY(final int y) {
+            final int translatedY = super.translateY(y);
+            if (isInKeyboardTopPadding(y)) {
+                // The forwarded event should have coordinates that are inside of
+                // the target.
+                return Math.min(translatedY, mEventReceivingRect.height() - 1);
+            }
+            return translatedY;
+        }
+    }
+
+    /**
+     * This class forwards {@link MotionEvent}s happened in the {@link MainKeyboardView} to
+     * {@link SuggestionStripView} when the {@link MoreSuggestionsView} is showing.
+     * {@link SuggestionStripView} dismisses {@link MoreSuggestionsView} when it receives those
+     * events.
+     */
+    private static class MoreSuggestionsViewCanceler
+            extends MotionEventForwarder<MainKeyboardView, SuggestionStripView> {
+        public MoreSuggestionsViewCanceler(final MainKeyboardView mainKeyboardView,
+                final SuggestionStripView suggestionStripView) {
+            super(mainKeyboardView, suggestionStripView);
+        }
+
+        @Override
+        protected boolean needsToForward(final int x, final int y) {
+            return mReceiverView.isShowingMoreSuggestionPanel() && mEventSendingRect.contains(x, y);
+        }
+
+        @Override
+        protected void onForwardingEvent(final MotionEvent me) {
+            if (me.getActionMasked() == MotionEvent.ACTION_DOWN) {
+                mReceiverView.dismissMoreSuggestionsPanel();
+            }
+        }
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 72d5435..67b5702 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -77,9 +77,7 @@
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.define.ProductionFlag;
 import com.android.inputmethod.latin.personalization.DictionaryDecayBroadcastReciever;
-import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
 import com.android.inputmethod.latin.personalization.PersonalizationDictionarySessionRegister;
-import com.android.inputmethod.latin.personalization.PersonalizationHelper;
 import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
 import com.android.inputmethod.latin.settings.Settings;
 import com.android.inputmethod.latin.settings.SettingsActivity;
@@ -179,8 +177,6 @@
 
     private boolean mIsMainDictionaryAvailable;
     private UserBinaryDictionary mUserDictionary;
-    private UserHistoryDictionary mUserHistoryDictionary;
-    private PersonalizationDictionary mPersonalizationDictionary;
     private boolean mIsUserDictionaryAvailable;
 
     private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
@@ -592,9 +588,9 @@
         // the layout; at this time, we need to skip resetting the contacts dictionary. It will
         // be done later inside {@see #initSuggest()} when the reopenDictionaries message is
         // processed.
-        if (!mHandler.hasPendingReopenDictionaries()) {
-            // May need to reset the contacts dictionary depending on the user settings.
-            resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary());
+        if (!mHandler.hasPendingReopenDictionaries() && mSuggest != null) {
+            // May need to reset dictionaries depending on the user settings.
+            mSuggest.setAdditionalDictionaries(mSuggest /* oldSuggest */, mSettings.getCurrent());
         }
     }
 
@@ -640,63 +636,12 @@
         mUserDictionary = new UserBinaryDictionary(this, subtypeLocale);
         mIsUserDictionaryAvailable = mUserDictionary.isEnabled();
         newSuggest.setUserDictionary(mUserDictionary);
-
-        mUserHistoryDictionary = PersonalizationHelper.getUserHistoryDictionary(
-                this, subtypeLocale);
-        newSuggest.setUserHistoryDictionary(mUserHistoryDictionary);
-        mPersonalizationDictionary =
-                PersonalizationHelper.getPersonalizationDictionary(this, subtypeLocale);
-        newSuggest.setPersonalizationDictionary(mPersonalizationDictionary);
-
+        newSuggest.setAdditionalDictionaries(mSuggest /* oldSuggest */, mSettings.getCurrent());
         final Suggest oldSuggest = mSuggest;
-        resetContactsDictionary(null != oldSuggest ? oldSuggest.getContactsDictionary() : null);
         mSuggest = newSuggest;
         if (oldSuggest != null) oldSuggest.close();
     }
 
-    /**
-     * Resets the contacts dictionary in mSuggest according to the user settings.
-     *
-     * This method takes an optional contacts dictionary to use when the locale hasn't changed
-     * since the contacts dictionary can be opened or closed as necessary depending on the settings.
-     *
-     * @param oldContactsDictionary an optional dictionary to use, or null
-     */
-    private void resetContactsDictionary(final ContactsBinaryDictionary oldContactsDictionary) {
-        final Suggest suggest = mSuggest;
-        final boolean shouldSetDictionary =
-                (null != suggest && mSettings.getCurrent().mUseContactsDict);
-
-        final ContactsBinaryDictionary dictionaryToUse;
-        if (!shouldSetDictionary) {
-            // Make sure the dictionary is closed. If it is already closed, this is a no-op,
-            // so it's safe to call it anyways.
-            if (null != oldContactsDictionary) oldContactsDictionary.close();
-            dictionaryToUse = null;
-        } else {
-            final Locale locale = mSubtypeSwitcher.getCurrentSubtypeLocale();
-            if (null != oldContactsDictionary) {
-                if (!oldContactsDictionary.mLocale.equals(locale)) {
-                    // If the locale has changed then recreate the contacts dictionary. This
-                    // allows locale dependent rules for handling bigram name predictions.
-                    oldContactsDictionary.close();
-                    dictionaryToUse = new ContactsBinaryDictionary(this, locale);
-                } else {
-                    // Make sure the old contacts dictionary is opened. If it is already open,
-                    // this is a no-op, so it's safe to call it anyways.
-                    oldContactsDictionary.reopen(this);
-                    dictionaryToUse = oldContactsDictionary;
-                }
-            } else {
-                dictionaryToUse = new ContactsBinaryDictionary(this, locale);
-            }
-        }
-
-        if (null != suggest) {
-            suggest.setContactsDictionary(dictionaryToUse);
-        }
-    }
-
     /* package private */ void resetSuggestMainDict() {
         final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
         mSuggest.resetMainDict(this, subtypeLocale, this /* SuggestInitializationListener */);
@@ -2861,7 +2806,7 @@
         final SettingsValues currentSettings = mSettings.getCurrent();
         if (!currentSettings.mCorrectionEnabled) return null;
 
-        final UserHistoryDictionary userHistoryDictionary = mUserHistoryDictionary;
+        final UserHistoryDictionary userHistoryDictionary = suggest.getUserHistoryDictionary();
         if (userHistoryDictionary == null) return null;
 
         final String prevWord = mConnection.getNthPreviousWord(currentSettings, 2);
@@ -3076,7 +3021,9 @@
         }
         mConnection.deleteSurroundingText(deleteLength, 0);
         if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
-            mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord);
+            if (mSuggest != null) {
+                mSuggest.cancelAddingUserHistory(previousWord, committedWord);
+            }
         }
         final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString;
         if (mSettings.getCurrent().mCurrentLanguageHasSpaces) {
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 0ecb411..32ab1f3 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -25,8 +25,10 @@
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
+import com.android.inputmethod.latin.personalization.PersonalizationHelper;
 import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
 import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.latin.settings.SettingsValues;
 import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
 import com.android.inputmethod.latin.utils.BoundedTreeSet;
 import com.android.inputmethod.latin.utils.CollectionUtils;
@@ -71,7 +73,9 @@
             CollectionUtils.newConcurrentHashMap();
     private HashSet<String> mOnlyDictionarySetForDebug = null;
     private Dictionary mMainDictionary;
-    private ContactsBinaryDictionary mContactsDict;
+    private ContactsBinaryDictionary mContactsDictionary;
+    private UserHistoryDictionary mUserHistoryDictionary;
+    private PersonalizationDictionary mPersonalizationDictionary;
     @UsedForTesting
     private boolean mIsCurrentlyWaitingForMainDictionary = false;
 
@@ -80,10 +84,14 @@
     // Locale used for upper- and title-casing words
     public final Locale mLocale;
 
+    private final Context mContext;
+
     public Suggest(final Context context, final Locale locale,
             final SuggestInitializationListener listener) {
         initAsynchronously(context, locale, listener);
         mLocale = locale;
+        mContext = context;
+        // TODO: Use SettingsValues instead of Settings.
         // initialize a debug flag for the personalization
         if (Settings.readUseOnlyPersonalizationDictionaryForDebug(
                 PreferenceManager.getDefaultSharedPreferences(context))) {
@@ -93,10 +101,11 @@
     }
 
     @UsedForTesting
-    Suggest(final AssetFileAddress[] dictionaryList, final Locale locale) {
+    Suggest(final Context context, final AssetFileAddress[] dictionaryList, final Locale locale) {
         final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(dictionaryList,
                 false /* useFullEditDistance */, locale);
         mLocale = locale;
+        mContext = context;
         mMainDictionary = mainDict;
         addOrReplaceDictionaryInternal(Dictionary.TYPE_MAIN, mainDict);
     }
@@ -163,7 +172,15 @@
     }
 
     public ContactsBinaryDictionary getContactsDictionary() {
-        return mContactsDict;
+        return mContactsDictionary;
+    }
+
+    public UserHistoryDictionary getUserHistoryDictionary() {
+        return mUserHistoryDictionary;
+    }
+
+    public PersonalizationDictionary getPersonalizationDictionary() {
+        return mPersonalizationDictionary;
     }
 
     public ConcurrentHashMap<String, Dictionary> getUnigramDictionaries() {
@@ -184,18 +201,120 @@
      * won't be used.
      */
     public void setContactsDictionary(final ContactsBinaryDictionary contactsDictionary) {
-        mContactsDict = contactsDictionary;
+        mContactsDictionary = contactsDictionary;
         addOrReplaceDictionaryInternal(Dictionary.TYPE_CONTACTS, contactsDictionary);
     }
 
     public void setUserHistoryDictionary(final UserHistoryDictionary userHistoryDictionary) {
+        mUserHistoryDictionary = userHistoryDictionary;
         addOrReplaceDictionaryInternal(Dictionary.TYPE_USER_HISTORY, userHistoryDictionary);
     }
 
     public void setPersonalizationDictionary(
             final PersonalizationDictionary personalizationDictionary) {
-        addOrReplaceDictionaryInternal(Dictionary.TYPE_PERSONALIZATION,
-                personalizationDictionary);
+        mPersonalizationDictionary = personalizationDictionary;
+        addOrReplaceDictionaryInternal(Dictionary.TYPE_PERSONALIZATION, personalizationDictionary);
+    }
+
+    /**
+     * Set dictionaries that can be turned off according to the user settings.
+     *
+     * @param oldSuggest the instance having old dictionaries
+     * @param settingsValues current SettingsValues
+     */
+    public void setAdditionalDictionaries(final Suggest oldSuggest,
+            final SettingsValues settingsValues) {
+        // Contacts dictionary
+        resetContactsDictionary(null != oldSuggest ? oldSuggest.getContactsDictionary() : null,
+                settingsValues);
+        // User history dictionary & Personalization dictionary
+        resetPersonalizedDictionaries(oldSuggest, settingsValues);
+    }
+
+    /**
+     * Set the user history dictionary and personalization dictionary according to the user
+     * settings.
+     *
+     * @param oldSuggest the instance that has been used
+     * @param settingsValues current settingsValues
+     */
+    // TODO: Consolidate resetPersonalizedDictionaries() and resetContactsDictionary(). Call up the
+    // new method for each dictionary.
+    private void resetPersonalizedDictionaries(final Suggest oldSuggest,
+            final SettingsValues settingsValues) {
+        final boolean shouldSetDictionaries = settingsValues.mUsePersonalizedDicts;
+
+        final UserHistoryDictionary oldUserHistoryDictionary = (null == oldSuggest) ? null :
+                oldSuggest.getUserHistoryDictionary();
+        final PersonalizationDictionary oldPersonalizationDictionary = (null == oldSuggest) ? null :
+                oldSuggest.getPersonalizationDictionary();
+        final UserHistoryDictionary userHistoryDictionaryToUse;
+        final PersonalizationDictionary personalizationDictionaryToUse;
+        if (!shouldSetDictionaries) {
+            userHistoryDictionaryToUse = null;
+            personalizationDictionaryToUse = null;
+        } else {
+            if (null != oldUserHistoryDictionary
+                    && oldUserHistoryDictionary.mLocale.equals(mLocale)) {
+                userHistoryDictionaryToUse = oldUserHistoryDictionary;
+            } else {
+                userHistoryDictionaryToUse =
+                        PersonalizationHelper.getUserHistoryDictionary(mContext, mLocale);
+            }
+            if (null != oldPersonalizationDictionary
+                    && oldPersonalizationDictionary.mLocale.equals(mLocale)) {
+                personalizationDictionaryToUse = oldPersonalizationDictionary;
+            } else {
+                personalizationDictionaryToUse =
+                        PersonalizationHelper.getPersonalizationDictionary(mContext, mLocale);
+            }
+        }
+        setUserHistoryDictionary(userHistoryDictionaryToUse);
+        setPersonalizationDictionary(personalizationDictionaryToUse);
+    }
+
+    /**
+     * Set the contacts dictionary according to the user settings.
+     *
+     * This method takes an optional contacts dictionary to use when the locale hasn't changed
+     * since the contacts dictionary can be opened or closed as necessary depending on the settings.
+     *
+     * @param oldContactsDictionary an optional dictionary to use, or null
+     * @param settingsValues current settingsValues
+     */
+    private void resetContactsDictionary(final ContactsBinaryDictionary oldContactsDictionary,
+            final SettingsValues settingsValues) {
+        final boolean shouldSetDictionary = settingsValues.mUseContactsDict;
+        final ContactsBinaryDictionary dictionaryToUse;
+        if (!shouldSetDictionary) {
+            // Make sure the dictionary is closed. If it is already closed, this is a no-op,
+            // so it's safe to call it anyways.
+            if (null != oldContactsDictionary) oldContactsDictionary.close();
+            dictionaryToUse = null;
+        } else {
+            if (null != oldContactsDictionary) {
+                if (!oldContactsDictionary.mLocale.equals(mLocale)) {
+                    // If the locale has changed then recreate the contacts dictionary. This
+                    // allows locale dependent rules for handling bigram name predictions.
+                    oldContactsDictionary.close();
+                    dictionaryToUse = new ContactsBinaryDictionary(mContext, mLocale);
+                } else {
+                    // Make sure the old contacts dictionary is opened. If it is already open,
+                    // this is a no-op, so it's safe to call it anyways.
+                    oldContactsDictionary.reopen(mContext);
+                    dictionaryToUse = oldContactsDictionary;
+                }
+            } else {
+                dictionaryToUse = new ContactsBinaryDictionary(mContext, mLocale);
+            }
+        }
+        setContactsDictionary(dictionaryToUse);
+    }
+
+    public void cancelAddingUserHistory(final String previousWord, final String committedWord) {
+        if (mUserHistoryDictionary != null) {
+            mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord);
+        }
     }
 
     public void setAutoCorrectionThreshold(float threshold) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
index acabea1..2dbb5eb 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
@@ -58,6 +58,7 @@
         public int readInt();
         public int position();
         public void position(int newPosition);
+        @UsedForTesting
         public void put(final byte b);
         public int limit();
         @UsedForTesting
@@ -166,6 +167,7 @@
             return size;
         }
 
+        @UsedForTesting
         static int getCharArraySize(final int[] chars, final int start, final int end) {
             int size = 0;
             for (int i = start; i < end; ++i) {
@@ -262,6 +264,7 @@
          */
         // TODO: Merge this method with writeCharArray and rename the various write* methods to
         // make the difference clear.
+        @UsedForTesting
         static int writeCodePoints(final OutputStream stream, final int[] codePoints,
                 final int startIndex, final int endIndex)
                 throws IOException {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
index 8ba0797..bb40e0d 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.inputmethod.latin.makedict;
 
+import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
 import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
 import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
@@ -245,6 +246,7 @@
         }
     }
 
+    @UsedForTesting
     static void writeUIntToDictBuffer(final DictBuffer dictBuffer, final int value,
             final int size) {
         switch(size) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index efe1b7b..07ba777 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -23,7 +23,6 @@
 import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
 import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
 import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
 import com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
 
 import java.io.File;
@@ -32,7 +31,6 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Stack;
 
@@ -245,6 +243,7 @@
     /**
      * @return the size written, in bytes. Always 3 bytes.
      */
+    @UsedForTesting
     static int writeSInt24ToBuffer(final DictBuffer dictBuffer, final int value) {
         final int absValue = Math.abs(value);
         dictBuffer.put((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
@@ -256,6 +255,7 @@
     /**
      * @return the size written, in bytes. Always 3 bytes.
      */
+    @UsedForTesting
     static int writeSInt24ToStream(final OutputStream destination, final int value)
             throws IOException {
         final int absValue = Math.abs(value);
@@ -265,28 +265,7 @@
         return 3;
     }
 
-    /**
-     * @return the size written, in bytes. 1, 2, or 3 bytes.
-     */
-    private static int writeVariableAddress(final OutputStream destination, final int value)
-            throws IOException {
-        switch (BinaryDictEncoderUtils.getByteSize(value)) {
-        case 1:
-            destination.write((byte)value);
-            break;
-        case 2:
-            destination.write((byte)(0xFF & (value >> 8)));
-            destination.write((byte)(0xFF & value));
-            break;
-        case 3:
-            destination.write((byte)(0xFF & (value >> 16)));
-            destination.write((byte)(0xFF & (value >> 8)));
-            destination.write((byte)(0xFF & value));
-            break;
-        }
-        return BinaryDictEncoderUtils.getByteSize(value);
-    }
-
+    @UsedForTesting
     static void skipString(final DictBuffer dictBuffer,
             final boolean hasMultipleChars) {
         if (hasMultipleChars) {
@@ -300,127 +279,13 @@
     }
 
     /**
-     * Write a PtNode to an output stream from a PtNodeInfo.
-     * A PtNode is an in-memory representation of a node in the patricia trie.
-     * A PtNode info is a container for low-level information about how the
-     * PtNode is stored in the binary format.
-     *
-     * @param destination the stream to write.
-     * @param info the PtNode info to be written.
-     * @return the size written, in bytes.
-     */
-    private static int writePtNode(final OutputStream destination, final PtNodeInfo info)
-            throws IOException {
-        int size = FormatSpec.PTNODE_FLAGS_SIZE;
-        destination.write((byte)info.mFlags);
-        final int parentOffset = info.mParentAddress == FormatSpec.NO_PARENT_ADDRESS ?
-                FormatSpec.NO_PARENT_ADDRESS : info.mParentAddress - info.mOriginalAddress;
-        size += writeSInt24ToStream(destination, parentOffset);
-
-        for (int i = 0; i < info.mCharacters.length; ++i) {
-            if (CharEncoding.getCharSize(info.mCharacters[i]) == 1) {
-                destination.write((byte)info.mCharacters[i]);
-                size++;
-            } else {
-                size += writeSInt24ToStream(destination, info.mCharacters[i]);
-            }
-        }
-        if (info.mCharacters.length > 1) {
-            destination.write((byte)FormatSpec.PTNODE_CHARACTERS_TERMINATOR);
-            size++;
-        }
-
-        if ((info.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0) {
-            destination.write((byte)info.mFrequency);
-            size++;
-        }
-
-        if (DBG) {
-            MakedictLog.d("writePtNode origin=" + info.mOriginalAddress + ", size=" + size
-                    + ", child=" + info.mChildrenAddress + ", characters ="
-                    + new String(info.mCharacters, 0, info.mCharacters.length));
-        }
-        final int childrenOffset = info.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS ?
-                0 : info.mChildrenAddress - (info.mOriginalAddress + size);
-        writeSInt24ToStream(destination, childrenOffset);
-        size += FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
-
-        if (info.mShortcutTargets != null && info.mShortcutTargets.size() > 0) {
-            final int shortcutListSize =
-                    BinaryDictEncoderUtils.getShortcutListSize(info.mShortcutTargets);
-            destination.write((byte)(shortcutListSize >> 8));
-            destination.write((byte)(shortcutListSize & 0xFF));
-            size += 2;
-            final Iterator<WeightedString> shortcutIterator = info.mShortcutTargets.iterator();
-            while (shortcutIterator.hasNext()) {
-                final WeightedString target = shortcutIterator.next();
-                destination.write((byte)BinaryDictEncoderUtils.makeShortcutFlags(
-                        shortcutIterator.hasNext(), target.mFrequency));
-                size++;
-                size += CharEncoding.writeString(destination, target.mWord);
-            }
-        }
-
-        if (info.mBigrams != null) {
-            // TODO: Consolidate this code with the code that computes the size of the bigram list
-            //        in BinaryDictEncoderUtils#computeActualNodeArraySize
-            for (int i = 0; i < info.mBigrams.size(); ++i) {
-
-                final int bigramFrequency = info.mBigrams.get(i).mFrequency;
-                int bigramFlags = (i < info.mBigrams.size() - 1)
-                        ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0;
-                size++;
-                final int bigramOffset = info.mBigrams.get(i).mAddress - (info.mOriginalAddress
-                        + size);
-                bigramFlags |= (bigramOffset < 0) ? FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE : 0;
-                switch (BinaryDictEncoderUtils.getByteSize(bigramOffset)) {
-                case 1:
-                    bigramFlags |= FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE;
-                    break;
-                case 2:
-                    bigramFlags |= FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES;
-                    break;
-                case 3:
-                    bigramFlags |= FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES;
-                    break;
-                }
-                bigramFlags |= bigramFrequency & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY;
-                destination.write((byte)bigramFlags);
-                size += writeVariableAddress(destination, Math.abs(bigramOffset));
-            }
-        }
-        return size;
-    }
-
-    /**
-     * Compute the size of the PtNode.
-     */
-    static int computePtNodeSize(final PtNodeInfo info, final FormatOptions formatOptions) {
-        int size = FormatSpec.PTNODE_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
-                + BinaryDictEncoderUtils.getPtNodeCharactersSize(info.mCharacters)
-                + getChildrenAddressSize(info.mFlags, formatOptions);
-        if ((info.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0) {
-            size += FormatSpec.PTNODE_FREQUENCY_SIZE;
-        }
-        if (info.mShortcutTargets != null && !info.mShortcutTargets.isEmpty()) {
-            size += BinaryDictEncoderUtils.getShortcutListSize(info.mShortcutTargets);
-        }
-        if (info.mBigrams != null) {
-            for (final PendingAttribute attr : info.mBigrams) {
-                size += FormatSpec.PTNODE_FLAGS_SIZE;
-                size += BinaryDictEncoderUtils.getByteSize(attr.mAddress);
-            }
-        }
-        return size;
-    }
-
-    /**
      * Writes a PtNodeCount to the stream.
      *
      * @param destination the stream to write.
      * @param ptNodeCount the count.
      * @return the size written in bytes.
      */
+    @UsedForTesting
     static int writePtNodeCount(final OutputStream destination, final int ptNodeCount)
             throws IOException {
         final int countSize = BinaryDictIOUtils.getPtNodeCountSize(ptNodeCount);
@@ -435,22 +300,6 @@
         return countSize;
     }
 
-    /**
-     * Write a node array to the stream.
-     *
-     * @param destination the stream to write.
-     * @param infos an array of PtNodeInfo to be written.
-     * @return the size written, in bytes.
-     * @throws IOException
-     */
-    static int writeNodes(final OutputStream destination, final PtNodeInfo[] infos)
-            throws IOException {
-        int size = writePtNodeCount(destination, infos.length);
-        for (final PtNodeInfo info : infos) size += writePtNode(destination, info);
-        writeSInt24ToStream(destination, FormatSpec.NO_FORWARD_LINK_ADDRESS);
-        return size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
-    }
-
     private static final int HEADER_READING_BUFFER_SIZE = 16384;
     /**
      * Convenience method to read the header of a binary file.
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictUpdater.java b/java/src/com/android/inputmethod/latin/makedict/DictUpdater.java
deleted file mode 100644
index c4f7ec9..0000000
--- a/java/src/com/android/inputmethod/latin/makedict/DictUpdater.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.makedict;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * An interface of a binary dictionary updater.
- */
-@UsedForTesting
-public interface DictUpdater extends DictDecoder {
-
-    /**
-     * Deletes the word from the binary dictionary.
-     *
-     * @param word the word to be deleted.
-     */
-    @UsedForTesting
-    public void deleteWord(final String word) throws IOException, UnsupportedFormatException;
-
-    /**
-     * Inserts a word into a binary dictionary.
-     *
-     * @param word the word to be inserted.
-     * @param frequency the frequency of the new word.
-     * @param bigramStrings bigram list, or null if none.
-     * @param shortcuts shortcut list, or null if none.
-     * @param isBlackListEntry whether this should be a blacklist entry.
-     */
-    // TODO: Support batch insertion.
-    @UsedForTesting
-    public void insertWord(final String word, final int frequency,
-            final ArrayList<WeightedString> bigramStrings,
-            final ArrayList<WeightedString> shortcuts, final boolean isNotAWord,
-            final boolean isBlackListEntry) throws IOException, UnsupportedFormatException;
-}
diff --git a/java/src/com/android/inputmethod/latin/makedict/SparseTableContentReader.java b/java/src/com/android/inputmethod/latin/makedict/SparseTableContentReader.java
index 06088b6..63e1f56 100644
--- a/java/src/com/android/inputmethod/latin/makedict/SparseTableContentReader.java
+++ b/java/src/com/android/inputmethod/latin/makedict/SparseTableContentReader.java
@@ -58,17 +58,17 @@
      * @param blockSize the block size of the content table.
      * @param baseDir the directory which contains the files of the content table.
      * @param contentFilenames the file names of content files.
-     * @param contentIds the ids of contents. These ids are used for a suffix of a name of
+     * @param contentSuffixes the ids of contents. These ids are used for a suffix of a name of
      * address files and content files.
      * @param factory the DictionaryBufferFactory which is used for opening the files.
      */
     public SparseTableContentReader(final String name, final int blockSize, final File baseDir,
-            final String[] contentFilenames, final String[] contentIds,
+            final String[] contentFilenames, final String[] contentSuffixes,
             final DictionaryBufferFactory factory) {
-        if (contentFilenames.length != contentIds.length) {
+        if (contentFilenames.length != contentSuffixes.length) {
             throw new RuntimeException("The length of contentFilenames and the length of"
-                    + " contentIds are different " + contentFilenames.length + ", "
-                    + contentIds.length);
+                    + " contentSuffixes are different " + contentFilenames.length + ", "
+                    + contentSuffixes.length);
         }
         mBlockSize = blockSize;
         mBaseDir = baseDir;
@@ -79,8 +79,8 @@
         mContentFiles = new File[mContentCount];
         for (int i = 0; i < mContentCount; ++i) {
             mAddressTableFiles[i] = new File(mBaseDir,
-                    name + FormatSpec.CONTENT_TABLE_FILE_SUFFIX + contentIds[i]);
-            mContentFiles[i] = new File(mBaseDir, contentFilenames[i] + contentIds[i]);
+                    name + FormatSpec.CONTENT_TABLE_FILE_SUFFIX + contentSuffixes[i]);
+            mContentFiles[i] = new File(mBaseDir, contentFilenames[i] + contentSuffixes[i]);
         }
         mAddressTableBuffers = new DictBuffer[mContentCount];
         mContentBuffers = new DictBuffer[mContentCount];
@@ -94,27 +94,33 @@
         }
     }
 
-    protected void read(final int contentIndex, final int index,
+    /**
+     * Calls the read() callback of the reader with the appropriate buffer appropriately positioned.
+     * @param contentNumber the index in the original contentFilenames[] array.
+     * @param terminalId the terminal ID to read.
+     * @param reader the reader on which to call the callback.
+     */
+    protected void read(final int contentNumber, final int terminalId,
             final SparseTableContentReaderInterface reader) {
-        if (index < 0 || (index / mBlockSize) * SparseTable.SIZE_OF_INT_IN_BYTES
+        if (terminalId < 0 || (terminalId / mBlockSize) * SparseTable.SIZE_OF_INT_IN_BYTES
                 >= mLookupTableBuffer.limit()) {
             return;
         }
 
-        mLookupTableBuffer.position((index / mBlockSize) * SparseTable.SIZE_OF_INT_IN_BYTES);
-        final int posInAddressTable = mLookupTableBuffer.readInt();
-        if (posInAddressTable == SparseTable.NOT_EXIST) {
+        mLookupTableBuffer.position((terminalId / mBlockSize) * SparseTable.SIZE_OF_INT_IN_BYTES);
+        final int indexInAddressTable = mLookupTableBuffer.readInt();
+        if (indexInAddressTable == SparseTable.NOT_EXIST) {
             return;
         }
 
-        mAddressTableBuffers[contentIndex].position(
-                (posInAddressTable + index % mBlockSize) * SparseTable.SIZE_OF_INT_IN_BYTES);
-        final int address = mAddressTableBuffers[contentIndex].readInt();
+        mAddressTableBuffers[contentNumber].position(SparseTable.SIZE_OF_INT_IN_BYTES
+                * ((indexInAddressTable * mBlockSize) + (terminalId % mBlockSize)));
+        final int address = mAddressTableBuffers[contentNumber].readInt();
         if (address == SparseTable.NOT_EXIST) {
             return;
         }
 
-        mContentBuffers[contentIndex].position(address);
-        reader.read(mContentBuffers[contentIndex]);
+        mContentBuffers[contentNumber].position(address);
+        reader.read(mContentBuffers[contentNumber]);
     }
 }
\ No newline at end of file
diff --git a/java/src/com/android/inputmethod/latin/makedict/SparseTableContentUpdater.java b/java/src/com/android/inputmethod/latin/makedict/SparseTableContentUpdater.java
deleted file mode 100644
index 4518f21..0000000
--- a/java/src/com/android/inputmethod/latin/makedict/SparseTableContentUpdater.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.makedict;
-
-import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFactory;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * An auxiliary class for updating data associated with SparseTable.
- */
-public class SparseTableContentUpdater extends SparseTableContentReader {
-    protected OutputStream mLookupTableOutStream;
-    protected OutputStream[] mAddressTableOutStreams;
-    protected OutputStream[] mContentOutStreams;
-
-    public SparseTableContentUpdater(final String name, final int blockSize,
-            final File baseDir, final String[] contentFilenames, final String[] contentIds,
-            final DictionaryBufferFactory factory) {
-        super(name, blockSize, baseDir, contentFilenames, contentIds, factory);
-        mAddressTableOutStreams = new OutputStream[mContentCount];
-        mContentOutStreams = new OutputStream[mContentCount];
-    }
-
-    protected void openStreamsAndBuffers() throws IOException {
-        openBuffers();
-        mLookupTableOutStream = new FileOutputStream(mLookupTableFile, true /* append */);
-        for (int i = 0; i < mContentCount; ++i) {
-            mAddressTableOutStreams[i] = new FileOutputStream(mAddressTableFiles[i],
-                    true /* append */);
-            mContentOutStreams[i] = new FileOutputStream(mContentFiles[i], true /* append */);
-        }
-    }
-
-    /**
-     * Set the contentIndex-th elements of contentId-th table.
-     *
-     * @param contentId the id of the content table.
-     * @param contentIndex the index where to set the valie.
-     * @param value the value to set.
-     */
-    protected void setContentValue(final int contentId, final int contentIndex, final int value)
-            throws IOException {
-        if ((contentIndex / mBlockSize) * SparseTable.SIZE_OF_INT_IN_BYTES
-                >= mLookupTableBuffer.limit()) {
-            // Need to extend the lookup table
-            final int currentSize = mLookupTableBuffer.limit()
-                    / SparseTable.SIZE_OF_INT_IN_BYTES;
-            final int target = contentIndex / mBlockSize + 1;
-            for (int i = currentSize; i < target; ++i) {
-                BinaryDictEncoderUtils.writeUIntToStream(mLookupTableOutStream,
-                        SparseTable.NOT_EXIST, SparseTable.SIZE_OF_INT_IN_BYTES);
-            }
-            // We need to reopen the byte buffer of the lookup table because a MappedByteBuffer in
-            // Java isn't expanded automatically when the underlying file is expanded.
-            reopenLookupTable();
-        }
-
-        mLookupTableBuffer.position((contentIndex / mBlockSize) * SparseTable.SIZE_OF_INT_IN_BYTES);
-        int posInAddressTable = mLookupTableBuffer.readInt();
-        if (posInAddressTable == SparseTable.NOT_EXIST) {
-            // Need to extend the address table
-            mLookupTableBuffer.position(mLookupTableBuffer.position()
-                    - SparseTable.SIZE_OF_INT_IN_BYTES);
-            posInAddressTable = mAddressTableBuffers[0].limit() / mBlockSize;
-            BinaryDictEncoderUtils.writeUIntToDictBuffer(mLookupTableBuffer,
-                    posInAddressTable, SparseTable.SIZE_OF_INT_IN_BYTES);
-            for (int i = 0; i < mContentCount; ++i) {
-                for (int j = 0; j < mBlockSize; ++j) {
-                    BinaryDictEncoderUtils.writeUIntToStream(mAddressTableOutStreams[i],
-                            SparseTable.NOT_EXIST, SparseTable.SIZE_OF_INT_IN_BYTES);
-                }
-            }
-            // We need to reopen the byte buffers of the address tables because a MappedByteBuffer
-            // in Java isn't expanded automatically when the underlying file is expanded.
-            reopenAddressTables();
-        }
-        posInAddressTable += (contentIndex % mBlockSize) * SparseTable.SIZE_OF_INT_IN_BYTES;
-
-        mAddressTableBuffers[contentId].position(posInAddressTable);
-        BinaryDictEncoderUtils.writeUIntToDictBuffer(mAddressTableBuffers[contentId],
-                value, SparseTable.SIZE_OF_INT_IN_BYTES);
-    }
-
-    private void reopenLookupTable() throws IOException {
-        mLookupTableOutStream.flush();
-        mLookupTableBuffer = mFactory.getDictionaryBuffer(mLookupTableFile);
-    }
-
-    private void reopenAddressTables() throws IOException {
-        for (int i = 0; i < mContentCount; ++i) {
-            mAddressTableOutStreams[i].flush();
-            mAddressTableBuffers[i] = mFactory.getDictionaryBuffer(mAddressTableFiles[i]);
-        }
-    }
-
-    protected void close() throws IOException {
-        mLookupTableOutStream.close();
-        for (final OutputStream stream : mAddressTableOutStreams) {
-            stream.close();
-        }
-        for (final OutputStream stream : mContentOutStreams) {
-            stream.close();
-        }
-    }
-}
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
index e9667ab..ea0a2c6 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
@@ -23,7 +23,6 @@
 import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
 import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
 import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
-import com.android.inputmethod.latin.utils.JniUtils;
 
 import android.util.Log;
 
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
index 3be62f0..7071893 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
@@ -440,6 +440,7 @@
     }
 
     @Override
+    @UsedForTesting
     public void skipPtNode(final FormatOptions formatOptions) {
         final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
         PtNodeReader.readParentAddress(mDictBuffer, formatOptions);
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
index 8eaee4d..d34aa17 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
@@ -91,9 +91,9 @@
             for (final WeightedString word1 : word0.mBigrams) {
                 binaryDict.addBigramWords(word0.mWord, word1.mWord, word1.mFrequency,
                         0 /* timestamp */);
-            }
-            if (binaryDict.needsToRunGC(true /* mindsBlockByGC */)) {
-                binaryDict.flushWithGC();
+                if (binaryDict.needsToRunGC(true /* mindsBlockByGC */)) {
+                    binaryDict.flushWithGC();
+                }
             }
         }
         binaryDict.flushWithGC();
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java
deleted file mode 100644
index 6298295..0000000
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.makedict;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
-import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
-import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-
-/**
- * An implementation of DictUpdater for version 4 binary dictionary.
- */
-@UsedForTesting
-public class Ver4DictUpdater extends Ver4DictDecoder implements DictUpdater {
-    private static final String TAG = Ver4DictUpdater.class.getSimpleName();
-    private static final int MAX_JUMPS = 10000;
-
-    private OutputStream mDictStream;
-    private final File mFrequencyFile;
-
-    @UsedForTesting
-    public Ver4DictUpdater(final File dictDirectory, final int factoryType)
-            throws UnsupportedFormatException {
-        // DictUpdater must have an updatable DictBuffer.
-        super(dictDirectory, ((factoryType & MASK_DICTBUFFER) == USE_BYTEARRAY)
-                ? USE_BYTEARRAY : USE_WRITABLE_BYTEBUFFER);
-        mFrequencyFile = getFile(FILETYPE_FREQUENCY);
-    }
-
-    private static class BigramContentUpdater extends SparseTableContentUpdater {
-        public BigramContentUpdater(final String name, final File baseDir,
-                final boolean hasTimestamp) {
-            super(name + FormatSpec.BIGRAM_FILE_EXTENSION,
-                    FormatSpec.BIGRAM_ADDRESS_TABLE_BLOCK_SIZE, baseDir,
-                    BigramContentReader.getContentFilenames(name, hasTimestamp),
-                    BigramContentReader.getContentIds(hasTimestamp),
-                    new DictionaryBufferFromWritableByteBufferFactory());
-        }
-
-        public void insertBigramEntries(final int terminalId, final int frequency,
-                final ArrayList<PendingAttribute> entries) throws IOException {
-            if (terminalId < 0) {
-                throw new RuntimeException("Invalid terminal id : " + terminalId);
-            }
-            openStreamsAndBuffers();
-
-            if (entries == null || entries.isEmpty()) {
-                setContentValue(FormatSpec.BIGRAM_FREQ_CONTENT_INDEX, terminalId,
-                        SparseTable.NOT_EXIST);
-                return;
-            }
-            final int positionOfEntries =
-                    (int) mContentFiles[FormatSpec.BIGRAM_FREQ_CONTENT_INDEX].length();
-            setContentValue(FormatSpec.BIGRAM_FREQ_CONTENT_INDEX, terminalId, positionOfEntries);
-
-            final Iterator<PendingAttribute> bigramIterator = entries.iterator();
-            while (bigramIterator.hasNext()) {
-                final PendingAttribute entry = bigramIterator.next();
-                final int flags = BinaryDictEncoderUtils.makeBigramFlags(bigramIterator.hasNext(),
-                        0 /* offset */, entry.mFrequency, frequency, "" /* word */);
-                BinaryDictEncoderUtils.writeUIntToStream(
-                        mContentOutStreams[FormatSpec.BIGRAM_FREQ_CONTENT_INDEX], flags,
-                        FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE);
-                BinaryDictEncoderUtils.writeUIntToStream(
-                        mContentOutStreams[FormatSpec.BIGRAM_FREQ_CONTENT_INDEX], entry.mAddress,
-                        FormatSpec.PTNODE_ATTRIBUTE_MAX_ADDRESS_SIZE);
-            }
-            close();
-        }
-    }
-
-    private static class ShortcutContentUpdater extends SparseTableContentUpdater {
-        public ShortcutContentUpdater(final String name, final File baseDir) {
-            super(name + FormatSpec.SHORTCUT_FILE_EXTENSION,
-                    FormatSpec.SHORTCUT_ADDRESS_TABLE_BLOCK_SIZE, baseDir,
-                    new String[] { name + FormatSpec.SHORTCUT_FILE_EXTENSION },
-                    new String[] { FormatSpec.SHORTCUT_CONTENT_ID },
-                    new DictionaryBufferFromWritableByteBufferFactory());
-        }
-
-        public void insertShortcuts(final int terminalId,
-                final ArrayList<WeightedString> shortcuts) throws IOException {
-            if (terminalId < 0) {
-                throw new RuntimeException("Invalid terminal id : " + terminalId);
-            }
-            openStreamsAndBuffers();
-            if (shortcuts == null || shortcuts.isEmpty()) {
-                setContentValue(FormatSpec.SHORTCUT_CONTENT_INDEX, terminalId,
-                        SparseTable.NOT_EXIST);
-                return;
-            }
-
-            final int positionOfShortcuts =
-                    (int) mContentFiles[FormatSpec.SHORTCUT_CONTENT_INDEX].length();
-            setContentValue(FormatSpec.SHORTCUT_CONTENT_INDEX, terminalId, positionOfShortcuts);
-
-            final Iterator<WeightedString> shortcutIterator = shortcuts.iterator();
-            while (shortcutIterator.hasNext()) {
-                final WeightedString target = shortcutIterator.next();
-                final int shortcutFlags = BinaryDictEncoderUtils.makeShortcutFlags(
-                        shortcutIterator.hasNext(), target.mFrequency);
-                BinaryDictEncoderUtils.writeUIntToStream(
-                        mContentOutStreams[FormatSpec.SHORTCUT_CONTENT_INDEX], shortcutFlags,
-                        FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE);
-                CharEncoding.writeString(mContentOutStreams[FormatSpec.SHORTCUT_CONTENT_INDEX],
-                        target.mWord);
-            }
-            close();
-        }
-    }
-
-    @Override
-    public void deleteWord(final String word) throws IOException, UnsupportedFormatException {
-        if (mDictBuffer == null) {
-            openDictBuffer();
-            readHeader();
-        }
-        final int wordPos = getTerminalPosition(word);
-        if (wordPos != FormatSpec.NOT_VALID_WORD) {
-            mDictBuffer.position(wordPos);
-            final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
-            mDictBuffer.position(wordPos);
-            mDictBuffer.put((byte)markAsDeleted(flags));
-        }
-    }
-
-    private int getNewTerminalId() {
-        // The size of frequency file is FormatSpec.FREQUENCY_AND_FLAGS_SIZE * number of terminals
-        // because each terminal always has a frequency.
-        // So we can get a fresh terminal id by this logic.
-        // CAVEAT: we are reading the file size from the disk each time: beware of race conditions,
-        // even on one thread.
-        return (int) (mFrequencyFile.length() / FormatSpec.FREQUENCY_AND_FLAGS_SIZE);
-    }
-
-    private void updateParentPosIfNotMoved(final int nodePos, final int newParentPos,
-            final FormatOptions formatOptions) {
-        final int originalPos = getPosition();
-        setPosition(nodePos);
-        final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
-        if (!BinaryDictIOUtils.isMovedPtNode(flags, formatOptions)) {
-            final int parentOffset = newParentPos - nodePos;
-            BinaryDictIOUtils.writeSInt24ToBuffer(mDictBuffer, parentOffset);
-        }
-        setPosition(originalPos);
-    }
-
-    private void updateParentPositions(final int nodeArrayPos, final int newParentPos,
-            final FormatOptions formatOptions) {
-        final int originalPos = mDictBuffer.position();
-        mDictBuffer.position(nodeArrayPos);
-        int jumpCount = 0;
-        do {
-            final int count = readPtNodeCount();
-            for (int i = 0; i < count; ++i) {
-                updateParentPosIfNotMoved(getPosition(), newParentPos, formatOptions);
-                skipPtNode(formatOptions);
-            }
-            if (!readAndFollowForwardLink()) break;
-        } while (jumpCount++ < MAX_JUMPS);
-        setPosition(originalPos);
-    }
-
-    private void updateChildrenPos(final int nodePos, final int newChildrenPos,
-            final FormatOptions options) {
-        final int originalPos = getPosition();
-        setPosition(nodePos);
-        final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
-        PtNodeReader.readParentAddress(mDictBuffer, options);
-        BinaryDictIOUtils.skipString(mDictBuffer,
-                (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0);
-        if ((flags & FormatSpec.FLAG_IS_TERMINAL) != 0) PtNodeReader.readTerminalId(mDictBuffer);
-        final int basePos = getPosition();
-        BinaryDictIOUtils.writeSInt24ToBuffer(mDictBuffer, newChildrenPos - basePos);
-        setPosition(originalPos);
-    }
-
-    private void updateTerminalPosition(final int terminalId, final int position) {
-        if (terminalId == PtNode.NOT_A_TERMINAL
-                || terminalId * FormatSpec.TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE
-                        >= mTerminalAddressTableBuffer.limit()) return;
-        mTerminalAddressTableBuffer.position(terminalId
-                * FormatSpec.TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE);
-        BinaryDictEncoderUtils.writeUIntToDictBuffer(mTerminalAddressTableBuffer, position,
-                FormatSpec.TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE);
-    }
-
-    private void updateForwardLink(final int nodeArrayPos, final int newForwardLink,
-            final FormatOptions formatOptions) {
-        final int originalPos = getPosition();
-        setPosition(nodeArrayPos);
-        int jumpCount = 0;
-        while (jumpCount++ < MAX_JUMPS) {
-            final int ptNodeCount = readPtNodeCount();
-            for (int i = 0; i < ptNodeCount; ++i) {
-                skipPtNode(formatOptions);
-            }
-            final int forwardLinkPos = getPosition();
-            if (!readAndFollowForwardLink()) {
-                setPosition(forwardLinkPos);
-                BinaryDictIOUtils.writeSInt24ToBuffer(mDictBuffer, newForwardLink - forwardLinkPos);
-                break;
-            }
-        }
-        setPosition(originalPos);
-    }
-
-    private void markPtNodeAsMoved(final int nodePos, final int newNodePos,
-            final FormatOptions options) {
-        final int originalPos = getPosition();
-        updateParentPosIfNotMoved(nodePos, newNodePos, options);
-        setPosition(nodePos);
-        final int currentFlags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
-        setPosition(nodePos);
-        mDictBuffer.put((byte) (FormatSpec.FLAG_IS_MOVED
-                | (currentFlags & (~FormatSpec.MASK_MOVE_AND_DELETE_FLAG))));
-        final int offset = newNodePos - nodePos;
-        BinaryDictIOUtils.writeSInt24ToBuffer(mDictBuffer, offset);
-        setPosition(originalPos);
-    }
-
-    /**
-     * Writes a PtNode to an output stream from a Ver4PtNodeInfo.
-     *
-     * @param nodePos the position of the head of the PtNode.
-     * @param info the PtNode info to be written.
-     * @return the size written, in bytes.
-     */
-    private int writePtNode(final int nodePos, final Ver4PtNodeInfo info) throws IOException {
-        int written = 0;
-
-        // Write flags.
-        mDictStream.write((byte) (info.mFlags & 0xFF));
-        written += FormatSpec.PTNODE_FLAGS_SIZE;
-
-        // Write the parent position.
-        final int parentOffset = info.mParentPos == FormatSpec.NO_PARENT_ADDRESS ?
-                FormatSpec.NO_PARENT_ADDRESS : info.mParentPos - nodePos;
-        BinaryDictIOUtils.writeSInt24ToStream(mDictStream, parentOffset);
-        written += FormatSpec.PARENT_ADDRESS_SIZE;
-
-        // Write a string.
-        if (((info.mFlags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0)
-                != (info.mEndIndexOfCharacters - info.mStartIndexOfCharacters > 1)) {
-            throw new RuntimeException("Inconsistent flags : hasMultipleChars = "
-                    + ((info.mFlags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0) + ", length = "
-                    + (info.mEndIndexOfCharacters - info.mStartIndexOfCharacters));
-        }
-        written += CharEncoding.writeCodePoints(mDictStream, info.mCharacters,
-                info.mStartIndexOfCharacters, info.mEndIndexOfCharacters);
-
-        // Write the terminal id.
-        if ((info.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0) {
-            BinaryDictEncoderUtils.writeUIntToStream(mDictStream, info.mTerminalId,
-                    FormatSpec.PTNODE_TERMINAL_ID_SIZE);
-            written += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
-        }
-
-        // Write the children position.
-        final int childrenOffset = info.mChildrenPos == FormatSpec.NO_CHILDREN_ADDRESS
-                ? 0 : info.mChildrenPos - (nodePos + written);
-        BinaryDictIOUtils.writeSInt24ToStream(mDictStream, childrenOffset);
-        written += FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
-
-        return written;
-    }
-
-    /**
-     * Helper method to split and move PtNode.
-     *
-     * @param ptNodeArrayPos the position of PtNodeArray which contains the split and moved PtNode.
-     * @param splittedPtNodeToMovePos the position of the split and moved PtNode.
-     * @param newParent the parent PtNode after splitting.
-     * @param newChildren the children PtNodes after splitting.
-     * @param newParentStartPos where to write the new parent.
-     * @param formatOptions the format options.
-     */
-    private void writeSplittedPtNodes(final int ptNodeArrayPos, final int splittedPtNodeToMovePos,
-            final Ver4PtNodeInfo newParent, final Ver4PtNodeInfo[] newChildren,
-            final int newParentStartPos,
-            final FormatOptions formatOptions) throws IOException {
-        updateTerminalPosition(newParent.mTerminalId,
-                newParentStartPos + 1 /* size of PtNodeCount */);
-        int written = writePtNodeArray(newParentStartPos, new Ver4PtNodeInfo[] { newParent },
-                FormatSpec.NO_FORWARD_LINK_ADDRESS);
-        final int childrenStartPos = newParentStartPos + written;
-        writePtNodeArray(childrenStartPos, newChildren, FormatSpec.NO_FORWARD_LINK_ADDRESS);
-        int childrenNodePos = childrenStartPos + 1 /* size of PtNodeCount */;
-        for (final Ver4PtNodeInfo info : newChildren) {
-            updateTerminalPosition(info.mTerminalId, childrenNodePos);
-            childrenNodePos += computePtNodeSize(info.mCharacters, info.mStartIndexOfCharacters,
-                    info.mEndIndexOfCharacters,
-                    (info.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0);
-        }
-
-        // Mark as moved.
-        markPtNodeAsMoved(splittedPtNodeToMovePos, newParentStartPos + 1 /* size of PtNodeCount */,
-                formatOptions);
-        updateForwardLink(ptNodeArrayPos, newParentStartPos, formatOptions);
-    }
-
-    /**
-     * Writes a node array to the stream.
-     *
-     * @param nodeArrayPos the position of the head of the node array.
-     * @param infos an array of Ver4PtNodeInfo to be written.
-     * @return the written length in bytes.
-     */
-    private int writePtNodeArray(final int nodeArrayPos, final Ver4PtNodeInfo[] infos,
-            final int forwardLink) throws IOException {
-        int written = BinaryDictIOUtils.writePtNodeCount(mDictStream, infos.length);
-        for (int i = 0; i < infos.length; ++i) {
-            written += writePtNode(nodeArrayPos + written, infos[i]);
-        }
-        BinaryDictIOUtils.writeSInt24ToStream(mDictStream, forwardLink);
-        written += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
-        return written;
-    }
-
-    private int computePtNodeSize(final int[] codePoints, final int startIndex, final int endIndex,
-            final boolean isTerminal) {
-        return FormatSpec.PTNODE_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
-                + CharEncoding.getCharArraySize(codePoints, startIndex, endIndex)
-                + (endIndex - startIndex > 1 ? FormatSpec.PTNODE_TERMINATOR_SIZE : 0)
-                + (isTerminal ? FormatSpec.PTNODE_TERMINAL_ID_SIZE : 0)
-                + FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
-    }
-
-    private void writeNewSinglePtNodeWithAttributes(final int[] codePoints,
-            final boolean hasShortcuts, final int terminalId, final boolean hasBigrams,
-            final boolean isNotAWord, final boolean isBlackListEntry, final int parentPos,
-            final FormatOptions formatOptions) throws IOException {
-        final int newNodeArrayPos = mDictBuffer.limit();
-        final int newNodeFlags = BinaryDictEncoderUtils.makePtNodeFlags(codePoints.length > 1,
-                terminalId != PtNode.NOT_A_TERMINAL, FormatSpec.FLAG_IS_NOT_MOVED, hasShortcuts,
-                hasBigrams, isNotAWord, isBlackListEntry, formatOptions);
-        final Ver4PtNodeInfo info = new Ver4PtNodeInfo(newNodeFlags, codePoints, terminalId,
-                FormatSpec.NO_CHILDREN_ADDRESS, parentPos, 0 /* nodeSize */);
-        writePtNodeArray(newNodeArrayPos, new Ver4PtNodeInfo[] { info },
-                FormatSpec.NO_FORWARD_LINK_ADDRESS);
-    }
-
-    private int setMultipleCharsInFlags(final int currentFlags, final boolean hasMultipleChars) {
-        final int flags;
-        if (hasMultipleChars) {
-            flags = currentFlags | FormatSpec.FLAG_HAS_MULTIPLE_CHARS;
-        } else {
-            flags = currentFlags & (~FormatSpec.FLAG_HAS_MULTIPLE_CHARS);
-        }
-        return flags;
-    }
-
-    private int setIsNotAWordInFlags(final int currentFlags, final boolean isNotAWord) {
-        final int flags;
-        if (isNotAWord) {
-            flags = currentFlags | FormatSpec.FLAG_IS_NOT_A_WORD;
-        } else {
-            flags = currentFlags & (~FormatSpec.FLAG_IS_NOT_A_WORD);
-        }
-        return flags;
-    }
-
-    private int setIsBlackListEntryInFlags(final int currentFlags, final boolean isBlackListEntry) {
-        final int flags;
-        if (isBlackListEntry) {
-            flags = currentFlags | FormatSpec.FLAG_IS_BLACKLISTED;
-        } else {
-            flags = currentFlags & (~FormatSpec.FLAG_IS_BLACKLISTED);
-        }
-        return flags;
-    }
-
-    /**
-     * Splits a PtNode.
-     *
-     *  abcd - ef
-     *
-     * -> inserting "abc"
-     *
-     *  abc - d - ef
-     *
-     * @param nodeArrayToSplitPos the position of PtNodeArray which contains the PtNode to split.
-     * @param nodeToSplitPos the position of the PtNode to split.
-     * @param nodeToSplitInfo the information of the PtNode to split.
-     * @param indexToSplit the index where to split in the code points array.
-     * @param parentOfNodeToSplitPos the absolute position of a parent of the node to split.
-     * @param newTerminalId the terminal id of the inserted node (corresponds to "d").
-     * @param hasShortcuts whether the inserted word should have shortcuts.
-     * @param hasBigrams whether the inserted word should have bigrams.
-     * @param isNotAWord whether the inserted word should be not a word.
-     * @param isBlackListEntry whether the inserted word should be a black list entry.
-     * @param formatOptions the format options.
-     */
-    private void splitOnly(final int nodeArrayToSplitPos, final int nodeToSplitPos,
-            final Ver4PtNodeInfo nodeToSplitInfo, final int indexToSplit,
-            final int parentOfNodeToSplitPos, final int newTerminalId, final boolean hasShortcuts,
-            final boolean hasBigrams, final boolean isNotAWord, final boolean isBlackListEntry,
-            final FormatOptions formatOptions) throws IOException {
-        final int parentNodeArrayStartPos = mDictBuffer.limit();
-        final int parentNodeStartPos = parentNodeArrayStartPos + 1 /* size of PtNodeCount */;
-        final int parentFlags = BinaryDictEncoderUtils.makePtNodeFlags(indexToSplit > 1,
-                true /* isTerminal */, FormatSpec.FLAG_IS_NOT_MOVED, hasShortcuts, hasBigrams,
-                isNotAWord, isBlackListEntry, formatOptions);
-        final Ver4PtNodeInfo parentInfo = new Ver4PtNodeInfo(parentFlags,
-                nodeToSplitInfo.mCharacters, newTerminalId, parentNodeStartPos
-                        + computePtNodeSize(nodeToSplitInfo.mCharacters, 0, indexToSplit, true)
-                        + FormatSpec.FORWARD_LINK_ADDRESS_SIZE,
-                parentOfNodeToSplitPos, 0 /* nodeSize */);
-        parentInfo.mStartIndexOfCharacters = 0;
-        parentInfo.mEndIndexOfCharacters = indexToSplit;
-
-        // Write the child.
-        final int childrenFlags = setMultipleCharsInFlags(nodeToSplitInfo.mFlags,
-                nodeToSplitInfo.mCharacters.length - indexToSplit > 1);
-        final Ver4PtNodeInfo childrenInfo = new Ver4PtNodeInfo(childrenFlags,
-                nodeToSplitInfo.mCharacters, nodeToSplitInfo.mTerminalId,
-                nodeToSplitInfo.mChildrenPos, parentNodeStartPos, 0 /* nodeSize */);
-        childrenInfo.mStartIndexOfCharacters = indexToSplit;
-        childrenInfo.mEndIndexOfCharacters = nodeToSplitInfo.mCharacters.length;
-        if (nodeToSplitInfo.mChildrenPos != FormatSpec.NO_CHILDREN_ADDRESS) {
-            updateParentPositions(nodeToSplitInfo.mChildrenPos,
-                    parentInfo.mChildrenPos + 1 /* size of PtNodeCount */, formatOptions);
-        }
-
-        writeSplittedPtNodes(nodeArrayToSplitPos, nodeToSplitPos, parentInfo,
-                new Ver4PtNodeInfo[] { childrenInfo }, parentNodeArrayStartPos, formatOptions);
-    }
-
-    /**
-     * Split and branch a PtNode.
-     *
-     *   ab - cd
-     *
-     * -> inserting "ac"
-     *
-     * a - b - cd
-     *   |
-     *   - c
-     *
-     * @param nodeArrayToSplitPos the position of PtNodeArray which contains the PtNode to split.
-     * @param nodeToSplitPos the position of the PtNode to split.
-     * @param nodeToSplitInfo the information of the PtNode to split.
-     * @param indexToSplit the index where to split in the code points array.
-     * @param parentOfNodeToSplitPos the absolute position of parent of the node to split.
-     * @param newWordSuffixCodePoints the suffix of the newly inserted word (corresponds to "c").
-     * @param startIndexOfNewWordSuffixCodePoints the start index in newWordSuffixCodePoints where
-     * the suffix starts.
-     * @param newTerminalId the terminal id of the inserted node (correspond to "c").
-     * @param hasShortcuts whether the inserted word should have shortcuts.
-     * @param hasBigrams whether the inserted word should have bigrams.
-     * @param isNotAWord whether the inserted word should be not a word.
-     * @param isBlackListEntry whether the inserted word should be a black list entry.
-     * @param formatOptions the format options.
-     */
-    private void splitAndBranch(final int nodeArrayToSplitPos, final int nodeToSplitPos,
-            final Ver4PtNodeInfo nodeToSplitInfo, final int indexToSplit,
-            final int parentOfNodeToSplitPos, final int[] newWordSuffixCodePoints,
-            final int startIndexOfNewWordSuffixCodePoints,
-            final int newTerminalId,
-            final boolean hasShortcuts, final boolean hasBigrams, final boolean isNotAWord,
-            final boolean isBlackListEntry, final FormatOptions formatOptions) throws IOException {
-        final int parentNodeArrayStartPos = mDictBuffer.limit();
-        final int parentNodeStartPos = parentNodeArrayStartPos + 1 /* size of PtNodeCount */;
-        final int parentFlags = BinaryDictEncoderUtils.makePtNodeFlags(
-                indexToSplit > 1,
-                false /* isTerminal */, FormatSpec.FLAG_IS_NOT_MOVED,
-                false /* hasShortcut */, false /* hasBigrams */,
-                false /* isNotAWord */, false /* isBlackListEntry */, formatOptions);
-        final Ver4PtNodeInfo parentInfo = new Ver4PtNodeInfo(parentFlags,
-                nodeToSplitInfo.mCharacters, PtNode.NOT_A_TERMINAL,
-                parentNodeStartPos
-                        + computePtNodeSize(nodeToSplitInfo.mCharacters, 0, indexToSplit, false)
-                        + FormatSpec.FORWARD_LINK_ADDRESS_SIZE,
-                parentOfNodeToSplitPos, 0 /* nodeSize */);
-        parentInfo.mStartIndexOfCharacters = 0;
-        parentInfo.mEndIndexOfCharacters = indexToSplit;
-
-        final int childrenNodeArrayStartPos = parentNodeStartPos
-                + computePtNodeSize(nodeToSplitInfo.mCharacters, 0, indexToSplit, false)
-                + FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
-        final int firstChildrenFlags = BinaryDictEncoderUtils.makePtNodeFlags(
-                newWordSuffixCodePoints.length - startIndexOfNewWordSuffixCodePoints > 1,
-                true /* isTerminal */, FormatSpec.FLAG_IS_NOT_MOVED, hasShortcuts, hasBigrams,
-                isNotAWord, isBlackListEntry, formatOptions);
-        final Ver4PtNodeInfo firstChildrenInfo = new Ver4PtNodeInfo(firstChildrenFlags,
-                newWordSuffixCodePoints, newTerminalId,
-                FormatSpec.NO_CHILDREN_ADDRESS, parentNodeStartPos,
-                0 /* nodeSize */);
-        firstChildrenInfo.mStartIndexOfCharacters = startIndexOfNewWordSuffixCodePoints;
-        firstChildrenInfo.mEndIndexOfCharacters = newWordSuffixCodePoints.length;
-
-        final int secondChildrenStartPos = childrenNodeArrayStartPos + 1 /* size of ptNodeCount */
-                + computePtNodeSize(newWordSuffixCodePoints, startIndexOfNewWordSuffixCodePoints,
-                        newWordSuffixCodePoints.length, true /* isTerminal */);
-        final int secondChildrenFlags = setMultipleCharsInFlags(nodeToSplitInfo.mFlags,
-                nodeToSplitInfo.mCharacters.length - indexToSplit > 1);
-        final Ver4PtNodeInfo secondChildrenInfo = new Ver4PtNodeInfo(secondChildrenFlags,
-                nodeToSplitInfo.mCharacters, nodeToSplitInfo.mTerminalId,
-                nodeToSplitInfo.mChildrenPos, parentNodeStartPos, 0 /* nodeSize */);
-        secondChildrenInfo.mStartIndexOfCharacters = indexToSplit;
-        secondChildrenInfo.mEndIndexOfCharacters = nodeToSplitInfo.mCharacters.length;
-        if (nodeToSplitInfo.mChildrenPos != FormatSpec.NO_CHILDREN_ADDRESS) {
-            updateParentPositions(nodeToSplitInfo.mChildrenPos, secondChildrenStartPos,
-                    formatOptions);
-        }
-
-        writeSplittedPtNodes(nodeArrayToSplitPos, nodeToSplitPos, parentInfo,
-                new Ver4PtNodeInfo[] { firstChildrenInfo, secondChildrenInfo },
-                parentNodeArrayStartPos, formatOptions);
-    }
-
-    /**
-     * Inserts a word into the trie file and returns the position of inserted terminal node.
-     * If the insertion is failed, returns FormatSpec.NOT_VALID_WORD.
-     */
-    @UsedForTesting
-    private int insertWordToTrie(final String word, final int newTerminalId,
-            final boolean isNotAWord, final boolean isBlackListEntry, final boolean hasBigrams,
-            final boolean hasShortcuts) throws IOException, UnsupportedFormatException {
-        setPosition(0);
-        final FileHeader header = readHeader();
-
-        final int[] codePoints = FusionDictionary.getCodePoints(word);
-        final int wordLen = codePoints.length;
-
-        int wordPos = 0;
-        for (int depth = 0; depth < FormatSpec.MAX_WORD_LENGTH; /* nop */) {
-            final int nodeArrayPos = getPosition();
-            final int ptNodeCount = readPtNodeCount();
-            boolean goToChildren = false;
-            int parentPos = FormatSpec.NO_PARENT_ADDRESS;
-            for (int i = 0; i < ptNodeCount; ++i) {
-                final int nodePos = getPosition();
-                final Ver4PtNodeInfo nodeInfo = readVer4PtNodeInfo(nodePos, header.mFormatOptions);
-                if (BinaryDictIOUtils.isMovedPtNode(nodeInfo.mFlags, header.mFormatOptions)) {
-                    continue;
-                }
-                if (nodeInfo.mParentPos != FormatSpec.NO_PARENT_ADDRESS) {
-                    parentPos = nodePos + nodeInfo.mParentPos;
-                }
-
-                final boolean firstCharacterMatched =
-                        codePoints[wordPos] == nodeInfo.mCharacters[0];
-                boolean allCharactersMatched = true;
-                int firstDifferentCharacterIndex = -1;
-                for (int p = 0; p < nodeInfo.mCharacters.length; ++p) {
-                    if (wordPos + p >= codePoints.length) break;
-                    if (codePoints[wordPos + p] != nodeInfo.mCharacters[p]) {
-                        if (firstDifferentCharacterIndex == -1) {
-                            firstDifferentCharacterIndex = p;
-                        }
-                        allCharactersMatched = false;
-                    }
-                }
-
-                if (!firstCharacterMatched) {
-                    // Go to the next sibling node.
-                    continue;
-                }
-
-                if (!allCharactersMatched) {
-                    final int parentNodeArrayStartPos = mDictBuffer.limit();
-                    splitAndBranch(nodeArrayPos, nodePos, nodeInfo, firstDifferentCharacterIndex,
-                            parentPos, codePoints, wordPos + firstDifferentCharacterIndex,
-                            newTerminalId, hasShortcuts, hasBigrams, isNotAWord,
-                            isBlackListEntry, header.mFormatOptions);
-
-                    return parentNodeArrayStartPos + computePtNodeSize(codePoints, wordPos,
-                            wordPos + firstDifferentCharacterIndex, false)
-                            + FormatSpec.FORWARD_LINK_ADDRESS_SIZE + 1 /* size of PtNodeCount */;
-                }
-
-                if (wordLen - wordPos < nodeInfo.mCharacters.length) {
-                    final int parentNodeArrayStartPos = mDictBuffer.limit();
-                    splitOnly(nodeArrayPos, nodePos, nodeInfo, wordLen - wordPos, parentPos,
-                            newTerminalId, hasShortcuts, hasBigrams, isNotAWord, isBlackListEntry,
-                            header.mFormatOptions);
-
-                    // Return the position of the inserted word.
-                    return parentNodeArrayStartPos + 1 /* size of PtNodeCount */;
-                }
-
-                wordPos += nodeInfo.mCharacters.length;
-                if (wordPos == wordLen) {
-                    // This dictionary already contains the word.
-                    Log.e(TAG, "Something went wrong. If the word is already contained, "
-                            + " there is no need to insert new PtNode.");
-                    return FormatSpec.NOT_VALID_WORD;
-                }
-                if (nodeInfo.mChildrenPos == FormatSpec.NO_CHILDREN_ADDRESS) {
-                    // There are no children.
-                    // We need to add a new node as a child of this node.
-                    final int newNodeArrayPos = mDictBuffer.limit();
-                    final int[] newNodeCodePoints = Arrays.copyOfRange(codePoints, wordPos,
-                            codePoints.length);
-                    writeNewSinglePtNodeWithAttributes(newNodeCodePoints, hasShortcuts,
-                            newTerminalId, hasBigrams, isNotAWord, isBlackListEntry, nodePos,
-                            header.mFormatOptions);
-                    updateChildrenPos(nodePos, newNodeArrayPos, header.mFormatOptions);
-                    return newNodeArrayPos + 1 /* size of PtNodeCount */;
-                } else {
-                    // Found the matched node.
-                    // Go to the children of this node.
-                    setPosition(nodeInfo.mChildrenPos);
-                    goToChildren = true;
-                    depth++;
-                    break;
-                }
-            }
-
-            if (goToChildren) continue;
-            if (!readAndFollowForwardLink()) {
-                // Add a new node that contains [wordPos, word.length()-1].
-                // and update the forward link.
-                final int newNodeArrayPos = mDictBuffer.limit();
-                final int[] newCodePoints = Arrays.copyOfRange(codePoints, wordPos,
-                        codePoints.length);
-                writeNewSinglePtNodeWithAttributes(newCodePoints, hasShortcuts, newTerminalId,
-                        hasBigrams, isNotAWord, isBlackListEntry, parentPos, header.mFormatOptions);
-                updateForwardLink(nodeArrayPos, newNodeArrayPos, header.mFormatOptions);
-                return newNodeArrayPos + 1 /* size of PtNodeCount */;
-            }
-        }
-        return FormatSpec.NOT_VALID_WORD;
-    }
-
-    private void updateFrequency(final int terminalId, final int frequency) {
-        mFrequencyBuffer.position(terminalId * FormatSpec.FREQUENCY_AND_FLAGS_SIZE);
-        BinaryDictEncoderUtils.writeUIntToDictBuffer(mFrequencyBuffer, frequency,
-                FormatSpec.FREQUENCY_AND_FLAGS_SIZE);
-    }
-
-    private void insertFrequency(final int frequency) throws IOException {
-        final OutputStream frequencyStream = new FileOutputStream(mFrequencyFile,
-                true /* append */);
-        BinaryDictEncoderUtils.writeUIntToStream(frequencyStream, frequency,
-                FormatSpec.FREQUENCY_AND_FLAGS_SIZE);
-        frequencyStream.close();
-    }
-
-    private void insertTerminalPosition(final int posOfTerminal) throws IOException,
-            UnsupportedFormatException {
-        final OutputStream terminalPosStream = new FileOutputStream(
-                getFile(FILETYPE_TERMINAL_ADDRESS_TABLE), true /* append */);
-        BinaryDictEncoderUtils.writeUIntToStream(terminalPosStream, posOfTerminal,
-                FormatSpec.TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE);
-        terminalPosStream.close();
-    }
-
-    private void insertBigrams(final int terminalId, final int frequency,
-            final ArrayList<PendingAttribute> bigramAddresses)
-                    throws IOException, UnsupportedFormatException {
-        openDictBuffer();
-        final BigramContentUpdater updater = new BigramContentUpdater(mDictDirectory.getName(),
-                mDictDirectory, false);
-
-        // Convert addresses to terminal ids.
-        final ArrayList<PendingAttribute> bigrams = CollectionUtils.newArrayList();
-        mDictBuffer.position(0);
-        final FileHeader header = readHeader();
-        for (PendingAttribute attr : bigramAddresses) {
-            mDictBuffer.position(attr.mAddress);
-            final Ver4PtNodeInfo info = readVer4PtNodeInfo(attr.mAddress, header.mFormatOptions);
-            if (info.mTerminalId == PtNode.NOT_A_TERMINAL) {
-                throw new RuntimeException("We can't have a bigram target that's not a terminal.");
-            }
-            bigrams.add(new PendingAttribute(frequency, info.mTerminalId));
-        }
-        updater.insertBigramEntries(terminalId, frequency, bigrams);
-        close();
-    }
-
-    private void insertShortcuts(final int terminalId, final ArrayList<WeightedString> shortcuts)
-            throws IOException {
-        final ShortcutContentUpdater updater = new ShortcutContentUpdater(mDictDirectory.getName(),
-                mDictDirectory);
-        updater.insertShortcuts(terminalId, shortcuts);
-    }
-
-    private void openBuffersAndStream() throws IOException, UnsupportedFormatException {
-        openDictBuffer();
-        mDictStream = new FileOutputStream(getFile(FILETYPE_TRIE), true /* append */);
-    }
-
-    private void close() throws IOException {
-        if (mDictStream != null) {
-            mDictStream.close();
-            mDictStream = null;
-        }
-        mDictBuffer = null;
-        mFrequencyBuffer = null;
-        mTerminalAddressTableBuffer = null;
-    }
-
-    private void updateAttributes(final int posOfWord, final int frequency,
-            final ArrayList<WeightedString> bigramStrings,
-            final ArrayList<WeightedString> shortcuts, final boolean isNotAWord,
-            final boolean isBlackListEntry) throws IOException, UnsupportedFormatException {
-        mDictBuffer.position(0);
-        final FileHeader header = readHeader();
-        mDictBuffer.position(posOfWord);
-        final Ver4PtNodeInfo info = readVer4PtNodeInfo(posOfWord, header.mFormatOptions);
-        final int terminalId = info.mTerminalId;
-
-        // Update the flags.
-        final int newFlags = setIsNotAWordInFlags(
-                setIsBlackListEntryInFlags(info.mFlags, isBlackListEntry), isNotAWord);
-        mDictBuffer.position(posOfWord);
-        mDictBuffer.put((byte) newFlags);
-
-        updateFrequency(terminalId, frequency);
-        insertBigrams(terminalId, frequency, resolveBigramPositions(this, bigramStrings));
-        insertShortcuts(terminalId, shortcuts);
-    }
-
-    @Override @UsedForTesting
-    public void insertWord(final String word, final int frequency,
-        final ArrayList<WeightedString> bigramStrings, final ArrayList<WeightedString> shortcuts,
-        final boolean isNotAWord, final boolean isBlackListEntry)
-                throws IOException, UnsupportedFormatException {
-        final int newTerminalId = getNewTerminalId();
-
-        openBuffersAndStream();
-        final int posOfWord = getTerminalPosition(word);
-        if (posOfWord != FormatSpec.NOT_VALID_WORD) {
-            // The word is already contained in the dictionary.
-            updateAttributes(posOfWord, frequency, bigramStrings, shortcuts, isNotAWord,
-                    isBlackListEntry);
-            close();
-            return;
-        }
-
-        // Insert new PtNode into trie.
-        final int posOfTerminal = insertWordToTrie(word, newTerminalId, isNotAWord,
-                isBlackListEntry, bigramStrings != null && !bigramStrings.isEmpty(),
-                shortcuts != null && !shortcuts.isEmpty());
-        insertFrequency(frequency);
-        insertTerminalPosition(posOfTerminal);
-        close();
-
-        insertBigrams(newTerminalId, frequency, resolveBigramPositions(this, bigramStrings));
-        insertShortcuts(newTerminalId, shortcuts);
-    }
-
-    /**
-     * Converts a list of WeightedString to a list of PendingAttribute.
-     */
-    private static ArrayList<PendingAttribute> resolveBigramPositions(final DictUpdater dictUpdater,
-            final ArrayList<WeightedString> bigramStrings)
-                    throws IOException, UnsupportedFormatException {
-        if (bigramStrings == null) return CollectionUtils.newArrayList();
-        final ArrayList<PendingAttribute> bigrams = CollectionUtils.newArrayList();
-        for (final WeightedString bigram : bigramStrings) {
-            final int pos = dictUpdater.getTerminalPosition(bigram.mWord);
-            if (pos == FormatSpec.NOT_VALID_WORD) {
-                // TODO: figure out what is the correct thing to do here.
-            } else {
-                bigrams.add(new PendingAttribute(bigram.mFrequency, pos));
-            }
-        }
-        return bigrams;
-    }
-
-    private static int markAsDeleted(final int flags) {
-        return (flags & (~FormatSpec.MASK_CHILDREN_ADDRESS_TYPE)) | FormatSpec.FLAG_IS_DELETED;
-    }
-}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
index 3a5c115..701c290 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
@@ -55,8 +55,8 @@
 
     public static final int REQUIRED_BINARY_DICTIONARY_VERSION = FormatSpec.VERSION4;
 
-    /** Locale for which this user history dictionary is storing words */
-    private final Locale mLocale;
+    /** The locale for this dictionary. */
+    public final Locale mLocale;
 
     private final String mDictName;
 
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index aa87aff..073148a 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -162,19 +162,19 @@
         mSuggestionsStrip.removeAllViews();
         removeAllViews();
         addView(mSuggestionsStrip);
-        mMoreSuggestionsView.dismissMoreKeysPanel();
+        dismissMoreSuggestionsPanel();
     }
 
     private final MoreSuggestionsListener mMoreSuggestionsListener = new MoreSuggestionsListener() {
         @Override
         public void onSuggestionSelected(final int index, final SuggestedWordInfo wordInfo) {
             mListener.pickSuggestionManually(index, wordInfo);
-            mMoreSuggestionsView.dismissMoreKeysPanel();
+            dismissMoreSuggestionsPanel();
         }
 
         @Override
         public void onCancelInput() {
-            mMoreSuggestionsView.dismissMoreKeysPanel();
+            dismissMoreSuggestionsPanel();
         }
     };
 
@@ -192,10 +192,18 @@
 
         @Override
         public void onCancelMoreKeysPanel(final MoreKeysPanel panel) {
-            mMoreSuggestionsView.dismissMoreKeysPanel();
+            dismissMoreSuggestionsPanel();
         }
     };
 
+    public boolean isShowingMoreSuggestionPanel() {
+        return mMoreSuggestionsView.isShowingInParent();
+    }
+
+    public void dismissMoreSuggestionsPanel() {
+        mMoreSuggestionsView.dismissMoreKeysPanel();
+    }
+
     @Override
     public boolean onLongClick(final View view) {
         AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(
@@ -322,6 +330,6 @@
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        mMoreSuggestionsView.dismissMoreKeysPanel();
+        dismissMoreSuggestionsPanel();
     }
 }
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
index f52f5e7..b5a71f0 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
@@ -34,7 +34,6 @@
 import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -356,25 +355,25 @@
         }
 
         // check bigrams
-        final HashMap<String, List<String>> expBigrams = new HashMap<String, List<String>>();
+        final HashMap<String, Set<String>> expBigrams = new HashMap<String, Set<String>>();
         for (int i = 0; i < expectedBigrams.size(); ++i) {
             final String word1 = expectedWords.get(expectedBigrams.keyAt(i));
             for (int w2 : expectedBigrams.valueAt(i)) {
                 if (expBigrams.get(word1) == null) {
-                    expBigrams.put(word1, new ArrayList<String>());
+                    expBigrams.put(word1, new HashSet<String>());
                 }
                 expBigrams.get(word1).add(expectedWords.get(w2));
             }
         }
 
-        final HashMap<String, List<String>> actBigrams = new HashMap<String, List<String>>();
+        final HashMap<String, Set<String>> actBigrams = new HashMap<String, Set<String>>();
         for (Entry<Integer, ArrayList<PendingAttribute>> entry : resultBigrams.entrySet()) {
             final String word1 = resultWords.get(entry.getKey());
             final int unigramFreq = resultFrequencies.get(entry.getKey());
             for (PendingAttribute attr : entry.getValue()) {
                 final String word2 = resultWords.get(attr.mAddress);
                 if (actBigrams.get(word1) == null) {
-                    actBigrams.put(word1, new ArrayList<String>());
+                    actBigrams.put(word1, new HashSet<String>());
                 }
                 actBigrams.get(word1).add(word2);
 
@@ -383,7 +382,6 @@
                 assertTrue(Math.abs(bigramFreq - BIGRAM_FREQ) < TOLERANCE_OF_BIGRAM_FREQ);
             }
         }
-
         assertEquals(actBigrams, expBigrams);
     }
 
@@ -594,35 +592,4 @@
             Log.d(TAG, result);
         }
     }
-
-    private void runTestDeleteWord(final FormatOptions formatOptions)
-            throws IOException, UnsupportedFormatException {
-        final String dictName = "testDeleteWord";
-        final String dictVersion = Long.toString(System.currentTimeMillis());
-        final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions,
-                getContext().getCacheDir());
-
-        final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
-                BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion));
-        addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */);
-        timeWritingDictToFile(file, dict, formatOptions);
-
-        final DictUpdater dictUpdater = BinaryDictUtils.getDictUpdater(file, formatOptions);
-        MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD,
-                dictUpdater.getTerminalPosition(sWords.get(0)));
-        dictUpdater.deleteWord(sWords.get(0));
-        assertEquals(FormatSpec.NOT_VALID_WORD,
-                dictUpdater.getTerminalPosition(sWords.get(0)));
-
-        MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD,
-                dictUpdater.getTerminalPosition(sWords.get(5)));
-        dictUpdater.deleteWord(sWords.get(5));
-        assertEquals(FormatSpec.NOT_VALID_WORD,
-                dictUpdater.getTerminalPosition(sWords.get(5)));
-    }
-
-    public void testDeleteWord() throws IOException, UnsupportedFormatException {
-        runTestDeleteWord(BinaryDictUtils.VERSION4_OPTIONS_WITHOUT_TIMESTAMP);
-        runTestDeleteWord(BinaryDictUtils.VERSION4_OPTIONS_WITH_TIMESTAMP);
-    }
 }
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
deleted file mode 100644
index 9ed50c4..0000000
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.makedict;
-
-import android.test.AndroidTestCase;
-import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-
-import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
-import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
-import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Random;
-
-@LargeTest
-public class BinaryDictIOUtilsTests extends AndroidTestCase {
-    private static final String TAG = BinaryDictIOUtilsTests.class.getSimpleName();
-
-    private static final ArrayList<String> sWords = CollectionUtils.newArrayList();
-    public static final int DEFAULT_MAX_UNIGRAMS = 1500;
-    private final int mMaxUnigrams;
-
-    private static final String[] CHARACTERS = {
-        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
-        "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
-        "\u00FC" /* ü */, "\u00E2" /* â */, "\u00F1" /* ñ */, // accented characters
-        "\u4E9C" /* 亜 */, "\u4F0A" /* 伊 */, "\u5B87" /* 宇 */, // kanji
-        "\uD841\uDE28" /* 𠘨 */, "\uD840\uDC0B" /* 𠀋 */, "\uD861\uDED7" /* 𨛗 */ // surrogate pair
-    };
-
-    public BinaryDictIOUtilsTests() {
-        // 1500 is the default max unigrams
-        this(System.currentTimeMillis(), DEFAULT_MAX_UNIGRAMS);
-    }
-
-    public BinaryDictIOUtilsTests(final long seed, final int maxUnigrams) {
-        super();
-        Log.d(TAG, "Seed for test is " + seed + ", maxUnigrams is " + maxUnigrams);
-        mMaxUnigrams = maxUnigrams;
-        final Random random = new Random(seed);
-        sWords.clear();
-        for (int i = 0; i < maxUnigrams; ++i) {
-            sWords.add(generateWord(random.nextInt()));
-        }
-    }
-
-    // Utilities for test
-    private String generateWord(final int value) {
-        final int lengthOfChars = CHARACTERS.length;
-        StringBuilder builder = new StringBuilder("");
-        long lvalue = Math.abs((long)value);
-        while (lvalue > 0) {
-            builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]);
-            lvalue /= lengthOfChars;
-        }
-        if (builder.toString().equals("")) return "a";
-        return builder.toString();
-    }
-
-    private static void printPtNode(final PtNodeInfo info) {
-        Log.d(TAG, "    PtNode at " + info.mOriginalAddress);
-        Log.d(TAG, "        flags = " + info.mFlags);
-        Log.d(TAG, "        parentAddress = " + info.mParentAddress);
-        Log.d(TAG, "        characters = " + new String(info.mCharacters, 0,
-                info.mCharacters.length));
-        if (info.mFrequency != -1) Log.d(TAG, "        frequency = " + info.mFrequency);
-        if (info.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {
-            Log.d(TAG, "        children address = no children address");
-        } else {
-            Log.d(TAG, "        children address = " + info.mChildrenAddress);
-        }
-        if (info.mShortcutTargets != null) {
-            for (final WeightedString ws : info.mShortcutTargets) {
-                Log.d(TAG, "        shortcuts = " + ws.mWord);
-            }
-        }
-        if (info.mBigrams != null) {
-            for (final PendingAttribute attr : info.mBigrams) {
-                Log.d(TAG, "        bigram = " + attr.mAddress);
-            }
-        }
-        Log.d(TAG, "    end address = " + info.mEndAddress);
-    }
-
-    private static void printNode(final Ver2DictDecoder dictDecoder,
-            final FormatSpec.FormatOptions formatOptions) {
-        final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
-        Log.d(TAG, "Node at " + dictBuffer.position());
-        final int count = BinaryDictDecoderUtils.readPtNodeCount(dictBuffer);
-        Log.d(TAG, "    ptNodeCount = " + count);
-        for (int i = 0; i < count; ++i) {
-            final PtNodeInfo currentInfo = dictDecoder.readPtNode(dictBuffer.position(),
-                    formatOptions);
-            printPtNode(currentInfo);
-        }
-        if (formatOptions.supportsDynamicUpdate()) {
-            final int forwardLinkAddress = dictBuffer.readUnsignedInt24();
-            Log.d(TAG, "    forwardLinkAddress = " + forwardLinkAddress);
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private static void printBinaryFile(final Ver2DictDecoder dictDecoder)
-            throws IOException, UnsupportedFormatException {
-        final FileHeader fileHeader = dictDecoder.readHeader();
-        final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
-        while (dictBuffer.position() < dictBuffer.limit()) {
-            printNode(dictDecoder, fileHeader.mFormatOptions);
-        }
-    }
-
-    private int getWordPosition(final File file, final String word) {
-        int position = FormatSpec.NOT_VALID_WORD;
-
-        try {
-            final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file,
-                    DictDecoder.USE_READONLY_BYTEBUFFER);
-            position = dictDecoder.getTerminalPosition(word);
-        } catch (IOException e) {
-        } catch (UnsupportedFormatException e) {
-        }
-        return position;
-    }
-
-    /**
-     * Find a word using the DictDecoder.
-     *
-     * @param dictDecoder the dict decoder
-     * @param word the word searched
-     * @return the found ptNodeInfo
-     * @throws IOException
-     * @throws UnsupportedFormatException
-     */
-    private static PtNodeInfo findWordByDictDecoder(final DictDecoder dictDecoder,
-            final String word) throws IOException, UnsupportedFormatException {
-        int position = dictDecoder.getTerminalPosition(word);
-        if (position != FormatSpec.NOT_VALID_WORD) {
-            dictDecoder.setPosition(0);
-            final FileHeader header = dictDecoder.readHeader();
-            dictDecoder.setPosition(position);
-            return dictDecoder.readPtNode(position, header.mFormatOptions);
-        }
-        return null;
-    }
-
-    private PtNodeInfo findWordFromFile(final File file, final String word) {
-        final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file);
-        PtNodeInfo info = null;
-        try {
-            dictDecoder.openDictBuffer();
-            info = findWordByDictDecoder(dictDecoder, word);
-        } catch (IOException e) {
-        } catch (UnsupportedFormatException e) {
-        }
-        return info;
-    }
-
-    // return amount of time to insert a word
-    private long insertAndCheckWord(final File file, final String word, final int frequency,
-            final boolean exist, final ArrayList<WeightedString> bigrams,
-            final ArrayList<WeightedString> shortcuts, final FormatOptions formatOptions) {
-        long amountOfTime = -1;
-        try {
-            final DictUpdater dictUpdater = BinaryDictUtils.getDictUpdater(file, formatOptions);
-
-            if (!exist) {
-                assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
-            }
-            final long now = System.nanoTime();
-            dictUpdater.insertWord(word, frequency, bigrams, shortcuts, false, false);
-            amountOfTime = System.nanoTime() - now;
-            MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
-        } catch (IOException e) {
-            Log.e(TAG, "Raised an IOException while inserting a word", e);
-        } catch (UnsupportedFormatException e) {
-            Log.e(TAG, "Raised an UnsupportedFormatException error while inserting a word", e);
-        }
-        return amountOfTime;
-    }
-
-    private void deleteWord(final File file, final String word, final FormatOptions formatOptions) {
-        try {
-            final DictUpdater dictUpdater = BinaryDictUtils.getDictUpdater(file, formatOptions);
-            dictUpdater.deleteWord(word);
-        } catch (IOException e) {
-            Log.e(TAG, "Raised an IOException while deleting a word", e);
-        } catch (UnsupportedFormatException e) {
-            Log.e(TAG, "Raised an UnsupportedFormatException while deleting a word", e);
-        }
-    }
-
-    private void checkReverseLookup(final File file, final String word, final int position) {
-
-        try {
-            final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file);
-            final FileHeader fileHeader = dictDecoder.readHeader();
-            assertEquals(word,
-                    BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mBodyOffset,
-                            position, fileHeader.mFormatOptions).mWord);
-        } catch (IOException e) {
-            Log.e(TAG, "Raised an IOException while looking up a word", e);
-        } catch (UnsupportedFormatException e) {
-            Log.e(TAG, "Raised an UnsupportedFormatException error while looking up a word", e);
-        }
-    }
-
-    private void runTestInsertWord(final FormatOptions formatOptions) {
-        final String testName = "testInsertWord";
-        final String version = Long.toString(System.currentTimeMillis());
-        final File file = BinaryDictUtils.getDictFile(testName, version, formatOptions,
-                getContext().getCacheDir());
-
-        // set an initial dictionary.
-        final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
-                BinaryDictUtils.makeDictionaryOptions(testName, version));
-        dict.add("abcd", 10, null, false);
-
-        try {
-            final DictEncoder dictEncoder = BinaryDictUtils.getDictEncoder(file, formatOptions);
-            dictEncoder.writeDictionary(dict, formatOptions);
-        } catch (IOException e) {
-            fail("IOException while writing an initial dictionary : " + e);
-        } catch (UnsupportedFormatException e) {
-            fail("UnsupportedFormatException while writing an initial dictionary : " + e);
-        }
-
-        MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd"));
-        insertAndCheckWord(file, "abcde", 10, false, null, null, formatOptions);
-        checkReverseLookup(file, "abcde", getWordPosition(file, "abcde"));
-
-        insertAndCheckWord(file, "abcdefghijklmn", 10, false, null, null, formatOptions);
-        checkReverseLookup(file, "abcdefghijklmn", getWordPosition(file, "abcdefghijklmn"));
-
-        insertAndCheckWord(file, "abcdabcd", 10, false, null, null, formatOptions);
-        checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd"));
-
-        // update the existing word.
-        insertAndCheckWord(file, "abcdabcd", 15, true, null, null, formatOptions);
-        checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd"));
-
-        // Testing splitOnly
-        insertAndCheckWord(file, "ab", 20, false, null, null, formatOptions);
-        checkReverseLookup(file, "ab", getWordPosition(file, "ab"));
-        checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd"));
-        checkReverseLookup(file, "abcde", getWordPosition(file, "abcde"));
-        checkReverseLookup(file, "abcdefghijklmn", getWordPosition(file, "abcdefghijklmn"));
-
-        // Testing splitAndBranch
-        insertAndCheckWord(file, "ami", 30, false, null, null, formatOptions);
-        checkReverseLookup(file, "ami", getWordPosition(file, "ami"));
-        checkReverseLookup(file, "ab", getWordPosition(file, "ab"));
-        checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd"));
-        checkReverseLookup(file, "abcde", getWordPosition(file, "abcde"));
-        checkReverseLookup(file, "abcdefghijklmn", getWordPosition(file, "abcdefghijklmn"));
-        checkReverseLookup(file, "ami", getWordPosition(file, "ami"));
-
-        insertAndCheckWord(file, "abcdefzzzz", 40, false, null, null, formatOptions);
-        checkReverseLookup(file, "abcdefzzzz", getWordPosition(file, "abcdefzzzz"));
-
-        deleteWord(file, "ami", formatOptions);
-        assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "ami"));
-
-        insertAndCheckWord(file, "abcdabfg", 30, false, null, null, formatOptions);
-
-        deleteWord(file, "abcd", formatOptions);
-        assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd"));
-    }
-
-    public void testInsertWord() {
-        runTestInsertWord(BinaryDictUtils.VERSION4_OPTIONS_WITHOUT_TIMESTAMP);
-        runTestInsertWord(BinaryDictUtils.VERSION4_OPTIONS_WITH_TIMESTAMP);
-    }
-
-    private void runTestInsertWordWithBigrams(final FormatOptions formatOptions) {
-        final String testName = "testInsertWordWithBigrams";
-        final String version = Long.toString(System.currentTimeMillis());
-        File file = BinaryDictUtils.getDictFile(testName, version, formatOptions,
-                getContext().getCacheDir());
-
-        // set an initial dictionary.
-        final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
-                BinaryDictUtils.makeDictionaryOptions(testName, version));
-        dict.add("abcd", 10, null, false);
-        dict.add("efgh", 15, null, false);
-
-        try {
-            final DictEncoder dictEncoder = BinaryDictUtils.getDictEncoder(file, formatOptions);
-            dictEncoder.writeDictionary(dict, formatOptions);
-        } catch (IOException e) {
-            fail("IOException while writing an initial dictionary : " + e);
-        } catch (UnsupportedFormatException e) {
-            fail("UnsupportedFormatException while writing an initial dictionary : " + e);
-        }
-
-        final ArrayList<WeightedString> banana = new ArrayList<WeightedString>();
-        banana.add(new WeightedString("banana", 10));
-
-        insertAndCheckWord(file, "banana", 0, false, null, null, formatOptions);
-        insertAndCheckWord(file, "recursive", 60, true, banana, null, formatOptions);
-
-        final PtNodeInfo info = findWordFromFile(file, "recursive");
-        int bananaPos = getWordPosition(file, "banana");
-        assertNotNull(info.mBigrams);
-        assertEquals(info.mBigrams.size(), 1);
-        assertEquals(info.mBigrams.get(0).mAddress, bananaPos);
-    }
-
-    public void testInsertWordWithBigrams() {
-        runTestInsertWordWithBigrams(BinaryDictUtils.VERSION4_OPTIONS_WITHOUT_TIMESTAMP);
-        runTestInsertWordWithBigrams(BinaryDictUtils.VERSION4_OPTIONS_WITH_TIMESTAMP);
-    }
-
-    private void runTestRandomWords(final FormatOptions formatOptions) {
-        final String testName = "testRandomWord";
-        final String version = Long.toString(System.currentTimeMillis());
-        final File file = BinaryDictUtils.getDictFile(testName, version, formatOptions,
-                getContext().getCacheDir());
-
-        // set an initial dictionary.
-        final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
-                BinaryDictUtils.makeDictionaryOptions(testName, version));
-        dict.add("initial", 10, null, false);
-
-        try {
-            final DictEncoder dictEncoder = BinaryDictUtils.getDictEncoder(file, formatOptions);
-            dictEncoder.writeDictionary(dict, formatOptions);
-        } catch (IOException e) {
-            assertTrue(false);
-        } catch (UnsupportedFormatException e) {
-            assertTrue(false);
-        }
-
-        long maxTimeToInsert = 0, sum = 0;
-        long minTimeToInsert = 100000000; // 1000000000 is an upper bound for minTimeToInsert.
-        int cnt = 0;
-        for (final String word : sWords) {
-            final long diff = insertAndCheckWord(file, word,
-                    cnt % FormatSpec.MAX_TERMINAL_FREQUENCY, false, null, null, formatOptions);
-            maxTimeToInsert = Math.max(maxTimeToInsert, diff);
-            minTimeToInsert = Math.min(minTimeToInsert, diff);
-            sum += diff;
-            cnt++;
-        }
-        cnt = 0;
-        for (final String word : sWords) {
-            MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
-        }
-
-        Log.d(TAG, "Test version " + formatOptions.mVersion);
-        Log.d(TAG, "max = " + ((double)maxTimeToInsert/1000000) + " ms.");
-        Log.d(TAG, "min = " + ((double)minTimeToInsert/1000000) + " ms.");
-        Log.d(TAG, "avg = " + ((double)sum/mMaxUnigrams/1000000) + " ms.");
-    }
-
-    public void testRandomWords() {
-        runTestRandomWords(BinaryDictUtils.VERSION4_OPTIONS_WITHOUT_TIMESTAMP);
-        runTestRandomWords(BinaryDictUtils.VERSION4_OPTIONS_WITH_TIMESTAMP);
-    }
-}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
index 67d77e0..f7a808c 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
@@ -69,14 +69,4 @@
                     + formatOptions.mVersion);
         }
     }
-
-    public static DictUpdater getDictUpdater(final File file, final FormatOptions formatOptions)
-            throws UnsupportedFormatException {
-        if (formatOptions.mVersion == FormatSpec.VERSION4) {
-            return new Ver4DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER);
-        } else {
-            throw new UnsupportedFormatException("The format option has a wrong version : "
-                    + formatOptions.mVersion);
-        }
-    }
 }
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Test.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Test.java
index 9174238..48817b1 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Test.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Test.java
@@ -18,7 +18,6 @@
 
 import com.android.inputmethod.latin.makedict.BinaryDictDecoderEncoderTests;
 import com.android.inputmethod.latin.makedict.BinaryDictEncoderFlattenTreeTests;
-import com.android.inputmethod.latin.makedict.BinaryDictIOUtilsTests;
 import com.android.inputmethod.latin.makedict.FusionDictionaryTest;
 
 import java.lang.reflect.Constructor;
@@ -31,15 +30,15 @@
  */
 public class Test extends Dicttool.Command {
     public static final String COMMAND = "test";
+    private static final int DEFAULT_MAX_UNIGRAMS = 1500;
     private long mSeed = System.currentTimeMillis();
-    private int mMaxUnigrams = BinaryDictIOUtilsTests.DEFAULT_MAX_UNIGRAMS;
+    private int mMaxUnigrams = DEFAULT_MAX_UNIGRAMS;
 
     private static final Class<?>[] sClassesToTest = {
         BinaryDictOffdeviceUtilsTests.class,
         FusionDictionaryTest.class,
         BinaryDictDecoderEncoderTests.class,
         BinaryDictEncoderFlattenTreeTests.class,
-        BinaryDictIOUtilsTests.class
     };
     private ArrayList<Method> mAllTestMethods = new ArrayList<Method>();
     private ArrayList<String> mUsedTestMethods = new ArrayList<String>();
diff --git a/tools/make-keyboard-text/res/values-hy-rAM/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-hy-rAM/donottranslate-more-keys.xml
index a94d50e..73fe927 100644
--- a/tools/make-keyboard-text/res/values-hy-rAM/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-hy-rAM/donottranslate-more-keys.xml
@@ -26,7 +26,7 @@
     <!-- U+055A: "՚" ARMENIAN APOSTROPHE -->
     <!-- U+055B: "՛" ARMENIAN EMPHASIS MARK -->
     <!-- U+055F: "՟" ARMENIAN ABBREVIATION MARK -->
-    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,!,?,\\,,.,&#x058A;,&#x055C;,&#x055D;,&#x055E;,:,;,\@,&#x0559;,&#x055A;,&#x055B;,&#x055F;"</string>
+    <string name="more_keys_for_punctuation">"!fixedColumnOrder!8,!,?,&#x0559;,&#x055A;,.,&#x055C;,\\,,&#x055E;,:,;,&#x055F;,&#x00AB;,&#x00BB;,&#x058A;,&#x055D;,&#x055B;"</string>
     <!-- U+055E: "՞" ARMENIAN QUESTION MARK -->
     <!-- U+00BF: "¿" INVERTED QUESTION MARK -->
     <string name="more_keys_for_question">&#x055E;,&#x00BF;</string>
