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/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 1400e05..4b6e12f 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -932,11 +932,7 @@
     @Override
     public void onShowMoreKeysPanel(final MoreKeysPanel panel) {
         locatePreviewPlacerView();
-        // TODO: Remove this check
-        if (panel.isShowingInParent()) {
-            panel.dismissMoreKeysPanel();
-        }
-        mPreviewPlacerView.addView(panel.getContainerView());
+        panel.showInParent(mPreviewPlacerView);
         mMoreKeysPanel = panel;
         dimEntireKeyboard(true /* dimmed */);
     }
@@ -954,7 +950,7 @@
     public void onDismissMoreKeysPanel(final MoreKeysPanel panel) {
         dimEntireKeyboard(false /* dimmed */);
         if (isShowingMoreKeysPanel()) {
-            mPreviewPlacerView.removeView(mMoreKeysPanel.getContainerView());
+            mMoreKeysPanel.removeFromParent();
             mMoreKeysPanel = null;
         }
     }
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index a7c4685..5b13e9a 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -21,6 +21,7 @@
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
@@ -216,12 +217,26 @@
         return true;
     }
 
-    @Override
-    public View getContainerView() {
+    private View getContainerView() {
         return (View)getParent();
     }
 
     @Override
+    public void showInParent(final ViewGroup parentView) {
+        removeFromParent();
+        parentView.addView(getContainerView());
+    }
+
+    @Override
+    public void removeFromParent() {
+        final View containerView = getContainerView();
+        final ViewGroup currentParent = (ViewGroup)containerView.getParent();
+        if (currentParent != null) {
+            currentParent.removeView(containerView);
+        }
+    }
+
+    @Override
     public boolean isShowingInParent() {
         return (getContainerView().getParent() != null);
     }
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
index 886c628..4a33e65 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
@@ -17,6 +17,7 @@
 package com.android.inputmethod.keyboard;
 
 import android.view.View;
+import android.view.ViewGroup;
 
 public interface MoreKeysPanel {
     public interface Controller {
@@ -119,9 +120,16 @@
     public int translateY(int y);
 
     /**
-     * Return the view containing the more keys panel.
+     * Show this {@link MoreKeysPanel} in the parent view.
+     *
+     * @param parentView the {@link ViewGroup} that hosts this {@link MoreKeysPanel}.
      */
-    public View getContainerView();
+    public void showInParent(ViewGroup parentView);
+
+    /**
+     * Remove this {@link MoreKeysPanel} from the parent view.
+     */
+    public void removeFromParent();
 
     /**
      * Return whether the panel is currently being shown.
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 770ea49..67b5702 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1414,7 +1414,7 @@
                 ResearchLogger.latinIME_maybeDoubleSpacePeriod(textToInsert,
                         false /* isBatchMode */);
             }
-            mWordComposer.doubleSpacePeriod();
+            mWordComposer.discardPreviousWordForSuggestion();
             mKeyboardSwitcher.updateShiftState();
             return true;
         }
@@ -2510,29 +2510,23 @@
         final SettingsValues currentSettings = mSettings.getCurrent();
         final int[] additionalFeaturesOptions = currentSettings.mAdditionalFeaturesSettingValues;
 
