Add Ver4DictUpdater.

Change-Id: I986ab26faf535fc4bc98443053f534eced9d048f
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver3DictUpdater.java b/java/src/com/android/inputmethod/latin/makedict/Ver3DictUpdater.java
index fa7ae31..07adda6 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver3DictUpdater.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver3DictUpdater.java
@@ -57,7 +57,7 @@
     public void deleteWord(final String word) throws IOException, UnsupportedFormatException {
         if (mOutStream == null) openStreamAndBuffer();
         mDictBuffer.position(0);
-        super.readHeader();
+        readHeader();
         final int wordPos = getTerminalPosition(word);
         if (wordPos != FormatSpec.NOT_VALID_WORD) {
             mDictBuffer.position(wordPos);
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
index bab24e3..5372907 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
@@ -48,7 +48,7 @@
 
     private final File mDictDirectory;
     private final DictionaryBufferFactory mBufferFactory;
-    private DictBuffer mDictBuffer;
+    protected DictBuffer mDictBuffer;
     private DictBuffer mFrequencyBuffer;
     private DictBuffer mTerminalAddressTableBuffer;
     private DictBuffer mBigramBuffer;
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java
new file mode 100644
index 0000000..3d8f186
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictUpdater.java
@@ -0,0 +1,59 @@
+/*
+ * 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.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * An implementation of DictUpdater for version 4 binary dictionary.
+ */
+@UsedForTesting
+public class Ver4DictUpdater extends Ver4DictDecoder implements DictUpdater {
+
+    @UsedForTesting
+    public Ver4DictUpdater(final File dictDirectory, final int factoryType) {
+        // DictUpdater must have an updatable DictBuffer.
+        super(dictDirectory, ((factoryType & MASK_DICTBUFFER) == USE_BYTEARRAY)
+                ? USE_BYTEARRAY : USE_WRITABLE_BYTEBUFFER);
+    }
+
+    @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) DynamicBinaryDictIOUtils.markAsDeleted(flags));
+        }
+    }
+
+    @Override
+    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 {
+        // TODO: Implement this method.
+    }
+}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
index d17b306..0189b33 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
@@ -660,6 +660,8 @@
         final DictUpdater dictUpdater;
         if (formatOptions.mVersion == 3) {
             dictUpdater = new Ver3DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER);
+        } else if (formatOptions.mVersion == 4) {
+            dictUpdater = new Ver4DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER);
         } else {
             throw new RuntimeException("DictUpdater for version " + formatOptions.mVersion
                     + " doesn't exist.");
@@ -684,5 +686,6 @@
 
     public void testDeleteWord() {
         runTestDeleteWord(VERSION3_WITH_DYNAMIC_UPDATE);
+        runTestDeleteWord(VERSION4_WITH_DYNAMIC_UPDATE);
     }
 }
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
index 39342ee..afe5adb 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
@@ -46,6 +46,7 @@
     private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
 
     private static final int VERSION3 = 3;
+    private static final int VERSION4 = 4;
 
     private static final String[] CHARACTERS = {
         "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",