diff --git a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java b/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
index d034515ca924f9873cab71604ec977b946a7a08c..59d55695697194f6bd6568e25a8a2b2cae36fbeb 100644
--- a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
@@ -27,15 +27,13 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Map;
 
-// TODO: Quit extending Dictionary after implementing dynamic binary dictionary.
-abstract public class AbstractDictionaryWriter extends Dictionary {
+abstract public class AbstractDictionaryWriter {
     /** Used for Log actions from this class */
     private static final String TAG = AbstractDictionaryWriter.class.getSimpleName();
 
     private final Context mContext;
 
-    public AbstractDictionaryWriter(final Context context, final String dictType) {
-        super(dictType);
+    public AbstractDictionaryWriter(final Context context) {
         mContext = context;
     }
 
diff --git a/java/src/com/android/inputmethod/latin/DictionaryWriter.java b/java/src/com/android/inputmethod/latin/DictionaryWriter.java
index f1a0541627448aa1fd9227e643948ac02dbb48be..f960c53431ae4d443fb2256828befab90d240de6 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryWriter.java
@@ -43,8 +43,8 @@ public class DictionaryWriter extends AbstractDictionaryWriter {
 
     private FusionDictionary mFusionDictionary;
 
-    public DictionaryWriter(final Context context, final String dictType) {
-        super(context, dictType);
+    public DictionaryWriter(final Context context) {
+        super(context);
         clear();
     }
 
@@ -92,18 +92,4 @@ public class DictionaryWriter extends AbstractDictionaryWriter {
         }
         dictEncoder.writeDictionary(mFusionDictionary, FORMAT_OPTIONS);
     }
-
-    @Override
-    public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
-            final String prevWord, final ProximityInfo proximityInfo,
-            boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
-        // This class doesn't support suggestion.
-        return null;
-    }
-
-    @Override
-    public boolean isValidWord(String word) {
-        // This class doesn't support dictionary retrieval.
-        return false;
-    }
 }
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index f86517d12463c759d60d980fd482896d2ed78c2d..98a18f6d3b516e462141632d9d3408c41b184f55 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -28,7 +28,6 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.utils.AsyncResultHolder;
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.PrioritizedSerialExecutor;
-import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -66,9 +65,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
 
     private static final int DICTIONARY_FORMAT_VERSION = 4;
 
-    private static final String SUPPORTS_DYNAMIC_UPDATE =
-            FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE;
-
     /**
      * A static map of update controllers, each of which records the time of accesses to a single
      * binary dictionary file and tracks whether the file is regenerating. The key for this map is
@@ -135,11 +131,18 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
      */
     protected abstract boolean hasContentChanged();
 
-    protected boolean isValidBinaryDictFormatVersion(final int formatVersion) {
-        // TODO: Use ver4 format.
+    protected boolean matchesExpectedBinaryDictFormatVersionForThisType(final int formatVersion) {
+        // This class is using format 2 because it's used by the User and Contacts dictionary
+        // only, which right now use format 2 (dicts using format 4 use Decaying*, which overrides
+        // this method).
+        // TODO: Migrate these dicts to ver4 format, and remove this function.
         return formatVersion == 2;
     }
 
+    public boolean hasValidContents() {
+        return mBinaryDictionary.hasValidContents();
+    }
+
     protected String getFileNameExtentionToOpenDict() {
         return "";
     }
@@ -174,11 +177,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
     }
 
     private static AbstractDictionaryWriter getDictionaryWriter(final Context context,
-            final String dictType, final boolean isDynamicPersonalizationDictionary) {
+            final boolean isDynamicPersonalizationDictionary) {
         if (isDynamicPersonalizationDictionary) {
              return null;
         } else {
-            return new DictionaryWriter(context, dictType);
+            return new DictionaryWriter(context);
         }
     }
 
@@ -203,7 +206,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
         mBinaryDictionary = null;
         mFilenameDictionaryUpdateController = getDictionaryUpdateController(filename);
         // Currently, only dynamic personalization dictionary is updatable.
-        mDictionaryWriter = getDictionaryWriter(context, dictType, isUpdatable);
+        mDictionaryWriter = getDictionaryWriter(context, isUpdatable);
     }
 
     protected static String getFilenameWithLocale(final String name, final Locale locale) {
@@ -222,9 +225,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
                     mBinaryDictionary.close();
                     mBinaryDictionary = null;
                 }
-                if (mDictionaryWriter != null) {
-                    mDictionaryWriter.close();
-                }
             }
         });
     }
@@ -564,7 +564,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
             mDictionaryWriter.write(mFilename, getHeaderAttributeMap());
         } else {
             if (mBinaryDictionary == null || !mBinaryDictionary.isValidDictionary()
-                    || !isValidBinaryDictFormatVersion(mBinaryDictionary.getFormatVersion())) {
+                    || !hasValidContents()
+                    // TODO: remove the check below
+                    || !matchesExpectedBinaryDictFormatVersionForThisType(
+                            mBinaryDictionary.getFormatVersion())) {
                 final File file = new File(mContext.getFilesDir(), mFilename);
                 file.delete();
                 BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
@@ -663,7 +666,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
                         loadBinaryDictionary();
                     }
                     if (mBinaryDictionary != null && !(mBinaryDictionary.isValidDictionary()
-                            && isValidBinaryDictFormatVersion(
+                            && hasValidContents()
+                            // TODO: remove the check below
+                            && matchesExpectedBinaryDictFormatVersionForThisType(
                                     mBinaryDictionary.getFormatVersion()))) {
                         // Binary dictionary or its format version is not valid. Regenerate the
                         // dictionary file.
diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
index 529ddc2571b6f9fdaebe5ac1a626c903ad65ffa8..f9733f7253587b145e0877b573fcb2cc0ed7dada 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
@@ -114,8 +114,10 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
     }
 
     @Override
-    protected boolean isValidBinaryDictFormatVersion(final int formatVersion) {
-        return formatVersion >= REQUIRED_BINARY_DICTIONARY_VERSION;
+    protected boolean matchesExpectedBinaryDictFormatVersionForThisType(final int formatVersion) {
+        // This class is using format 4 because it's used by all version 4 dictionaries.
+        // TODO: remove this when all dynamically generated dicts use version 4.
+        return formatVersion == REQUIRED_BINARY_DICTIONARY_VERSION;
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
index a0aed2829da65f3c2f0301de62b89a3aff43e584..b7a5a4026c1b6fb38f2ebbd95162870d53b5b818 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
@@ -49,6 +49,7 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> {
     final static ArrayList<SuggestedWordInfo> noSuggestions = CollectionUtils.newArrayList();
     private final static DictAndKeyboard dummyDict = new DictAndKeyboard(
             new Dictionary(Dictionary.TYPE_MAIN) {
+                // TODO: this dummy dictionary should be a singleton in the Dictionary class.
                 @Override
                 public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
                         final String prevWord, final ProximityInfo proximityInfo,