-        final String previousWord;
-        if (mWordComposer.isComposingWord() || mWordComposer.isBatchMode()) {
-            previousWord = mWordComposer.getPreviousWord();
-        } else {
-            // Not composing: this is for prediction.
-            // TODO: read the previous word earlier for prediction, like we are doing for
-            // normal suggestions.
-            previousWord = getNthPreviousWordForSuggestion(currentSettings, 1 /* nthPreviousWord*/);
-        }
         if (DEBUG) {
-            // TODO: this is for checking consistency with older versions. Remove this when
-            // we are confident this is stable.
-            // We're checking the previous word in the text field against the memorized previous
-            // word. If we are composing a word we should have the second word before the cursor
-            // memorized, otherwise we should have the first.
-            final String rereadPrevWord = getNthPreviousWordForSuggestion(currentSettings,
-                    mWordComposer.isComposingWord() ? 2 : 1);
-            if (!TextUtils.equals(previousWord, rereadPrevWord)) {
-                throw new RuntimeException("Unexpected previous word: "
-                        + previousWord + " <> " + rereadPrevWord);
+            if (mWordComposer.isComposingWord() || mWordComposer.isBatchMode()) {
+                final String previousWord = mWordComposer.getPreviousWordForSuggestion();
+                // TODO: this is for checking consistency with older versions. Remove this when
+                // we are confident this is stable.
+                // We're checking the previous word in the text field against the memorized previous
+                // word. If we are composing a word we should have the second word before the cursor
+                // memorized, otherwise we should have the first.
+                final String rereadPrevWord = getNthPreviousWordForSuggestion(currentSettings,
+                        mWordComposer.isComposingWord() ? 2 : 1);
+                if (!TextUtils.equals(previousWord, rereadPrevWord)) {
+                    throw new RuntimeException("Unexpected previous word: "
+                            + previousWord + " <> " + rereadPrevWord);
+                }
             }
         }
-        suggest.getSuggestedWords(mWordComposer, mWordComposer.getPreviousWord(),
+        suggest.getSuggestedWords(mWordComposer, mWordComposer.getPreviousWordForSuggestion(),
                 keyboard.getProximityInfo(),
                 currentSettings.mBlockPotentiallyOffensive, currentSettings.mCorrectionEnabled,
                 additionalFeaturesOptions, sessionId, sequenceNumber, callback);
@@ -2775,6 +2769,19 @@
         // strings.
         mLastComposedWord = mWordComposer.commitWord(commitType, chosenWord, separatorString,
                 prevWord);
+        final boolean shouldDiscardPreviousWordForSuggestion;
+        if (0 == StringUtils.codePointCount(separatorString)) {
+            // Separator is 0-length. Discard the word only if the current language has spaces.
+            shouldDiscardPreviousWordForSuggestion =
+                    mSettings.getCurrent().mCurrentLanguageHasSpaces;
+        } else {
+            // Otherwise, we discard if the separator contains any non-whitespace.
+            shouldDiscardPreviousWordForSuggestion =
+                    !StringUtils.containsOnlyWhitespace(separatorString);
+        }
+        if (shouldDiscardPreviousWordForSuggestion) {
+            mWordComposer.discardPreviousWordForSuggestion();
+        }
     }
 
     private void setPunctuationSuggestions() {
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 5ecfc67..7da97e5 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -50,8 +50,9 @@
     private final StringBuilder mTypedWord;
     // The previous word (before the composing word). Used as context for suggestions. May be null
     // after resetting and before starting a new composing word, or when there is no context like
-    // at the start of text for example.
-    private String mPreviousWord;
+    // at the start of text for example. It can also be set to null externally when the user
+    // enters a separator that does not let bigrams across, like a period or a comma.
+    private String mPreviousWordForSuggestion;
     private String mAutoCorrection;
     private boolean mIsResumed;
     private boolean mIsBatchMode;
@@ -89,7 +90,7 @@
         mIsBatchMode = false;
         mCursorPositionWithinWord = 0;
         mRejectedBatchModeSuggestion = null;
-        mPreviousWord = null;
+        mPreviousWordForSuggestion = null;
         refreshSize();
     }
 
@@ -106,7 +107,7 @@
         mIsBatchMode = source.mIsBatchMode;
         mCursorPositionWithinWord = source.mCursorPositionWithinWord;
         mRejectedBatchModeSuggestion = source.mRejectedBatchModeSuggestion;
-        mPreviousWord = source.mPreviousWord;
+        mPreviousWordForSuggestion = source.mPreviousWordForSuggestion;
         refreshSize();
     }
 
@@ -124,7 +125,7 @@
         mIsBatchMode = false;
         mCursorPositionWithinWord = 0;
         mRejectedBatchModeSuggestion = null;
-        mPreviousWord = null;
+        mPreviousWordForSuggestion = null;
         refreshSize();
     }
 
@@ -305,7 +306,7 @@
             addKeyInfo(codePoint, keyboard);
         }
         mIsResumed = true;
-        mPreviousWord = previousWord;
+        mPreviousWordForSuggestion = previousWord;
     }
 
     /**
@@ -356,8 +357,8 @@
         return mTypedWord.toString();
     }
 
-    public String getPreviousWord() {
-        return mPreviousWord;
+    public String getPreviousWordForSuggestion() {
+        return mPreviousWordForSuggestion;
     }
 
     /**
@@ -419,7 +420,7 @@
     public void setCapitalizedModeAndPreviousWordAtStartComposingTime(final int mode,
             final String previousWord) {
         mCapitalizedMode = mode;
-        mPreviousWord = previousWord;
+        mPreviousWordForSuggestion = previousWord;
     }
 
     /**
@@ -471,12 +472,7 @@
         mCapsCount = 0;
         mDigitsCount = 0;
         mIsBatchMode = false;
-        final boolean isWhitespace = 1 == StringUtils.codePointCount(separatorString)
-                && Character.isWhitespace(separatorString.codePointAt(0));
-        // If not whitespace, we don't use the previous word for suggestion. This is consistent
-        // with how we get the previous word for suggestion: see RichInputConnection#spaceRegex and
-        // LatinIME#getNthPreviousWordForSuggestion.
-        mPreviousWord = isWhitespace ? mTypedWord.toString() : null;
+        mPreviousWordForSuggestion = mTypedWord.toString();
         mTypedWord.setLength(0);
         mCodePointSize = 0;
         mTrailingSingleQuotesCount = 0;
@@ -490,11 +486,11 @@
         return lastComposedWord;
     }
 
-    public void doubleSpacePeriod() {
-        // When a period was entered with a double space, the separator we got has been
-        // changed by a period (see #commitWord). We should not use the previous word for
-        // suggestion.
-        mPreviousWord = null;
+    // Call this when the recorded previous word should be discarded. This is typically called
+    // when the user inputs a separator that's not whitespace (including the case of the
+    // double-space-to-period feature).
+    public void discardPreviousWordForSuggestion() {
+        mPreviousWordForSuggestion = null;
     }
 
     public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord,
@@ -509,7 +505,7 @@
         mCursorPositionWithinWord = mCodePointSize;
         mRejectedBatchModeSuggestion = null;
         mIsResumed = true;
-        mPreviousWord = previousWord;
+        mPreviousWordForSuggestion = previousWord;
     }
 
     public boolean isBatchMode() {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
index 7f0aa77..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 {
@@ -436,7 +439,7 @@
             final FormatOptions options) {
         dictDecoder.setPosition(headerSize);
         final int count = dictDecoder.readPtNodeCount();
-        int groupPos = headerSize + BinaryDictIOUtils.getPtNodeCountSize(count);
+        int groupPos = dictDecoder.getPosition();
         final StringBuilder builder = new StringBuilder();
         WeightedString result = null;
 
@@ -498,9 +501,9 @@
         do { // Scan the linked-list node.
             final int nodeArrayHeadPos = dictDecoder.getPosition();
             final int count = dictDecoder.readPtNodeCount();
-            int groupOffsetPos = nodeArrayHeadPos + BinaryDictIOUtils.getPtNodeCountSize(count);
+            int groupPos = dictDecoder.getPosition();
             for (int i = count; i > 0; --i) { // Scan the array of PtNode.
-                PtNodeInfo info = dictDecoder.readPtNode(groupOffsetPos, options);
+                PtNodeInfo info = dictDecoder.readPtNode(groupPos, options);
                 if (BinaryDictIOUtils.isMovedPtNode(info.mFlags, options)) continue;
                 ArrayList<WeightedString> shortcutTargets = info.mShortcutTargets;
                 ArrayList<WeightedString> bigrams = null;
@@ -536,7 +539,7 @@
                                     0 != (info.mFlags & FormatSpec.FLAG_IS_NOT_A_WORD),
                                     0 != (info.mFlags & FormatSpec.FLAG_IS_BLACKLISTED)));
                 }
-                groupOffsetPos = info.mEndAddress;
+                groupPos = info.mEndAddress;
             }
 
             // reach the end of the array.
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 640d778..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;
 
@@ -87,7 +85,7 @@
 
             if (p.mNumOfPtNode == Position.NOT_READ_PTNODE_COUNT) {
                 p.mNumOfPtNode = dictDecoder.readPtNodeCount();
-                p.mAddress += getPtNodeCountSize(p.mNumOfPtNode);
+                p.mAddress = dictDecoder.getPosition();
                 p.mPosition = 0;
             }
             if (p.mNumOfPtNode == 0) {
@@ -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/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index af54805..437fa94 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -188,7 +188,7 @@
     // us to change the format during development while having testing devices remove
     // older files with each upgrade, while still having a readable versioning scheme.
     public static final int VERSION2 = 2;
-    public static final int VERSION4 = 400;
+    public static final int VERSION4 = 401;
     static final int MINIMUM_SUPPORTED_VERSION = VERSION2;
     static final int MAXIMUM_SUPPORTED_VERSION = VERSION4;
 
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/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/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
index df42041..85f4454 100644
--- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -250,6 +250,24 @@
         return true;
     }
 
+    /**
+     * Returns true if all code points in text are whitespace, false otherwise. Empty is true.
+     */
+    // Interestingly enough, U+00A0 NO-BREAK SPACE and U+200B ZERO-WIDTH SPACE are not considered
+    // whitespace, while EN SPACE, EM SPACE and IDEOGRAPHIC SPACES are.
+    public static boolean containsOnlyWhitespace(final String text) {
+        final int length = text.length();
+        int i = 0;
+        while (i < length) {
+            final int codePoint = text.codePointAt(i);
+            if (!Character.isWhitespace(codePoint)) {
+                return false;
+            }
+            i += Character.charCount(codePoint);
+        }
+        return true;
+    }
+
     @UsedForTesting
     public static boolean looksValidForDictionaryInsertion(final CharSequence text,
             final SettingsValues settings) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp
index 9afb5f2..deed010 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp
@@ -48,9 +48,9 @@
 const int Ver4DictConstants::WORD_LEVEL_FIELD_SIZE = 1;
 const int Ver4DictConstants::WORD_COUNT_FIELD_SIZE = 1;
 
-const int Ver4DictConstants::BIGRAM_ADDRESS_TABLE_BLOCK_SIZE = 4;
+const int Ver4DictConstants::BIGRAM_ADDRESS_TABLE_BLOCK_SIZE = 16;
 const int Ver4DictConstants::BIGRAM_ADDRESS_TABLE_DATA_SIZE = 4;
-const int Ver4DictConstants::SHORTCUT_ADDRESS_TABLE_BLOCK_SIZE = 16;
+const int Ver4DictConstants::SHORTCUT_ADDRESS_TABLE_BLOCK_SIZE = 64;
 const int Ver4DictConstants::SHORTCUT_ADDRESS_TABLE_DATA_SIZE = 4;
 
 const int Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE = 3;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h
index eb2227d..7c6a21d 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h
@@ -31,7 +31,7 @@
     enum FORMAT_VERSION {
         // These MUST have the same values as the relevant constants in FormatSpec.java.
         VERSION_2 = 2,
-        VERSION_4 = 400,
+        VERSION_4 = 401,
         UNKNOWN_VERSION = -1
     };
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/sparse_table.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/sparse_table.cpp
index 4ad82f9..c380429 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/sparse_table.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/sparse_table.cpp
@@ -34,7 +34,8 @@
     const int indexTableReadingPos = getPosInIndexTable(id);
     const int index = mIndexTableBuffer->readUint(INDEX_SIZE, indexTableReadingPos);
     const int contentTableReadingPos = getPosInContentTable(id, index);
-    return mContentTableBuffer->readUint(mDataSize, contentTableReadingPos);
+    const int contentValue = mContentTableBuffer->readUint(mDataSize, contentTableReadingPos);
+    return contentValue == NOT_EXIST ? NOT_A_DICT_POS : contentValue;
 }
 
 bool SparseTable::set(const int id, const uint32_t value) {
@@ -70,7 +71,7 @@
     // Write a new block that containing the entry to be set.
     int writingPos = getPosInContentTable(0 /* id */, index);
     for (int i = 0; i < mBlockSize; ++i) {
-        if (!mContentTableBuffer->writeUintAndAdvancePosition(NOT_A_DICT_POS, mDataSize,
+        if (!mContentTableBuffer->writeUintAndAdvancePosition(NOT_EXIST, mDataSize,
                 &writingPos)) {
             AKLOGE("cannot write content table to extend. writingPos: %d, tailPos: %d, "
                     "mDataSize: %d", writingPos, mContentTableBuffer->getTailPosition(), mDataSize);
diff --git a/tests/src/com/android/inputmethod/latin/WordComposerTests.java b/tests/src/com/android/inputmethod/latin/WordComposerTests.java
index a67f6a4..1336c6d 100644
--- a/tests/src/com/android/inputmethod/latin/WordComposerTests.java
+++ b/tests/src/com/android/inputmethod/latin/WordComposerTests.java
@@ -51,14 +51,14 @@
         assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1));
         assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
         // Check the previous word is still there
-        assertEquals(PREVWORD, wc.getPreviousWord());
+        assertEquals(PREVWORD, wc.getPreviousWordForSuggestion());
         // Move the cursor past the end of the word
         assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(1));
         assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(15));
         // Do what LatinIME does when the cursor is moved outside of the word,
         // and check the behavior is correct.
         wc.reset();
-        assertNull(wc.getPreviousWord());
+        assertNull(wc.getPreviousWordForSuggestion());
 
         // \uD861\uDED7 is 𨛗, a character outside the BMP
         final String STR_WITH_SUPPLEMENTARY_CHAR = "abcde\uD861\uDED7fgh";
@@ -73,35 +73,35 @@
         assertTrue(wc.isCursorFrontOrMiddleOfComposingWord());
         assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1));
         assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
-        assertNull(wc.getPreviousWord());
+        assertNull(wc.getPreviousWordForSuggestion());
 
         wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, STR_WITHIN_BMP, null /* keyboard */);
         wc.setCursorPositionWithinWord(3);
         assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7));
-        assertEquals(STR_WITHIN_BMP, wc.getPreviousWord());
+        assertEquals(STR_WITHIN_BMP, wc.getPreviousWordForSuggestion());
 
         wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, STR_WITH_SUPPLEMENTARY_CHAR,
                 null /* keyboard */);
         wc.setCursorPositionWithinWord(3);
         assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7));
-        assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWord());
+        assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWordForSuggestion());
 
         wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, STR_WITHIN_BMP, null /* keyboard */);
         wc.setCursorPositionWithinWord(3);
         assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-3));
         assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-1));
-        assertEquals(STR_WITHIN_BMP, wc.getPreviousWord());
+        assertEquals(STR_WITHIN_BMP, wc.getPreviousWordForSuggestion());
 
         wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null /* previousWord */,
                 null /* keyboard */);
         wc.setCursorPositionWithinWord(3);
         assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-9));
-        assertNull(wc.getPreviousWord());
+        assertNull(wc.getPreviousWordForSuggestion());
 
         wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, STR_WITH_SUPPLEMENTARY_CHAR,
                 null /* keyboard */);
         assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-10));
-        assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWord());
+        assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWordForSuggestion());
 
         wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null /* previousWord */,
                 null /* keyboard */);
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/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java
index 2123e84..0c88f34 100644
--- a/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java
@@ -292,6 +292,20 @@
         assertTrue(bytesStr.equals(bytesStr2));
     }
 
+    public void testContainsOnlyWhitespace() {
+        assertTrue(StringUtils.containsOnlyWhitespace("   "));
+        assertTrue(StringUtils.containsOnlyWhitespace(""));
+        assertTrue(StringUtils.containsOnlyWhitespace("  \n\t\t"));
+        // U+2002 : EN SPACE
+        // U+2003 : EM SPACE
+        // U+3000 : IDEOGRAPHIC SPACE (commonly "double-width space")
+        assertTrue(StringUtils.containsOnlyWhitespace("\u2002\u2003\u3000"));
+        assertFalse(StringUtils.containsOnlyWhitespace("  a "));
+        assertFalse(StringUtils.containsOnlyWhitespace(". "));
+        assertFalse(StringUtils.containsOnlyWhitespace("."));
+        assertTrue(StringUtils.containsOnlyWhitespace(""));
+    }
+
     public void testJsonUtils() {
         final Object[] objs = new Object[] { 1, "aaa", "bbb", 3 };
         final List<Object> objArray = Arrays.asList(objs);
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>
