diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 2d50a6f..3da670e 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -25,7 +25,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -55,66 +54,6 @@
     }
 
     /**
-     * Escapes a string for any characters that may be suspicious for a file or directory name.
-     *
-     * Concretely this does a sort of URL-encoding except it will encode everything that's not
-     * alphanumeric or underscore. (true URL-encoding leaves alone characters like '*', which
-     * we cannot allow here)
-     */
-    // TODO: create a unit test for this method
-    private static String replaceFileNameDangerousCharacters(String name) {
-        // This assumes '%' is fully available as a non-separator, normal
-        // character in a file name. This is probably true for all file systems.
-        final StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < name.length(); ++i) {
-            final int codePoint = name.codePointAt(i);
-            if (Character.isLetterOrDigit(codePoint) || '_' == codePoint) {
-                sb.appendCodePoint(codePoint);
-            } else {
-                sb.append('%');
-                sb.append(Integer.toHexString(codePoint));
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Find out the cache directory associated with a specific locale.
-     */
-    private static String getCacheDirectoryForLocale(Locale locale, Context context) {
-        final String relativeDirectoryName = replaceFileNameDangerousCharacters(locale.toString());
-        final String absoluteDirectoryName = context.getFilesDir() + File.separator
-                + relativeDirectoryName;
-        final File directory = new File(absoluteDirectoryName);
-        if (!directory.exists()) {
-            if (!directory.mkdirs()) {
-                Log.e(TAG, "Could not create the directory for locale" + locale);
-            }
-        }
-        return absoluteDirectoryName;
-    }
-
-    /**
-     * Generates a file name for the id and locale passed as an argument.
-     *
-     * In the current implementation the file name returned will always be unique for
-     * any id/locale pair, but please do not expect that the id can be the same for
-     * different dictionaries with different locales. An id should be unique for any
-     * dictionary.
-     * The file name is pretty much an URL-encoded version of the id inside a directory
-     * named like the locale, except it will also escape characters that look dangerous
-     * to some file systems.
-     * @param id the id of the dictionary for which to get a file name
-     * @param locale the locale for which to get the file name
-     * @param context the context to use for getting the directory
-     * @return the name of the file to be created
-     */
-    private static String getCacheFileName(String id, Locale locale, Context context) {
-        final String fileName = replaceFileNameDangerousCharacters(id);
-        return getCacheDirectoryForLocale(locale, context) + File.separator + fileName;
-    }
-
-    /**
      * Return for a given locale or dictionary id the provider URI to get the dictionary.
      */
     private static Uri getProviderUri(String path) {
@@ -149,32 +88,32 @@
     }
 
     /**
-     * Queries a content provider for dictionary data for some locale and returns the file addresses
+     * Queries a content provider for dictionary data for some locale and cache the returned files
      *
-     * This will query a content provider for dictionary data for a given locale, and return
-     * the addresses of a file set the members of which are suitable to be mmap'ed. It will copy
-     * them to local storage if needed.
-     * It should also check the dictionary versions to avoid unnecessary copies but this is
-     * still in TODO state.
-     * This will make the data from the content provider the cached dictionary for this locale,
-     * overwriting any previous cached data.
+     * This will query a content provider for dictionary data for a given locale, and copy the
+     * files locally so that they can be mmap'ed. This may overwrite previously cached dictionaries
+     * with newer versions if a newer version is made available by the content provider.
      * @returns the addresses of the files, or null if no data could be obtained.
      * @throw FileNotFoundException if the provider returns non-existent data.
      * @throw IOException if the provider-returned data could not be read.
      */
-    public static List<AssetFileAddress> getDictSetFromContentProvider(final Locale locale,
+    public static List<AssetFileAddress> cacheDictionariesFromContentProvider(final Locale locale,
             final Context context) throws FileNotFoundException, IOException {
         final ContentResolver resolver = context.getContentResolver();
         final List<String> idList = getDictIdList(locale, context);
         final List<AssetFileAddress> fileAddressList = new ArrayList<AssetFileAddress>();
         for (String id : idList) {
-            final Uri dictionaryPackUri = getProviderUri(id);
+            final Uri wordListUri = getProviderUri(id);
             final AssetFileDescriptor afd =
-                    resolver.openAssetFileDescriptor(dictionaryPackUri, "r");
+                    resolver.openAssetFileDescriptor(wordListUri, "r");
             if (null == afd) continue;
             final String fileName = copyFileTo(afd.createInputStream(),
-                    getCacheFileName(id, locale, context));
+                    BinaryDictionaryGetter.getCacheFileName(id, locale, context));
             afd.close();
+            if (0 >= resolver.delete(wordListUri, null, null)) {
+                // I'd rather not print the word list ID to the log here out of security concerns
+                Log.e(TAG, "Could not have the dictionary pack delete a word list");
+            }
             fileAddressList.add(AssetFileAddress.makeFromFileName(fileName));
         }
         return fileAddressList;
@@ -192,7 +131,9 @@
         final Locale savedLocale = Utils.setSystemLocale(res, locale);
         final InputStream stream = res.openRawResource(resource);
         Utils.setSystemLocale(res, savedLocale);
-        return copyFileTo(stream, getCacheFileName(Integer.toString(resource), locale, context));
+        return copyFileTo(stream,
+                BinaryDictionaryGetter.getCacheFileName(Integer.toString(resource),
+                        locale, context));
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 4b1c05a..b26731a 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -21,6 +21,7 @@
 import android.content.res.Resources;
 import android.util.Log;
 
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.Arrays;
@@ -41,6 +42,66 @@
     private BinaryDictionaryGetter() {}
 
     /**
+     * Escapes a string for any characters that may be suspicious for a file or directory name.
+     *
+     * Concretely this does a sort of URL-encoding except it will encode everything that's not
+     * alphanumeric or underscore. (true URL-encoding leaves alone characters like '*', which
+     * we cannot allow here)
+     */
+    // TODO: create a unit test for this method
+    private static String replaceFileNameDangerousCharacters(String name) {
+        // This assumes '%' is fully available as a non-separator, normal
+        // character in a file name. This is probably true for all file systems.
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < name.length(); ++i) {
+            final int codePoint = name.codePointAt(i);
+            if (Character.isLetterOrDigit(codePoint) || '_' == codePoint) {
+                sb.appendCodePoint(codePoint);
+            } else {
+                sb.append('%');
+                sb.append(Integer.toHexString(codePoint));
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Find out the cache directory associated with a specific locale.
+     */
+    private static String getCacheDirectoryForLocale(Locale locale, Context context) {
+        final String relativeDirectoryName = replaceFileNameDangerousCharacters(locale.toString());
+        final String absoluteDirectoryName = context.getFilesDir() + File.separator
+                + relativeDirectoryName;
+        final File directory = new File(absoluteDirectoryName);
+        if (!directory.exists()) {
+            if (!directory.mkdirs()) {
+                Log.e(TAG, "Could not create the directory for locale" + locale);
+            }
+        }
+        return absoluteDirectoryName;
+    }
+
+    /**
+     * Generates a file name for the id and locale passed as an argument.
+     *
+     * In the current implementation the file name returned will always be unique for
+     * any id/locale pair, but please do not expect that the id can be the same for
+     * different dictionaries with different locales. An id should be unique for any
+     * dictionary.
+     * The file name is pretty much an URL-encoded version of the id inside a directory
+     * named like the locale, except it will also escape characters that look dangerous
+     * to some file systems.
+     * @param id the id of the dictionary for which to get a file name
+     * @param locale the locale for which to get the file name
+     * @param context the context to use for getting the directory
+     * @return the name of the file to be created
+     */
+    public static String getCacheFileName(String id, Locale locale, Context context) {
+        final String fileName = replaceFileNameDangerousCharacters(id);
+        return getCacheDirectoryForLocale(locale, context) + File.separator + fileName;
+    }
+
+    /**
      * Returns a file address from a resource, or null if it cannot be opened.
      */
     private static AssetFileAddress loadFallbackResource(final Context context,
@@ -74,10 +135,11 @@
     public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context,
             int fallbackResId) {
         try {
-            List<AssetFileAddress> listFromContentProvider =
-                    BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context);
-            if (null != listFromContentProvider) {
-                return listFromContentProvider;
+            List<AssetFileAddress> cachedDictionaryList =
+                    BinaryDictionaryFileDumper.cacheDictionariesFromContentProvider(locale,
+                            context);
+            if (null != cachedDictionaryList) {
+                return cachedDictionaryList;
             }
             // If the list is null, fall through and return the fallback
         } catch (FileNotFoundException e) {
diff --git a/tools/makedict2/Android.mk b/tools/makedict2/Android.mk
new file mode 100644
index 0000000..e056168
--- /dev/null
+++ b/tools/makedict2/Android.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2011 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.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_SRC_FILES += $(call all-java-files-under,tests)
+LOCAL_JAR_MANIFEST := etc/manifest.txt
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := makedict2
+LOCAL_JAVA_LIBRARIES := junit
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+include $(LOCAL_PATH)/etc/Android.mk
diff --git a/tools/makedict2/etc/Android.mk b/tools/makedict2/etc/Android.mk
new file mode 100644
index 0000000..c71377c
--- /dev/null
+++ b/tools/makedict2/etc/Android.mk
@@ -0,0 +1,21 @@
+# Copyright (C) 2011 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_PREBUILT_EXECUTABLES := makedict2
+include $(BUILD_HOST_PREBUILT)
diff --git a/tools/makedict2/etc/makedict2 b/tools/makedict2/etc/makedict2
new file mode 100755
index 0000000..1bad825
--- /dev/null
+++ b/tools/makedict2/etc/makedict2
@@ -0,0 +1,63 @@
+#!/bin/sh
+# Copyright 2011, 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.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=makedict2.jar
+frameworkdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
+# might need more memory, e.g. -Xmx128M
+exec java -ea -Djava.ext.dirs="$frameworkdir" -jar "$jarpath" "$@"
diff --git a/tools/makedict2/etc/manifest.txt b/tools/makedict2/etc/manifest.txt
new file mode 100644
index 0000000..948609d
--- /dev/null
+++ b/tools/makedict2/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.inputmethod.latin.DictionaryMaker
diff --git a/tools/makedict2/src/com/android/inputmethod/latin/BinaryDictInputOutput.java b/tools/makedict2/src/com/android/inputmethod/latin/BinaryDictInputOutput.java
new file mode 100644
index 0000000..92f402d
--- /dev/null
+++ b/tools/makedict2/src/com/android/inputmethod/latin/BinaryDictInputOutput.java
@@ -0,0 +1,1024 @@
+/*
+ * Copyright (C) 2011 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;
+
+import com.android.inputmethod.latin.FusionDictionary.CharGroup;
+import com.android.inputmethod.latin.FusionDictionary.Node;
+import com.android.inputmethod.latin.FusionDictionary.WeightedString;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Reads and writes XML files for a FusionDictionary.
+ *
+ * All the methods in this class are static.
+ */
+public class BinaryDictInputOutput {
+
+    /* Node layout is as follows:
+     *   | addressType                         xx     : mask with MASK_GROUP_ADDRESS_TYPE
+     *                                 2 bits, 00 = no children : FLAG_GROUP_ADDRESS_TYPE_NOADDRESS
+     * f |                                     01 = 1 byte      : FLAG_GROUP_ADDRESS_TYPE_ONEBYTE
+     * l |                                     10 = 2 bytes     : FLAG_GROUP_ADDRESS_TYPE_TWOBYTES
+     * a |                                     11 = 3 bytes     : FLAG_GROUP_ADDRESS_TYPE_THREEBYTES
+     * g | has several chars ?         1 bit, 1 = yes, 0 = no   : FLAG_HAS_MULTIPLE_CHARS
+     * s | has a terminal ?            1 bit, 1 = yes, 0 = no   : FLAG_IS_TERMINAL
+     *   | reserved                    1 bit, 1 = yes, 0 = no
+     *   | has bigrams ?               1 bit, 1 = yes, 0 = no   : FLAG_HAS_BIGRAMS
+     *
+     * c | IF FLAG_HAS_MULTIPLE_CHARS
+     * h |   char, char, char, char    n * (1 or 3 bytes) : use CharGroupInfo for i/o helpers
+     * a |   end                       1 byte, = 0
+     * r | ELSE
+     * s |   char                      1 or 3 bytes
+     *   | END
+     *
+     * f |
+     * r | IF FLAG_IS_TERMINAL
+     * e |   frequency                 1 byte
+     * q |
+     *
+     * c | IF 00 = FLAG_GROUP_ADDRESS_TYPE_NOADDRESS = addressType
+     * h |   // nothing
+     * i | ELSIF 01 = FLAG_GROUP_ADDRESS_TYPE_ONEBYTE == addressType
+     * l |   children address, 1 byte
+     * d | ELSIF 10 = FLAG_GROUP_ADDRESS_TYPE_TWOBYTES == addressType
+     * r |   children address, 2 bytes
+     * e | ELSE // 11 = FLAG_GROUP_ADDRESS_TYPE_THREEBYTES = addressType
+     * n |   children address, 3 bytes
+     * A | END
+     * d
+     * dress
+     *
+     *   | IF FLAG_IS_TERMINAL && FLAG_HAS_BIGRAMS
+     *   | bigrams address list
+     *
+     * Char format is:
+     * 1 byte = bbbbbbbb match
+     * case 000xxxxx: xxxxx << 16 + next byte << 8 + next byte
+     * else: if 00011111 (= 0x1F) : this is the terminator. This is a relevant choice because
+     *       unicode code points range from 0 to 0x10FFFF, so any 3-byte value starting with
+     *       00011111 would be outside unicode.
+     * else: iso-latin-1 code
+     * This allows for the whole unicode range to be encoded, including chars outside of
+     * the BMP. Also everything in the iso-latin-1 charset is only 1 byte, except control
+     * characters which should never happen anyway (and still work, but take 3 bytes).
+     *
+     * bigram and shortcut address list is:
+     * <flags> = | hasNext = 1 bit, 1 = yes, 0 = no     : FLAG_ATTRIBUTE_HAS_NEXT
+     *           | addressSign = 1 bit,                 : FLAG_ATTRIBUTE_OFFSET_NEGATIVE
+     *           |                      1 = must take -address, 0 = must take +address
+     *           |                         xx : mask with MASK_ATTRIBUTE_ADDRESS_TYPE
+     *           | addressFormat = 2 bits, 00 = unused  : FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE
+     *           |                         01 = 1 byte  : FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE
+     *           |                         10 = 2 bytes : FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES
+     *           |                         11 = 3 bytes : FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES
+     *           | 4 bits : frequency         : mask with FLAG_ATTRIBUTE_FREQUENCY
+     * <address> | IF (01 == FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE == addressFormat)
+     *           |   read 1 byte, add top 4 bits
+     *           | ELSIF (10 == FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES == addressFormat)
+     *           |   read 2 bytes, add top 4 bits
+     *           | ELSE // 11 == FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES == addressFormat
+     *           |   read 3 bytes, add top 4 bits
+     *           | END
+     *           | if (FLAG_ATTRIBUTE_OFFSET_NEGATIVE) then address = -address
+     * if (FLAG_ATTRIBUTE_HAS_NET) goto bigram_and_shortcut_address_list_is
+     *
+     */
+
+    private static final int MAGIC_NUMBER = 0x78B1;
+    private static final int VERSION = 1;
+    private static final int MAXIMUM_SUPPORTED_VERSION = VERSION;
+    // No options yet, reserved for future use.
+    private static final int OPTIONS = 0;
+
+    // TODO: Make this value adaptative to content data, store it in the header, and
+    // use it in the reading code.
+    private static final int MAX_WORD_LENGTH = 48;
+
+    private static final int MASK_GROUP_ADDRESS_TYPE = 0xC0;
+    private static final int FLAG_GROUP_ADDRESS_TYPE_NOADDRESS = 0x00;
+    private static final int FLAG_GROUP_ADDRESS_TYPE_ONEBYTE = 0x40;
+    private static final int FLAG_GROUP_ADDRESS_TYPE_TWOBYTES = 0x80;
+    private static final int FLAG_GROUP_ADDRESS_TYPE_THREEBYTES = 0xC0;
+
+    private static final int FLAG_HAS_MULTIPLE_CHARS = 0x20;
+
+    private static final int FLAG_IS_TERMINAL = 0x10;
+    private static final int FLAG_HAS_BIGRAMS = 0x04;
+
+    private static final int FLAG_ATTRIBUTE_HAS_NEXT = 0x80;
+    private static final int FLAG_ATTRIBUTE_OFFSET_NEGATIVE = 0x40;
+    private static final int MASK_ATTRIBUTE_ADDRESS_TYPE = 0x30;
+    private static final int FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE = 0x10;
+    private static final int FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES = 0x20;
+    private static final int FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES = 0x30;
+    private static final int FLAG_ATTRIBUTE_FREQUENCY = 0x0F;
+
+    private static final int GROUP_CHARACTERS_TERMINATOR = 0x1F;
+
+    private static final int GROUP_COUNT_SIZE = 1;
+    private static final int GROUP_TERMINATOR_SIZE = 1;
+    private static final int GROUP_FLAGS_SIZE = 1;
+    private static final int GROUP_FREQUENCY_SIZE = 1;
+    private static final int GROUP_MAX_ADDRESS_SIZE = 3;
+    private static final int GROUP_ATTRIBUTE_FLAGS_SIZE = 1;
+    private static final int GROUP_ATTRIBUTE_MAX_ADDRESS_SIZE = 3;
+
+    private static final int NO_CHILDREN_ADDRESS = Integer.MIN_VALUE;
+    private static final int INVALID_CHARACTER = -1;
+
+    // Limiting to 127 for upward compatibility
+    // TODO: implement a scheme to be able to shoot 256 chargroups in a node
+    private static final int MAX_CHARGROUPS_IN_A_NODE = 127;
+
+    private static final int MAX_TERMINAL_FREQUENCY = 255;
+
+    /**
+     * A class grouping utility function for our specific character encoding.
+     */
+    private static class CharEncoding {
+
+        private static final int MINIMAL_ONE_BYTE_CHARACTER_VALUE = 0x20;
+        private static final int MAXIMAL_ONE_BYTE_CHARACTER_VALUE = 0xFF;
+
+        /**
+         * Helper method to find out whether this code fits on one byte
+         */
+        private static boolean fitsOnOneByte(int character) {
+            return character >= MINIMAL_ONE_BYTE_CHARACTER_VALUE
+                    && character <= MAXIMAL_ONE_BYTE_CHARACTER_VALUE;
+        }
+
+        /**
+         * Compute the size of a character given its character code.
+         *
+         * Char format is:
+         * 1 byte = bbbbbbbb match
+         * case 000xxxxx: xxxxx << 16 + next byte << 8 + next byte
+         * else: if 00011111 (= 0x1F) : this is the terminator. This is a relevant choice because
+         *       unicode code points range from 0 to 0x10FFFF, so any 3-byte value starting with
+         *       00011111 would be outside unicode.
+         * else: iso-latin-1 code
+         * This allows for the whole unicode range to be encoded, including chars outside of
+         * the BMP. Also everything in the iso-latin-1 charset is only 1 byte, except control
+         * characters which should never happen anyway (and still work, but take 3 bytes).
+         *
+         * @param character the character code.
+         * @return the size in binary encoded-form, either 1 or 3 bytes.
+         */
+        private static int getCharSize(int character) {
+            // See char encoding in FusionDictionary.java
+            if (fitsOnOneByte(character)) return 1;
+            if (INVALID_CHARACTER == character) return 1;
+            return 3;
+        }
+
+        /**
+         * Compute the byte size of a character array.
+         */
+        private static int getCharArraySize(final int[] chars) {
+            int size = 0;
+            for (int character : chars) size += getCharSize(character);
+            return size;
+        }
+
+        /**
+         * Writes a char array to a byte buffer.
+         *
+         * @param characters the character array to write.
+         * @param buffer the byte buffer to write to.
+         * @param index the index in buffer to write the character array to.
+         * @return the index after the last character.
+         */
+        private static int writeCharArray(int[] characters, byte[] buffer, int index) {
+            for (int character : characters) {
+                if (1 == getCharSize(character)) {
+                    buffer[index++] = (byte)character;
+                } else {
+                    buffer[index++] = (byte)(0xFF & (character >> 16));
+                    buffer[index++] = (byte)(0xFF & (character >> 8));
+                    buffer[index++] = (byte)(0xFF & character);
+                }
+            }
+            return index;
+        }
+
+        /**
+         * Reads a character from the file.
+         *
+         * This follows the character format documented earlier in this source file.
+         *
+         * @param source the file, positioned over an encoded character.
+         * @return the character code.
+         */
+        private static int readChar(RandomAccessFile source) throws IOException {
+            int character = source.readUnsignedByte();
+            if (!fitsOnOneByte(character)) {
+                if (GROUP_CHARACTERS_TERMINATOR == character)
+                    return INVALID_CHARACTER;
+                character <<= 16;
+                character += source.readUnsignedShort();
+            }
+            return character;
+        }
+    }
+
+    /**
+     * Compute the binary size of the character array in a group
+     *
+     * If only one character, this is the size of this character. If many, it's the sum of their
+     * sizes + 1 byte for the terminator.
+     *
+     * @param group the group
+     * @return the size of the char array, including the terminator if any
+     */
+    private static int getGroupCharactersSize(CharGroup group) {
+        int size = CharEncoding.getCharArraySize(group.mChars);
+        if (group.hasSeveralChars()) size += GROUP_TERMINATOR_SIZE;
+        return size;
+    }
+
+    /**
+     * Compute the maximum size of a CharGroup, assuming 3-byte addresses for everything.
+     *
+     * @param group the CharGroup to compute the size of.
+     * @return the maximum size of the group.
+     */
+    private static int getCharGroupMaximumSize(CharGroup group) {
+        int size = getGroupCharactersSize(group) + GROUP_FLAGS_SIZE;
+        // If terminal, one byte for the frequency
+        if (group.isTerminal()) size += GROUP_FREQUENCY_SIZE;
+        size += GROUP_MAX_ADDRESS_SIZE; // For children address
+        if (null != group.mBigrams) {
+            for (WeightedString bigram : group.mBigrams) {
+                size += GROUP_ATTRIBUTE_FLAGS_SIZE + GROUP_ATTRIBUTE_MAX_ADDRESS_SIZE;
+            }
+        }
+        return size;
+    }
+
+    /**
+     * Compute the maximum size of a node, assuming 3-byte addresses for everything, and caches
+     * it in the 'actualSize' member of the node.
+     *
+     * @param node the node to compute the maximum size of.
+     */
+    private static void setNodeMaximumSize(Node node) {
+        int size = GROUP_COUNT_SIZE;
+        for (CharGroup g : node.mData) {
+            final int groupSize = getCharGroupMaximumSize(g);
+            g.mCachedSize = groupSize;
+            size += groupSize;
+        }
+        node.mCachedSize = size;
+    }
+
+    /**
+     * Helper method to hide the actual value of the no children address.
+     */
+    private static boolean hasChildrenAddress(int address) {
+        return NO_CHILDREN_ADDRESS != address;
+    }
+
+    /**
+     * Compute the size, in bytes, that an address will occupy.
+     *
+     * This can be used either for children addresses (which are always positive) or for
+     * attribute, which may be positive or negative but
+     * store their sign bit separately.
+     *
+     * @param address the address
+     * @return the byte size.
+     */
+    private static int getByteSize(int address) {
+        assert(address < 0x1000000);
+        if (!hasChildrenAddress(address)) {
+            return 0;
+        } else if (Math.abs(address) < 0x100) {
+            return 1;
+        } else if (Math.abs(address) < 0x10000) {
+            return 2;
+        } else {
+            return 3;
+        }
+    }
+    // End utility methods.
+
+    // This method is responsible for finding a nice ordering of the nodes that favors run-time
+    // cache performance and dictionary size.
+    /* package for tests */ static ArrayList<Node> flattenTree(Node root) {
+        final int treeSize = FusionDictionary.countCharGroups(root);
+        MakedictLog.i("Counted nodes : " + treeSize);
+        final ArrayList<Node> flatTree = new ArrayList<Node>(treeSize);
+        return flattenTreeInner(flatTree, root);
+    }
+
+    private static ArrayList<Node> flattenTreeInner(ArrayList<Node> list, Node node) {
+        // Removing the node is necessary if the tails are merged, because we would then
+        // add the same node several times when we only want it once. A number of places in
+        // the code also depends on any node being only once in the list.
+        // Merging tails can only be done if there are no attributes. Searching for attributes
+        // in LatinIME code depends on a total breadth-first ordering, which merging tails
+        // breaks. If there are no attributes, it should be fine (and reduce the file size)
+        // to merge tails, and the following step would be necessary.
+        // If eventually the code runs on Android, searching through the whole array each time
+        // may be a performance concern.
+        list.remove(node);
+        list.add(node);
+        final ArrayList<CharGroup> branches = node.mData;
+        final int nodeSize = branches.size();
+        for (CharGroup group : branches) {
+            if (null != group.mChildren) flattenTreeInner(list, group.mChildren);
+        }
+        return list;
+    }
+
+    /**
+     * Finds the absolute address of a word in the dictionary.
+     *
+     * @param dict the dictionary in which to search.
+     * @param word the word we are searching for.
+     * @return the word address. If it is not found, an exception is thrown.
+     */
+    private static int findAddressOfWord(final FusionDictionary dict, final String word) {
+        return FusionDictionary.findWordInTree(dict.mRoot, word).mCachedAddress;
+    }
+
+    /**
+     * Computes the actual node size, based on the cached addresses of the children nodes.
+     *
+     * Each node stores its tentative address. During dictionary address computing, these
+     * are not final, but they can be used to compute the node size (the node size depends
+     * on the address of the children because the number of bytes necessary to store an
+     * address depends on its numeric value.
+     *
+     * @param node the node to compute the size of.
+     * @param dict the dictionary in which the word/attributes are to be found.
+     */
+    private static void computeActualNodeSize(Node node, FusionDictionary dict) {
+        int size = GROUP_COUNT_SIZE;
+        for (CharGroup group : node.mData) {
+            int groupSize = GROUP_FLAGS_SIZE + getGroupCharactersSize(group);
+            if (group.isTerminal()) groupSize += GROUP_FREQUENCY_SIZE;
+            if (null != group.mChildren) {
+                final int offsetBasePoint= groupSize + node.mCachedAddress + size;
+                final int offset = group.mChildren.mCachedAddress - offsetBasePoint;
+                groupSize += getByteSize(offset);
+            }
+            if (null != group.mBigrams) {
+                for (WeightedString bigram : group.mBigrams) {
+                    final int offsetBasePoint = groupSize + node.mCachedAddress + size
+                            + GROUP_FLAGS_SIZE;
+                    final int addressOfBigram = findAddressOfWord(dict, bigram.mWord);
+                    final int offset = addressOfBigram - offsetBasePoint;
+                    groupSize += getByteSize(offset) + GROUP_FLAGS_SIZE;
+                }
+            }
+            group.mCachedSize = groupSize;
+            size += groupSize;
+        }
+        node.mCachedSize = size;
+    }
+
+    /**
+     * Computes the byte size of a list of nodes and updates each node cached position.
+     *
+     * @param flatNodes the array of nodes.
+     * @return the byte size of the entire stack.
+     */
+    private static int stackNodes(ArrayList<Node> flatNodes) {
+        int nodeOffset = 0;
+        for (Node n : flatNodes) {
+            n.mCachedAddress = nodeOffset;
+            int groupOffset = 0;
+            for (CharGroup g : n.mData) {
+                g.mCachedAddress = GROUP_COUNT_SIZE + nodeOffset + groupOffset;
+                groupOffset += g.mCachedSize;
+            }
+            if (groupOffset + GROUP_COUNT_SIZE != n.mCachedSize) {
+                throw new RuntimeException("Bug : Stored and computed node size differ");
+            }
+            nodeOffset += n.mCachedSize;
+        }
+        return nodeOffset;
+    }
+
+    /**
+     * Compute the addresses and sizes of an ordered node array.
+     *
+     * This method takes a node array and will update its cached address and size values
+     * so that they can be written into a file. It determines the smallest size each of the
+     * nodes can be given the addresses of its children and attributes, and store that into
+     * each node.
+     * The order of the node is given by the order of the array. This method makes no effort
+     * to find a good order; it only mechanically computes the size this order results in.
+     *
+     * @param dict the dictionary
+     * @param flatNodes the ordered array of nodes
+     * @return the same array it was passed. The nodes have been updated for address and size.
+     */
+    private static ArrayList<Node> computeAddresses(FusionDictionary dict,
+            ArrayList<Node> flatNodes) {
+        // First get the worst sizes and offsets
+        for (Node n : flatNodes) setNodeMaximumSize(n);
+        final int offset = stackNodes(flatNodes);
+
+        MakedictLog.i("Compressing the array addresses. Original size : " + offset);
+        MakedictLog.i("(Recursively seen size : " + offset + ")");
+
+        int passes = 0;
+        boolean changesDone = false;
+        do {
+            changesDone = false;
+            for (Node n : flatNodes) {
+                final int oldNodeSize = n.mCachedSize;
+                computeActualNodeSize(n, dict);
+                final int newNodeSize = n.mCachedSize;
+                if (oldNodeSize < newNodeSize) throw new RuntimeException("Increased size ?!");
+                if (oldNodeSize != newNodeSize) changesDone = true;
+            }
+            stackNodes(flatNodes);
+            ++passes;
+        } while (changesDone);
+
+        final Node lastNode = flatNodes.get(flatNodes.size() - 1);
+        MakedictLog.i("Compression complete in " + passes + " passes.");
+        MakedictLog.i("After address compression : "
+                + (lastNode.mCachedAddress + lastNode.mCachedSize));
+
+        return flatNodes;
+    }
+
+    /**
+     * Sanity-checking method.
+     *
+     * This method checks an array of node for juxtaposition, that is, it will do
+     * nothing if each node's cached address is actually the previous node's address
+     * plus the previous node's size.
+     * If this is not the case, it will throw an exception.
+     *
+     * @param array the array node to check
+     */
+    private static void checkFlatNodeArray(ArrayList<Node> array) {
+        int offset = 0;
+        int index = 0;
+        for (Node n : array) {
+            if (n.mCachedAddress != offset) {
+                throw new RuntimeException("Wrong address for node " + index
+                        + " : expected " + offset + ", got " + n.mCachedAddress);
+            }
+            ++index;
+            offset += n.mCachedSize;
+        }
+    }
+
+    /**
+     * Helper method to write a variable-size address to a file.
+     *
+     * @param buffer the buffer to write to.
+     * @param index the index in the buffer to write the address to.
+     * @param address the address to write.
+     * @return the size in bytes the address actually took.
+     */
+    private static int writeVariableAddress(byte[] buffer, int index, int address) {
+        switch (getByteSize(address)) {
+        case 1:
+            buffer[index++] = (byte)address;
+            return 1;
+        case 2:
+            buffer[index++] = (byte)(0xFF & (address >> 8));
+            buffer[index++] = (byte)(0xFF & address);
+            return 2;
+        case 3:
+            buffer[index++] = (byte)(0xFF & (address >> 16));
+            buffer[index++] = (byte)(0xFF & (address >> 8));
+            buffer[index++] = (byte)(0xFF & address);
+            return 3;
+        case 0:
+            return 0;
+        default:
+            throw new RuntimeException("Address " + address + " has a strange size");
+        }
+    }
+
+    private static byte makeCharGroupFlags(final CharGroup group, final int groupAddress,
+            final int childrenOffset) {
+        byte flags = 0;
+        if (group.mChars.length > 1) flags |= FLAG_HAS_MULTIPLE_CHARS;
+        if (group.mFrequency >= 0) {
+            flags |= FLAG_IS_TERMINAL;
+        }
+        if (null != group.mChildren) {
+            switch (getByteSize(childrenOffset)) {
+             case 1:
+                 flags |= FLAG_GROUP_ADDRESS_TYPE_ONEBYTE;
+                 break;
+             case 2:
+                 flags |= FLAG_GROUP_ADDRESS_TYPE_TWOBYTES;
+                 break;
+             case 3:
+                 flags |= FLAG_GROUP_ADDRESS_TYPE_THREEBYTES;
+                 break;
+             default:
+                 throw new RuntimeException("Node with a strange address");
+             }
+        }
+        if (null != group.mBigrams) flags |= FLAG_HAS_BIGRAMS;
+        return flags;
+    }
+
+    /**
+     * Makes the flag value for an attribute.
+     *
+     * @param more whether there are more attributes after this one.
+     * @param offset the offset of the attribute.
+     * @param frequency the frequency of the attribute, 0..15
+     * @return the flags
+     */
+    private static final int makeAttributeFlags(final boolean more, final int offset,
+            final int frequency) {
+        int bigramFlags = (more ? FLAG_ATTRIBUTE_HAS_NEXT : 0)
+                + (offset < 0 ? FLAG_ATTRIBUTE_OFFSET_NEGATIVE : 0);
+        switch (getByteSize(offset)) {
+        case 1:
+            bigramFlags |= FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE;
+            break;
+        case 2:
+            bigramFlags |= FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES;
+            break;
+        case 3:
+            bigramFlags |= FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES;
+            break;
+        default:
+            throw new RuntimeException("Strange offset size");
+        }
+        bigramFlags += frequency & FLAG_ATTRIBUTE_FREQUENCY;
+        return bigramFlags;
+    }
+
+    /**
+     * Write a node to memory. The node is expected to have its final position cached.
+     *
+     * This can be an empty map, but the more is inside the faster the lookups will be. It can
+     * be carried on as long as nodes do not move.
+     *
+     * @param dict the dictionary the node is a part of (for relative offsets).
+     * @param buffer the memory buffer to write to.
+     * @param node the node to write.
+     * @return the address of the END of the node.
+     */
+    private static int writePlacedNode(FusionDictionary dict, byte[] buffer, Node node) {
+        int index = node.mCachedAddress;
+
+        final int size = node.mData.size();
+        if (size > MAX_CHARGROUPS_IN_A_NODE)
+            throw new RuntimeException("A node has a group count over 127 (" + size + ").");
+
+        buffer[index++] = (byte)size;
+        int groupAddress = index;
+        for (int i = 0; i < size; ++i) {
+            CharGroup group = node.mData.get(i);
+            if (index != group.mCachedAddress) throw new RuntimeException("Bug: write index is not "
+                    + "the same as the cached address of the group");
+            groupAddress += GROUP_FLAGS_SIZE + getGroupCharactersSize(group);
+            // Sanity checks.
+            if (group.mFrequency > MAX_TERMINAL_FREQUENCY) {
+                throw new RuntimeException("A node has a frequency > " + MAX_TERMINAL_FREQUENCY
+                        + " : " + group.mFrequency);
+            }
+            if (group.mFrequency >= 0) groupAddress += GROUP_FREQUENCY_SIZE;
+            final int childrenOffset = null == group.mChildren
+                    ? NO_CHILDREN_ADDRESS : group.mChildren.mCachedAddress - groupAddress;
+            byte flags = makeCharGroupFlags(group, groupAddress, childrenOffset);
+            buffer[index++] = flags;
+            index = CharEncoding.writeCharArray(group.mChars, buffer, index);
+            if (group.hasSeveralChars()) {
+                buffer[index++] = GROUP_CHARACTERS_TERMINATOR;
+            }
+            if (group.mFrequency >= 0) {
+                buffer[index++] = (byte) group.mFrequency;
+            }
+            final int shift = writeVariableAddress(buffer, index, childrenOffset);
+            index += shift;
+            groupAddress += shift;
+
+            // Write bigrams
+            if (null != group.mBigrams) {
+                int remainingBigrams = group.mBigrams.size();
+                for (WeightedString bigram : group.mBigrams) {
+                    boolean more = remainingBigrams > 1;
+                    final int addressOfBigram = findAddressOfWord(dict, bigram.mWord);
+                    ++groupAddress;
+                    final int offset = addressOfBigram - groupAddress;
+                    int bigramFlags = makeAttributeFlags(more, offset, bigram.mFrequency);
+                    buffer[index++] = (byte)bigramFlags;
+                    final int bigramShift = writeVariableAddress(buffer, index, Math.abs(offset));
+                    index += bigramShift;
+                    groupAddress += bigramShift;
+                    --remainingBigrams;
+                }
+            }
+
+        }
+        if (index != node.mCachedAddress + node.mCachedSize) throw new RuntimeException(
+                "Not the same size : written "
+                + (index - node.mCachedAddress) + " bytes out of a node that should have "
+                + node.mCachedSize + " bytes");
+        return index;
+    }
+
+    /**
+     * Dumps a collection of useful statistics about a node array.
+     *
+     * This prints purely informative stuff, like the total estimated file size, the
+     * number of nodes, of character groups, the repartition of each address size, etc
+     *
+     * @param nodes the node array.
+     */
+    private static void showStatistics(ArrayList<Node> nodes) {
+        int firstTerminalAddress = Integer.MAX_VALUE;
+        int lastTerminalAddress = Integer.MIN_VALUE;
+        int size = 0;
+        int charGroups = 0;
+        int maxGroups = 0;
+        int maxRuns = 0;
+        for (Node n : nodes) {
+            if (maxGroups < n.mData.size()) maxGroups = n.mData.size();
+            for (CharGroup cg : n.mData) {
+                ++charGroups;
+                if (cg.mChars.length > maxRuns) maxRuns = cg.mChars.length;
+                if (cg.mFrequency >= 0) {
+                    if (n.mCachedAddress < firstTerminalAddress)
+                        firstTerminalAddress = n.mCachedAddress;
+                    if (n.mCachedAddress > lastTerminalAddress)
+                        lastTerminalAddress = n.mCachedAddress;
+                }
+            }
+            if (n.mCachedAddress + n.mCachedSize > size) size = n.mCachedAddress + n.mCachedSize;
+        }
+        final int[] groupCounts = new int[maxGroups + 1];
+        final int[] runCounts = new int[maxRuns + 1];
+        for (Node n : nodes) {
+            ++groupCounts[n.mData.size()];
+            for (CharGroup cg : n.mData) {
+                ++runCounts[cg.mChars.length];
+            }
+        }
+
+        MakedictLog.i("Statistics:\n"
+                + "  total file size " + size + "\n"
+                + "  " + nodes.size() + " nodes\n"
+                + "  " + charGroups + " groups (" + ((float)charGroups / nodes.size())
+                        + " groups per node)\n"
+                + "  first terminal at " + firstTerminalAddress + "\n"
+                + "  last terminal at " + lastTerminalAddress + "\n"
+                + "  Group stats : max = " + maxGroups);
+        for (int i = 0; i < groupCounts.length; ++i) {
+            MakedictLog.i("    " + i + " : " + groupCounts[i]);
+        }
+        MakedictLog.i("  Character run stats : max = " + maxRuns);
+        for (int i = 0; i < runCounts.length; ++i) {
+            MakedictLog.i("    " + i + " : " + runCounts[i]);
+        }
+    }
+
+    /**
+     * Dumps a FusionDictionary to a file.
+     *
+     * This is the public entry point to write a dictionary to a file.
+     *
+     * @param destination the stream to write the binary data to.
+     * @param dict the dictionary to write.
+     */
+    public static void writeDictionaryBinary(OutputStream destination, FusionDictionary dict)
+            throws IOException {
+
+        // Addresses are limited to 3 bytes, so we'll just make a 16MB buffer. Since addresses
+        // can be relative to each node, the structure itself is not limited to 16MB at all, but
+        // I doubt this will ever be shot. If it is, deciding the order of the nodes becomes
+        // a quite complicated problem, because though the dictionary itself does not have a
+        // size limit, each node must still be within 16MB of all its children and parents.
+        // As long as this is ensured, the dictionary file may grow to any size.
+        // Anyway, to make a dictionary bigger than 16MB just increase the size of this buffer.
+        final byte[] buffer = new byte[1 << 24];
+        int index = 0;
+
+        // Magic number in big-endian order.
+        buffer[index++] = (byte) (0xFF & (MAGIC_NUMBER >> 8));
+        buffer[index++] = (byte) (0xFF & MAGIC_NUMBER);
+        // Dictionary version.
+        buffer[index++] = (byte) (0xFF & VERSION);
+        // Options flags
+        buffer[index++] = (byte) (0xFF & (OPTIONS >> 8));
+        buffer[index++] = (byte) (0xFF & OPTIONS);
+
+        // Should we include the locale and title of the dictionary ?
+
+        destination.write(buffer, 0, index);
+        index = 0;
+
+        // Leave the choice of the optimal node order to the flattenTree function.
+        MakedictLog.i("Flattening the tree...");
+        ArrayList<Node> flatNodes = flattenTree(dict.mRoot);
+
+        MakedictLog.i("Computing addresses...");
+        computeAddresses(dict, flatNodes);
+        MakedictLog.i("Checking array...");
+        checkFlatNodeArray(flatNodes);
+
+        MakedictLog.i("Writing file...");
+        int dataEndOffset = 0;
+        for (Node n : flatNodes) {
+            dataEndOffset = writePlacedNode(dict, buffer, n);
+        }
+
+        showStatistics(flatNodes);
+
+        destination.write(buffer, 0, dataEndOffset);
+
+        destination.close();
+        MakedictLog.i("Done");
+    }
+
+
+    // Input methods: Read a binary dictionary to memory.
+    // readDictionaryBinary is the public entry point for them.
+
+    static final int[] characterBuffer = new int[MAX_WORD_LENGTH];
+    private static CharGroupInfo readCharGroup(RandomAccessFile source,
+            final int originalGroupAddress) throws IOException {
+        int addressPointer = originalGroupAddress;
+        final int flags = source.readUnsignedByte();
+        ++addressPointer;
+        final int characters[];
+        if (0 != (flags & FLAG_HAS_MULTIPLE_CHARS)) {
+            int index = 0;
+            int character = CharEncoding.readChar(source);
+            addressPointer += CharEncoding.getCharSize(character);
+            while (-1 != character) {
+                characterBuffer[index++] = character;
+                character = CharEncoding.readChar(source);
+                addressPointer += CharEncoding.getCharSize(character);
+            }
+            characters = Arrays.copyOfRange(characterBuffer, 0, index);
+        } else {
+            final int character = CharEncoding.readChar(source);
+            addressPointer += CharEncoding.getCharSize(character);
+            characters = new int[] { character };
+        }
+        final int frequency;
+        if (0 != (FLAG_IS_TERMINAL & flags)) {
+            ++addressPointer;
+            frequency = source.readUnsignedByte();
+        } else {
+            frequency = CharGroup.NOT_A_TERMINAL;
+        }
+        int childrenAddress = addressPointer;
+        switch (flags & MASK_GROUP_ADDRESS_TYPE) {
+        case FLAG_GROUP_ADDRESS_TYPE_ONEBYTE:
+            childrenAddress += source.readUnsignedByte();
+            addressPointer += 1;
+            break;
+        case FLAG_GROUP_ADDRESS_TYPE_TWOBYTES:
+            childrenAddress += source.readUnsignedShort();
+            addressPointer += 2;
+            break;
+        case FLAG_GROUP_ADDRESS_TYPE_THREEBYTES:
+            childrenAddress += (source.readUnsignedByte() << 16) + source.readUnsignedShort();
+            addressPointer += 3;
+            break;
+        case FLAG_GROUP_ADDRESS_TYPE_NOADDRESS:
+        default:
+            childrenAddress = NO_CHILDREN_ADDRESS;
+            break;
+        }
+        ArrayList<PendingAttribute> bigrams = null;
+        if (0 != (flags & FLAG_HAS_BIGRAMS)) {
+            bigrams = new ArrayList<PendingAttribute>();
+            boolean more = true;
+            while (more) {
+                int bigramFlags = source.readUnsignedByte();
+                ++addressPointer;
+                more = (0 != (bigramFlags & FLAG_ATTRIBUTE_HAS_NEXT));
+                final int sign = 0 == (bigramFlags & FLAG_ATTRIBUTE_OFFSET_NEGATIVE) ? 1 : -1;
+                int bigramAddress = addressPointer;
+                switch (bigramFlags & MASK_ATTRIBUTE_ADDRESS_TYPE) {
+                case FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE:
+                    bigramAddress += sign * source.readUnsignedByte();
+                    addressPointer += 1;
+                    break;
+                case FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES:
+                    bigramAddress += sign * source.readUnsignedShort();
+                    addressPointer += 2;
+                    break;
+                case FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES:
+                    final int offset = ((source.readUnsignedByte() << 16)
+                            + source.readUnsignedShort());
+                    bigramAddress += sign * offset;
+                    addressPointer += 3;
+                    break;
+                default:
+                    throw new RuntimeException("Has attribute with no address");
+                }
+                bigrams.add(new PendingAttribute(bigramFlags & FLAG_ATTRIBUTE_FREQUENCY,
+                        bigramAddress));
+            }
+        }
+        return new CharGroupInfo(originalGroupAddress, addressPointer, flags, characters, frequency,
+                childrenAddress, bigrams);
+    }
+
+    /**
+     * Finds, as a string, the word at the address passed as an argument.
+     *
+     * @param source the file to read from.
+     * @param headerSize the size of the header.
+     * @param address the address to seek.
+     * @return the word, as a string.
+     * @throws IOException if the file can't be read.
+     */
+    private static String getWordAtAddress(RandomAccessFile source, long headerSize,
+            int address) throws IOException {
+        final long originalPointer = source.getFilePointer();
+        source.seek(headerSize);
+        final int count = source.readUnsignedByte();
+        int groupOffset = 1; // 1 for the group count
+        final StringBuilder builder = new StringBuilder();
+        String result = null;
+
+        CharGroupInfo last = null;
+        for (int i = count - 1; i >= 0; --i) {
+            CharGroupInfo info = readCharGroup(source, groupOffset);
+            groupOffset = info.mEndAddress;
+            if (info.mOriginalAddress == address) {
+                builder.append(new String(info.mCharacters, 0, info.mCharacters.length));
+                result = builder.toString();
+                break; // and return
+            }
+            if (hasChildrenAddress(info.mChildrenAddress)) {
+                if (info.mChildrenAddress > address) {
+                    if (null == last) continue;
+                    builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
+                    source.seek(last.mChildrenAddress + headerSize);
+                    groupOffset = last.mChildrenAddress + 1;
+                    i = source.readUnsignedByte();
+                    last = null;
+                    continue;
+                }
+                last = info;
+            }
+            if (0 == i && hasChildrenAddress(last.mChildrenAddress)) {
+                builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
+                source.seek(last.mChildrenAddress + headerSize);
+                groupOffset = last.mChildrenAddress + 1;
+                i = source.readUnsignedByte();
+                last = null;
+                continue;
+            }
+        }
+        source.seek(originalPointer);
+        return result;
+    }
+
+    /**
+     * Reads a single node from a binary file.
+     *
+     * This methods reads the file at the current position of its file pointer. A node is
+     * fully expected to start at the current position.
+     * This will recursively read other nodes into the structure, populating the reverse
+     * maps on the fly and using them to keep track of already read nodes.
+     *
+     * @param source the data file, correctly positioned at the start of a node.
+     * @param headerSize the size, in bytes, of the file header.
+     * @param reverseNodeMap a mapping from addresses to already read nodes.
+     * @param reverseGroupMap a mapping from addresses to already read character groups.
+     * @return the read node with all his children already read.
+     */
+    private static Node readNode(RandomAccessFile source, long headerSize,
+            Map<Integer, Node> reverseNodeMap, Map<Integer, CharGroup> reverseGroupMap)
+            throws IOException {
+        final int nodeOrigin = (int)(source.getFilePointer() - headerSize);
+        final int count = source.readUnsignedByte();
+        final ArrayList<CharGroup> nodeContents = new ArrayList<CharGroup>();
+        int groupOffset = nodeOrigin + 1; // 1 byte for the group count
+        for (int i = count; i > 0; --i) {
+            CharGroupInfo info = readCharGroup(source, groupOffset);
+            ArrayList<WeightedString> bigrams = null;
+            if (null != info.mBigrams) {
+                bigrams = new ArrayList<WeightedString>();
+                for (PendingAttribute bigram : info.mBigrams) {
+                    final String word = getWordAtAddress(source, headerSize, bigram.mAddress);
+                    bigrams.add(new WeightedString(word, bigram.mFrequency));
+                }
+            }
+            if (hasChildrenAddress(info.mChildrenAddress)) {
+                Node children = reverseNodeMap.get(info.mChildrenAddress);
+                if (null == children) {
+                    final long currentPosition = source.getFilePointer();
+                    source.seek(info.mChildrenAddress + headerSize);
+                    children = readNode(source, headerSize, reverseNodeMap, reverseGroupMap);
+                    source.seek(currentPosition);
+                }
+                nodeContents.add(
+                        new CharGroup(info.mCharacters, bigrams, info.mFrequency,
+                        children));
+            } else {
+                nodeContents.add(
+                        new CharGroup(info.mCharacters, bigrams, info.mFrequency));
+            }
+            groupOffset = info.mEndAddress;
+        }
+        final Node node = new Node(nodeContents);
+        node.mCachedAddress = nodeOrigin;
+        reverseNodeMap.put(node.mCachedAddress, node);
+        return node;
+    }
+
+    /**
+     * Reads a random access file and returns the memory representation of the dictionary.
+     *
+     * This high-level method takes a binary file and reads its contents, populating a
+     * FusionDictionary structure. The optional dict argument is an existing dictionary to
+     * which words from the file should be added. If it is null, a new dictionary is created.
+     *
+     * @param source the file to read.
+     * @param dict an optional dictionary to add words to, or null.
+     * @return the created (or merged) dictionary.
+     */
+    public static FusionDictionary readDictionaryBinary(RandomAccessFile source,
+            FusionDictionary dict) throws IOException, UnsupportedFormatException {
+        // Check magic number
+        final int magic = source.readUnsignedShort();
+        if (MAGIC_NUMBER != magic) {
+            throw new UnsupportedFormatException("The magic number in this file does not match "
+                    + "the expected value");
+        }
+
+        // Check file version
+        final int version = source.readUnsignedByte();
+        if (version > MAXIMUM_SUPPORTED_VERSION) {
+            throw new UnsupportedFormatException("This file has version " + version
+                    + ", but this implementation does not support versions above "
+                    + MAXIMUM_SUPPORTED_VERSION);
+        }
+
+        // Read options
+        source.readUnsignedShort();
+
+        long headerSize = source.getFilePointer();
+        Map<Integer, Node> reverseNodeMapping = new TreeMap<Integer, Node>();
+        Map<Integer, CharGroup> reverseGroupMapping = new TreeMap<Integer, CharGroup>();
+        final Node root = readNode(source, headerSize, reverseNodeMapping, reverseGroupMapping);
+
+        FusionDictionary newDict = new FusionDictionary(root,
+                new FusionDictionary.DictionaryOptions());
+        if (null != dict) {
+            for (Word w : dict) {
+                newDict.add(w.mWord, w.mFrequency, w.mBigrams);
+            }
+        }
+
+        return newDict;
+    }
+
+    /**
+     * Basic test to find out whether the file is a binary dictionary or not.
+     *
+     * Concretely this only tests the magic number.
+     *
+     * @param filename The name of the file to test.
+     * @return true if it's a binary dictionary, false otherwise
+     */
+    public static boolean isBinaryDictionary(String filename) {
+        try {
+            RandomAccessFile f = new RandomAccessFile(filename, "r");
+            return MAGIC_NUMBER == f.readUnsignedShort();
+        } catch (FileNotFoundException e) {
+            return false;
+        } catch (IOException e) {
+            return false;
+        }
+    }
+}
diff --git a/tools/makedict2/src/com/android/inputmethod/latin/CharGroupInfo.java b/tools/makedict2/src/com/android/inputmethod/latin/CharGroupInfo.java
new file mode 100644
index 0000000..6badfd1
--- /dev/null
+++ b/tools/makedict2/src/com/android/inputmethod/latin/CharGroupInfo.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 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;
+
+import java.util.ArrayList;
+
+/**
+ * Raw char group info straight out of a file. This will contain numbers for addresses.
+ */
+public class CharGroupInfo {
+
+    public final int mOriginalAddress;
+    public final int mEndAddress;
+    public final int mFlags;
+    public final int[] mCharacters;
+    public final int mFrequency;
+    public final int mChildrenAddress;
+    public final ArrayList<PendingAttribute> mBigrams;
+
+    public CharGroupInfo(final int originalAddress, final int endAddress, final int flags,
+            final int[] characters, final int frequency, final int childrenAddress,
+            final ArrayList<PendingAttribute> bigrams) {
+        mOriginalAddress = originalAddress;
+        mEndAddress = endAddress;
+        mFlags = flags;
+        mCharacters = characters;
+        mFrequency = frequency;
+        mChildrenAddress = childrenAddress;
+        mBigrams = bigrams;
+    }
+}
diff --git a/tools/makedict2/src/com/android/inputmethod/latin/DictionaryMaker.java b/tools/makedict2/src/com/android/inputmethod/latin/DictionaryMaker.java
new file mode 100644
index 0000000..6194454
--- /dev/null
+++ b/tools/makedict2/src/com/android/inputmethod/latin/DictionaryMaker.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2011 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;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Arrays;
+import java.util.LinkedList;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Main class/method for DictionaryMaker.
+ */
+public class DictionaryMaker {
+
+    static class Arguments {
+        private final static String OPTION_VERSION_2 = "-2";
+        private final static String OPTION_INPUT_SOURCE = "-s";
+        private final static String OPTION_INPUT_BIGRAM_XML = "-b";
+        private final static String OPTION_OUTPUT_BINARY = "-d";
+        private final static String OPTION_OUTPUT_XML = "-x";
+        private final static String OPTION_HELP = "-h";
+        public final String mInputBinary;
+        public final String mInputUnigramXml;
+        public final String mInputBigramXml;
+        public final String mOutputBinary;
+        public final String mOutputXml;
+
+        private void checkIntegrity() {
+            checkHasExactlyOneInput();
+            checkHasAtLeastOneOutput();
+        }
+
+        private void checkHasExactlyOneInput() {
+            if (null == mInputUnigramXml && null == mInputBinary) {
+                throw new RuntimeException("No input file specified");
+            } else if (null != mInputUnigramXml && null != mInputBinary) {
+                throw new RuntimeException("Both input XML and binary specified");
+            } else if (null != mInputBinary && null != mInputBigramXml) {
+                throw new RuntimeException("Cannot specify a binary input and a separate bigram "
+                        + "file");
+            }
+        }
+
+        private void checkHasAtLeastOneOutput() {
+            if (null == mOutputBinary && null == mOutputXml) {
+                throw new RuntimeException("No output specified");
+            }
+        }
+
+        private void displayHelp() {
+            MakedictLog.i("Usage: makedict2 "
+                    + "[-s <unigrams.xml> [-b <bigrams.xml>] | -s <binary input>] "
+                    + " [-d <binary output>] [-x <xml output>] [-2]\n"
+                    + "\n"
+                    + "  Converts a source dictionary file to one or several outputs.\n"
+                    + "  Source can be an XML file, with an optional XML bigrams file, or a\n"
+                    + "  binary dictionary file.\n"
+                    + "  Both binary and XML outputs are supported. Both can be output at\n"
+                    + "  the same time but outputting several files of the same type is not\n"
+                    + "  supported.");
+        }
+
+        public Arguments(String[] argsArray) {
+            final LinkedList<String> args = new LinkedList<String>(Arrays.asList(argsArray));
+            if (args.isEmpty()) {
+                displayHelp();
+            }
+            String inputBinary = null;
+            String inputUnigramXml = null;
+            String inputBigramXml = null;
+            String outputBinary = null;
+            String outputXml = null;
+
+            while (!args.isEmpty()) {
+                final String arg = args.get(0);
+                args.remove(0);
+                if (arg.charAt(0) == '-') {
+                    if (OPTION_VERSION_2.equals(arg)) {
+                        // Do nothing, this is the default
+                    } else if (OPTION_HELP.equals(arg)) {
+                        displayHelp();
+                    } else {
+                        // All these options need an argument
+                        if (args.isEmpty()) {
+                            throw new RuntimeException("Option " + arg + " requires an argument");
+                        }
+                        String filename = args.get(0);
+                        args.remove(0);
+                        if (OPTION_INPUT_SOURCE.equals(arg)) {
+                            if (BinaryDictInputOutput.isBinaryDictionary(filename)) {
+                                inputBinary = filename;
+                            } else {
+                                inputUnigramXml = filename;
+                            }
+                        } else if (OPTION_INPUT_BIGRAM_XML.equals(arg)) {
+                            inputBigramXml = filename;
+                        } else if (OPTION_OUTPUT_BINARY.equals(arg)) {
+                            outputBinary = filename;
+                        } else if (OPTION_OUTPUT_XML.equals(arg)) {
+                            outputXml = filename;
+                        }
+                    }
+                } else {
+                    if (null == inputBinary && null == inputUnigramXml) {
+                        if (BinaryDictInputOutput.isBinaryDictionary(arg)) {
+                            inputBinary = arg;
+                        } else {
+                            inputUnigramXml = arg;
+                        }
+                    } else if (null == outputBinary) {
+                        outputBinary = arg;
+                    } else {
+                        throw new RuntimeException("Several output binary files specified");
+                    }
+                }
+            }
+
+            mInputBinary = inputBinary;
+            mInputUnigramXml = inputUnigramXml;
+            mInputBigramXml = inputBigramXml;
+            mOutputBinary = outputBinary;
+            mOutputXml = outputXml;
+            checkIntegrity();
+        }
+    }
+
+    public static void main(String[] args)
+            throws FileNotFoundException, ParserConfigurationException, SAXException, IOException,
+            UnsupportedFormatException {
+        final Arguments parsedArgs = new Arguments(args);
+        FusionDictionary dictionary = readInputFromParsedArgs(parsedArgs);
+        writeOutputToParsedArgs(parsedArgs, dictionary);
+    }
+
+    /**
+     * Invoke the right input method according to args.
+     *
+     * @param args the parsed command line arguments.
+     * @return the read dictionary.
+     */
+    private static FusionDictionary readInputFromParsedArgs(final Arguments args)
+            throws IOException, UnsupportedFormatException, ParserConfigurationException,
+            SAXException, FileNotFoundException {
+        if (null != args.mInputBinary) {
+            return readBinaryFile(args.mInputBinary);
+        } else if (null != args.mInputUnigramXml) {
+            return readXmlFile(args.mInputUnigramXml, args.mInputBigramXml);
+        } else {
+            throw new RuntimeException("No input file specified");
+        }
+    }
+
+    /**
+     * Read a dictionary from the name of a binary file.
+     *
+     * @param binaryFilename the name of the file in the binary dictionary format.
+     * @return the read dictionary.
+     * @throws FileNotFoundException if the file can't be found
+     * @throws IOException if the input file can't be read
+     * @throws UnsupportedFormatException if the binary file is not in the expected format
+     */
+    private static FusionDictionary readBinaryFile(final String binaryFilename)
+            throws FileNotFoundException, IOException, UnsupportedFormatException {
+        final RandomAccessFile inputFile = new RandomAccessFile(binaryFilename, "r");
+        return BinaryDictInputOutput.readDictionaryBinary(inputFile, null);
+    }
+
+    /**
+     * Read a dictionary from a unigram XML file, and optionally a bigram XML file.
+     *
+     * @param unigramXmlFilename the name of the unigram XML file. May not be null.
+     * @param bigramXmlFilename the name of the bigram XML file. Pass null if there are no bigrams.
+     * @return the read dictionary.
+     * @throws FileNotFoundException if one of the files can't be found
+     * @throws SAXException if one or more of the XML files is not well-formed
+     * @throws IOException if one the input files can't be read
+     * @throws ParserConfigurationException if the system can't create a SAX parser
+     */
+    private static FusionDictionary readXmlFile(final String unigramXmlFilename,
+            final String bigramXmlFilename) throws FileNotFoundException, SAXException,
+            IOException, ParserConfigurationException {
+        final FileInputStream unigrams = new FileInputStream(new File(unigramXmlFilename));
+        final FileInputStream bigrams = null == bigramXmlFilename ? null :
+                new FileInputStream(new File(bigramXmlFilename));
+        return XmlDictInputOutput.readDictionaryXml(unigrams, bigrams);
+    }
+
+    /**
+     * Invoke the right output method according to args.
+     *
+     * This will write the passed dictionary to the file(s) passed in the command line arguments.
+     * @param args the parsed arguments.
+     * @param dict the file to output.
+     * @throws FileNotFoundException if one of the output files can't be created.
+     * @throws IOException if one of the output files can't be written to.
+     */
+    private static void writeOutputToParsedArgs(final Arguments args, final FusionDictionary dict)
+            throws FileNotFoundException, IOException {
+        if (null != args.mOutputBinary) {
+            writeBinaryDictionary(args.mOutputBinary, dict);
+        }
+        if (null != args.mOutputXml) {
+            writeXmlDictionary(args.mOutputXml, dict);
+        }
+    }
+
+    /**
+     * Write the dictionary in binary format to the specified filename.
+     *
+     * @param outputFilename the name of the file to write to.
+     * @param dict the dictionary to write.
+     * @throws FileNotFoundException if the output file can't be created.
+     * @throws IOException if the output file can't be written to.
+     */
+    private static void writeBinaryDictionary(final String outputFilename,
+            final FusionDictionary dict) throws FileNotFoundException, IOException {
+        final File outputFile = new File(outputFilename);
+        BinaryDictInputOutput.writeDictionaryBinary(new FileOutputStream(outputFilename), dict);
+    }
+
+    /**
+     * Write the dictionary in XML format to the specified filename.
+     *
+     * @param outputFilename the name of the file to write to.
+     * @param dict the dictionary to write.
+     * @throws FileNotFoundException if the output file can't be created.
+     * @throws IOException if the output file can't be written to.
+     */
+    private static void writeXmlDictionary(final String outputFilename,
+            final FusionDictionary dict) throws FileNotFoundException, IOException {
+        XmlDictInputOutput.writeDictionaryXml(new FileWriter(outputFilename), dict);
+    }
+}
diff --git a/tools/makedict2/src/com/android/inputmethod/latin/FusionDictionary.java b/tools/makedict2/src/com/android/inputmethod/latin/FusionDictionary.java
new file mode 100644
index 0000000..031f35d
--- /dev/null
+++ b/tools/makedict2/src/com/android/inputmethod/latin/FusionDictionary.java
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2011 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;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A dictionary that can fusion heads and tails of words for more compression.
+ */
+public class FusionDictionary implements Iterable<Word> {
+
+    /**
+     * A node of the dictionary, containing several CharGroups.
+     *
+     * A node is but an ordered array of CharGroups, which essentially contain all the
+     * real information.
+     * This class also contains fields to cache size and address, to help with binary
+     * generation.
+     */
+    public static class Node {
+        ArrayList<CharGroup> mData;
+        // To help with binary generation
+        int mCachedSize;
+        int mCachedAddress;
+        public Node() {
+            mData = new ArrayList<CharGroup>();
+            mCachedSize = Integer.MIN_VALUE;
+            mCachedAddress = Integer.MIN_VALUE;
+        }
+        public Node(ArrayList<CharGroup> data) {
+            mData = data;
+            mCachedSize = Integer.MIN_VALUE;
+            mCachedAddress = Integer.MIN_VALUE;
+        }
+    }
+
+    /**
+     * A string with a frequency.
+     *
+     * This represents an "attribute", that is either a bigram or a shortcut.
+     */
+    public static class WeightedString {
+        final String mWord;
+        final int mFrequency;
+        public WeightedString(String word, int frequency) {
+            mWord = word;
+            mFrequency = frequency;
+        }
+    }
+
+    /**
+     * A group of characters, with a frequency, shortcuts, bigrams, and children.
+     *
+     * This is the central class of the in-memory representation. A CharGroup is what can
+     * be seen as a traditional "trie node", except it can hold several characters at the
+     * same time. A CharGroup essentially represents one or several characters in the middle
+     * of the trie trie; as such, it can be a terminal, and it can have children.
+     * In this in-memory representation, whether the CharGroup is a terminal or not is represented
+     * in the frequency, where NOT_A_TERMINAL (= -1) means this is not a terminal and any other
+     * value is the frequency of this terminal. A terminal may have non-null shortcuts and/or
+     * bigrams, but a non-terminal may not. Moreover, children, if present, are null.
+     */
+    public static class CharGroup {
+        public static final int NOT_A_TERMINAL = -1;
+        final int mChars[];
+        final ArrayList<WeightedString> mBigrams;
+        final int mFrequency; // NOT_A_TERMINAL == mFrequency indicates this is not a terminal.
+        Node mChildren;
+        // The two following members to help with binary generation
+        int mCachedSize;
+        int mCachedAddress;
+
+        public CharGroup(final int[] chars,
+                final ArrayList<WeightedString> bigrams, final int frequency) {
+            mChars = chars;
+            mFrequency = frequency;
+            mBigrams = bigrams;
+            mChildren = null;
+        }
+
+        public CharGroup(final int[] chars,
+                final ArrayList<WeightedString> bigrams, final int frequency, final Node children) {
+            mChars = chars;
+            mFrequency = frequency;
+            mBigrams = bigrams;
+            mChildren = children;
+        }
+
+        public void addChild(CharGroup n) {
+            if (null == mChildren) {
+                mChildren = new Node();
+            }
+            mChildren.mData.add(n);
+        }
+
+        public boolean isTerminal() {
+            return NOT_A_TERMINAL != mFrequency;
+        }
+
+        public boolean hasSeveralChars() {
+            assert(mChars.length > 0);
+            return 1 < mChars.length;
+        }
+    }
+
+    /**
+     * Options global to the dictionary.
+     *
+     * There are no options at the moment, so this class is empty.
+     */
+    public static class DictionaryOptions {
+    }
+
+
+    public final DictionaryOptions mOptions;
+    public final Node mRoot;
+
+    public FusionDictionary() {
+        mOptions = new DictionaryOptions();
+        mRoot = new Node();
+    }
+
+    public FusionDictionary(final Node root, final DictionaryOptions options) {
+        mRoot = root;
+        mOptions = options;
+    }
+
+    /**
+     * Helper method to convert a String to an int array.
+     */
+    static private int[] getCodePoints(String word) {
+        final int wordLength = word.length();
+        int[] array = new int[word.codePointCount(0, wordLength)];
+        for (int i = 0; i < wordLength; ++i) {
+            array[i] = word.codePointAt(i);
+        }
+        return array;
+    }
+
+    /**
+     * Helper method to add a word as a string.
+     *
+     * This method adds a word to the dictionary with the given frequency. Optional
+     * lists of bigrams and shortcuts can be passed here. For each word inside,
+     * they will be added to the dictionary as necessary.
+     *
+     * @param word the word to add.
+     * @param frequency the frequency of the word, in the range [0..255].
+     * @param bigrams a list of bigrams, or null.
+     */
+    public void add(String word, int frequency, ArrayList<WeightedString> bigrams) {
+        if (null != bigrams) {
+            for (WeightedString bigram : bigrams) {
+                final CharGroup t = findWordInTree(mRoot, bigram.mWord);
+                if (null == t) {
+                    add(getCodePoints(bigram.mWord), 0, null);
+                }
+            }
+        }
+        add(getCodePoints(word), frequency, bigrams);
+    }
+
+    /**
+     * Sanity check for a node.
+     *
+     * This method checks that all CharGroups in a node are ordered as expected.
+     * If they are, nothing happens. If they aren't, an exception is thrown.
+     */
+    private void checkStack(Node node) {
+        ArrayList<CharGroup> stack = node.mData;
+        int lastValue = -1;
+        for (int i = 0; i < stack.size(); ++i) {
+            int currentValue = stack.get(i).mChars[0];
+            if (currentValue <= lastValue)
+                throw new RuntimeException("Invalid stack");
+            else
+                lastValue = currentValue;
+        }
+    }
+
+    /**
+     * Add a word to this dictionary.
+     *
+     * The bigrams, if any, have to be in the dictionary already. If they aren't,
+     * an exception is thrown.
+     *
+     * @param word the word, as an int array.
+     * @param frequency the frequency of the word, in the range [0..255].
+     * @param bigrams an optional list of bigrams for this word (null if none).
+     */
+    private void add(int[] word, int frequency, ArrayList<WeightedString> bigrams) {
+        assert(frequency >= 0 && frequency <= 255);
+        Node currentNode = mRoot;
+        int charIndex = 0;
+
+        CharGroup currentGroup = null;
+        int differentCharIndex = 0; // Set by the loop to the index of the char that differs
+        int nodeIndex = findIndexOfChar(mRoot, word[charIndex]);
+        while (CHARACTER_NOT_FOUND != nodeIndex) {
+            currentGroup = currentNode.mData.get(nodeIndex);
+            differentCharIndex = compareArrays(currentGroup.mChars, word, charIndex) ;
+            if (ARRAYS_ARE_EQUAL != differentCharIndex
+                    && differentCharIndex < currentGroup.mChars.length) break;
+            if (null == currentGroup.mChildren) break;
+            charIndex += currentGroup.mChars.length;
+            if (charIndex >= word.length) break;
+            currentNode = currentGroup.mChildren;
+            nodeIndex = findIndexOfChar(currentNode, word[charIndex]);
+        }
+
+        if (-1 == nodeIndex) {
+            // No node at this point to accept the word. Create one.
+            final int insertionIndex = findInsertionIndex(currentNode, word[charIndex]);
+            final CharGroup newGroup = new CharGroup(
+                    Arrays.copyOfRange(word, charIndex, word.length), bigrams, frequency);
+            currentNode.mData.add(insertionIndex, newGroup);
+            checkStack(currentNode);
+        } else {
+            // There is a word with a common prefix.
+            if (differentCharIndex == currentGroup.mChars.length) {
+                if (charIndex + differentCharIndex >= word.length) {
+                    // The new word is a prefix of an existing word, but the node on which it
+                    // should end already exists as is.
+                    if (currentGroup.mFrequency > 0) {
+                        throw new RuntimeException("Such a word already exists in the dictionary : "
+                                + new String(word, 0, word.length));
+                    } else {
+                        final CharGroup newNode = new CharGroup(currentGroup.mChars,
+                                bigrams, frequency, currentGroup.mChildren);
+                        currentNode.mData.set(nodeIndex, newNode);
+                        checkStack(currentNode);
+                    }
+                } else {
+                    // The new word matches the full old word and extends past it.
+                    // We only have to create a new node and add it to the end of this.
+                    final CharGroup newNode = new CharGroup(
+                            Arrays.copyOfRange(word, charIndex + differentCharIndex, word.length),
+                                    bigrams, frequency);
+                    currentGroup.mChildren = new Node();
+                    currentGroup.mChildren.mData.add(newNode);
+                }
+            } else {
+                if (0 == differentCharIndex) {
+                    // Exact same word. Check the frequency is 0 or -1, and update.
+                    if (0 != frequency) {
+                        if (0 < currentGroup.mFrequency) {
+                            throw new RuntimeException("This word already exists with frequency "
+                                    + currentGroup.mFrequency + " : "
+                                    + new String(word, 0, word.length));
+                        }
+                        final CharGroup newGroup = new CharGroup(word,
+                                currentGroup.mBigrams, frequency);
+                        currentNode.mData.set(nodeIndex, newGroup);
+                    }
+                } else {
+                    // Partial prefix match only. We have to replace the current node with a node
+                    // containing the current prefix and create two new ones for the tails.
+                    Node newChildren = new Node();
+                    final CharGroup newOldWord = new CharGroup(
+                            Arrays.copyOfRange(currentGroup.mChars, differentCharIndex,
+                                    currentGroup.mChars.length),
+                            currentGroup.mBigrams, currentGroup.mFrequency, currentGroup.mChildren);
+                    newChildren.mData.add(newOldWord);
+
+                    final CharGroup newParent;
+                    if (charIndex + differentCharIndex >= word.length) {
+                        newParent = new CharGroup(
+                                Arrays.copyOfRange(currentGroup.mChars, 0, differentCharIndex),
+                                        bigrams, frequency, newChildren);
+                    } else {
+                        newParent = new CharGroup(
+                                Arrays.copyOfRange(currentGroup.mChars, 0, differentCharIndex),
+                                        null, -1, newChildren);
+                        final CharGroup newWord = new CharGroup(
+                                Arrays.copyOfRange(word, charIndex + differentCharIndex,
+                                        word.length), bigrams, frequency);
+                        final int addIndex = word[charIndex + differentCharIndex]
+                                > currentGroup.mChars[differentCharIndex] ? 1 : 0;
+                        newChildren.mData.add(addIndex, newWord);
+                    }
+                    currentNode.mData.set(nodeIndex, newParent);
+                }
+                checkStack(currentNode);
+            }
+        }
+    }
+
+    /**
+     * Custom comparison of two int arrays taken to contain character codes.
+     *
+     * This method compares the two arrays passed as an argument in a lexicographic way,
+     * with an offset in the dst string.
+     * This method does NOT test for the first character. It is taken to be equal.
+     * I repeat: this method starts the comparison at 1 <> dstOffset + 1.
+     * The index where the strings differ is returned. ARRAYS_ARE_EQUAL = 0 is returned if the
+     * strings are equal. This works BECAUSE we don't look at the first character.
+     *
+     * @param src the left-hand side string of the comparison.
+     * @param dst the right-hand side string of the comparison.
+     * @param dstOffset the offset in the right-hand side string.
+     * @return the index at which the strings differ, or ARRAYS_ARE_EQUAL = 0 if they don't.
+     */
+    private static int ARRAYS_ARE_EQUAL = 0;
+    private static int compareArrays(final int[] src, final int[] dst, int dstOffset) {
+        // We do NOT test the first char, because we come from a method that already
+        // tested it.
+        for (int i = 1; i < src.length; ++i) {
+            if (dstOffset + i >= dst.length) return i;
+            if (src[i] != dst[dstOffset + i]) return i;
+        }
+        if (dst.length > src.length) return src.length;
+        return ARRAYS_ARE_EQUAL;
+    }
+
+    /**
+     * Helper class that compares and sorts two chargroups according to their
+     * first element only. I repeat: ONLY the first element is considered, the rest
+     * is ignored.
+     * This comparator imposes orderings that are inconsistent with equals.
+     */
+    static private class CharGroupComparator implements java.util.Comparator {
+        public int compare(Object o1, Object o2) {
+            final CharGroup c1 = (CharGroup)o1;
+            final CharGroup c2 = (CharGroup)o2;
+            if (c1.mChars[0] == c2.mChars[0]) return 0;
+            return c1.mChars[0] < c2.mChars[0] ? -1 : 1;
+        }
+        public boolean equals(Object o) {
+            return o instanceof CharGroupComparator;
+        }
+    }
+    final static private CharGroupComparator CHARGROUP_COMPARATOR = new CharGroupComparator();
+
+    /**
+     * Finds the insertion index of a character within a node.
+     */
+    private static int findInsertionIndex(final Node node, int character) {
+        final List data = node.mData;
+        final CharGroup reference = new CharGroup(new int[] { character }, null, 0);
+        int result = Collections.binarySearch(data, reference, CHARGROUP_COMPARATOR);
+        return result >= 0 ? result : -result - 1;
+    }
+
+    /**
+     * Find the index of a char in a node, if it exists.
+     *
+     * @param node the node to search in.
+     * @param character the character to search for.
+     * @return the position of the character if it's there, or CHARACTER_NOT_FOUND = -1 else.
+     */
+    private static int CHARACTER_NOT_FOUND = -1;
+    private static int findIndexOfChar(final Node node, int character) {
+        final int insertionIndex = findInsertionIndex(node, character);
+        if (node.mData.size() <= insertionIndex) return CHARACTER_NOT_FOUND;
+        return character == node.mData.get(insertionIndex).mChars[0] ? insertionIndex
+                : CHARACTER_NOT_FOUND;
+    }
+
+    /**
+     * Helper method to find a word in a given branch.
+     */
+    public static CharGroup findWordInTree(Node node, final String s) {
+        int index = 0;
+        final StringBuilder checker = new StringBuilder();
+
+        CharGroup currentGroup;
+        do {
+            int indexOfGroup = findIndexOfChar(node, s.codePointAt(index));
+            if (CHARACTER_NOT_FOUND == indexOfGroup) return null;
+            currentGroup = node.mData.get(indexOfGroup);
+            checker.append(new String(currentGroup.mChars, 0, currentGroup.mChars.length));
+            index += currentGroup.mChars.length;
+            if (index < s.length()) {
+                node = currentGroup.mChildren;
+            }
+        } while (null != node && index < s.length());
+
+        if (!s.equals(checker.toString())) return null;
+        return currentGroup;
+    }
+
+    /**
+     * Recursively count the number of character groups in a given branch of the trie.
+     *
+     * @param node the parent node.
+     * @return the number of char groups in all the branch under this node.
+     */
+    public static int countCharGroups(final Node node) {
+        final int nodeSize = node.mData.size();
+        int size = nodeSize;
+        for (int i = nodeSize - 1; i >= 0; --i) {
+            CharGroup group = node.mData.get(i);
+            if (null != group.mChildren)
+                size += countCharGroups(group.mChildren);
+        }
+        return size;
+    }
+
+    /**
+     * Recursively count the number of nodes in a given branch of the trie.
+     *
+     * @param node the node to count.
+     * @result the number of nodes in this branch.
+     */
+    public static int countNodes(final Node node) {
+        int size = 1;
+        for (int i = node.mData.size() - 1; i >= 0; --i) {
+            CharGroup group = node.mData.get(i);
+            if (null != group.mChildren)
+                size += countNodes(group.mChildren);
+        }
+        return size;
+    }
+
+    // Historically, the tails of the words were going to be merged to save space.
+    // However, that would prevent the code to search for a specific address in log(n)
+    // time so this was abandoned.
+    // The code is still of interest as it does add some compression to any dictionary
+    // that has no need for attributes. Implementations that does not read attributes should be
+    // able to read a dictionary with merged tails.
+    // Also, the following code does support frequencies, as in, it will only merges
+    // tails that share the same frequency. Though it would result in the above loss of
+    // performance while searching by address, it is still technically possible to merge
+    // tails that contain attributes, but this code does not take that into account - it does
+    // not compare attributes and will merge terminals with different attributes regardless.
+    public void mergeTails() {
+        MakedictLog.i("Do not merge tails");
+        return;
+
+//        MakedictLog.i("Merging nodes. Number of nodes : " + countNodes(root));
+//        MakedictLog.i("Number of groups : " + countCharGroups(root));
+//
+//        final HashMap<String, ArrayList<Node>> repository =
+//                  new HashMap<String, ArrayList<Node>>();
+//        mergeTailsInner(repository, root);
+//
+//        MakedictLog.i("Number of different pseudohashes : " + repository.size());
+//        int size = 0;
+//        for (ArrayList<Node> a : repository.values()) {
+//            size += a.size();
+//        }
+//        MakedictLog.i("Number of nodes after merge : " + (1 + size));
+//        MakedictLog.i("Recursively seen nodes : " + countNodes(root));
+    }
+
+    // The following methods are used by the deactivated mergeTails()
+//   private static boolean isEqual(Node a, Node b) {
+//       if (null == a && null == b) return true;
+//       if (null == a || null == b) return false;
+//       if (a.data.size() != b.data.size()) return false;
+//       final int size = a.data.size();
+//       for (int i = size - 1; i >= 0; --i) {
+//           CharGroup aGroup = a.data.get(i);
+//           CharGroup bGroup = b.data.get(i);
+//           if (aGroup.frequency != bGroup.frequency) return false;
+//           if (aGroup.alternates == null && bGroup.alternates != null) return false;
+//           if (aGroup.alternates != null && !aGroup.equals(bGroup.alternates)) return false;
+//           if (!Arrays.equals(aGroup.chars, bGroup.chars)) return false;
+//           if (!isEqual(aGroup.children, bGroup.children)) return false;
+//       }
+//       return true;
+//   }
+
+//   static private HashMap<String, ArrayList<Node>> mergeTailsInner(
+//           final HashMap<String, ArrayList<Node>> map, final Node node) {
+//       final ArrayList<CharGroup> branches = node.data;
+//       final int nodeSize = branches.size();
+//       for (int i = 0; i < nodeSize; ++i) {
+//           CharGroup group = branches.get(i);
+//           if (null != group.children) {
+//               String pseudoHash = getPseudoHash(group.children);
+//               ArrayList<Node> similarList = map.get(pseudoHash);
+//               if (null == similarList) {
+//                   similarList = new ArrayList<Node>();
+//                   map.put(pseudoHash, similarList);
+//               }
+//               boolean merged = false;
+//               for (Node similar : similarList) {
+//                   if (isEqual(group.children, similar)) {
+//                       group.children = similar;
+//                       merged = true;
+//                       break;
+//                   }
+//               }
+//               if (!merged) {
+//                   similarList.add(group.children);
+//               }
+//               mergeTailsInner(map, group.children);
+//           }
+//       }
+//       return map;
+//   }
+
+//  private static String getPseudoHash(final Node node) {
+//      StringBuilder s = new StringBuilder();
+//      for (CharGroup g : node.data) {
+//          s.append(g.frequency);
+//          for (int ch : g.chars){
+//              s.append(Character.toChars(ch));
+//          }
+//      }
+//      return s.toString();
+//  }
+
+    /**
+     * Iterator to walk through a dictionary.
+     *
+     * This is purely for convenience.
+     */
+    public static class DictionaryIterator implements Iterator<Word> {
+
+        private static class Position {
+            public Iterator<CharGroup> pos;
+            public int length;
+            public Position(ArrayList<CharGroup> groups) {
+                pos = groups.iterator();
+                length = 0;
+            }
+        }
+        final StringBuilder mCurrentString;
+        final LinkedList<Position> mPositions;
+
+        public DictionaryIterator(ArrayList<CharGroup> root) {
+            mCurrentString = new StringBuilder();
+            mPositions = new LinkedList<Position>();
+            final Position rootPos = new Position(root);
+            mPositions.add(rootPos);
+        }
+
+        @Override
+        public boolean hasNext() {
+            for (Position p : mPositions) {
+                if (p.pos.hasNext()) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public Word next() {
+            Position currentPos = mPositions.getLast();
+            mCurrentString.setLength(mCurrentString.length() - currentPos.length);
+
+            do {
+                if (currentPos.pos.hasNext()) {
+                    final CharGroup currentGroup = currentPos.pos.next();
+                    currentPos.length = currentGroup.mChars.length;
+                    for (int i : currentGroup.mChars)
+                        mCurrentString.append(Character.toChars(i));
+                    if (null != currentGroup.mChildren) {
+                        currentPos = new Position(currentGroup.mChildren.mData);
+                        mPositions.addLast(currentPos);
+                    }
+                    if (currentGroup.mFrequency >= 0)
+                        return new Word(mCurrentString.toString(), currentGroup.mFrequency,
+                                currentGroup.mBigrams);
+                } else {
+                    mPositions.removeLast();
+                    currentPos = mPositions.getLast();
+                    mCurrentString.setLength(mCurrentString.length() - mPositions.getLast().length);
+                }
+            } while(true);
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException("Unsupported yet");
+        }
+
+    }
+
+    /**
+     * Method to return an iterator.
+     *
+     * This method enables Java's enhanced for loop. With this you can have a FusionDictionary x
+     * and say : for (Word w : x) {}
+     */
+    @Override
+    public Iterator<Word> iterator() {
+        return new DictionaryIterator(mRoot.mData);
+    }
+}
diff --git a/tools/makedict2/src/com/android/inputmethod/latin/MakedictLog.java b/tools/makedict2/src/com/android/inputmethod/latin/MakedictLog.java
new file mode 100644
index 0000000..badb2ff
--- /dev/null
+++ b/tools/makedict2/src/com/android/inputmethod/latin/MakedictLog.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011 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;
+
+/**
+ * Wrapper to redirect log events to the right output medium.
+ */
+public class MakedictLog {
+
+    private static void print(String message) {
+        System.out.println(message);
+    }
+
+    public static void d(String message) {
+        print(message);
+    }
+    public static void e(String message) {
+        print(message);
+    }
+    public static void i(String message) {
+        print(message);
+    }
+    public static void w(String message) {
+        print(message);
+    }
+}
diff --git a/tools/makedict2/src/com/android/inputmethod/latin/PendingAttribute.java b/tools/makedict2/src/com/android/inputmethod/latin/PendingAttribute.java
new file mode 100644
index 0000000..e502021
--- /dev/null
+++ b/tools/makedict2/src/com/android/inputmethod/latin/PendingAttribute.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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;
+
+/**
+ * A not-yet-resolved attribute.
+ *
+ * An attribute is either a bigram or an shortcut.
+ * All instances of this class are always immutable.
+ */
+public class PendingAttribute {
+    public final int mFrequency;
+    public final int mAddress;
+    public PendingAttribute(final int frequency, final int address) {
+        mFrequency = frequency;
+        mAddress = address;
+    }
+}
diff --git a/tools/makedict2/src/com/android/inputmethod/latin/UnsupportedFormatException.java b/tools/makedict2/src/com/android/inputmethod/latin/UnsupportedFormatException.java
new file mode 100644
index 0000000..511ad56
--- /dev/null
+++ b/tools/makedict2/src/com/android/inputmethod/latin/UnsupportedFormatException.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011 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;
+
+/**
+ * Simple exception thrown when a file format is not recognized.
+ */
+public class UnsupportedFormatException extends Exception {
+    public UnsupportedFormatException(String description) {
+        super(description);
+    }
+}
diff --git a/tools/makedict2/src/com/android/inputmethod/latin/Word.java b/tools/makedict2/src/com/android/inputmethod/latin/Word.java
new file mode 100644
index 0000000..916165a
--- /dev/null
+++ b/tools/makedict2/src/com/android/inputmethod/latin/Word.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 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;
+
+import com.android.inputmethod.latin.FusionDictionary.WeightedString;
+
+import java.util.ArrayList;
+
+/**
+ * Utility class for a word with a frequency.
+ *
+ * This is chiefly used to iterate a dictionary.
+ */
+public class Word implements Comparable<Word> {
+    final String mWord;
+    final int mFrequency;
+    final ArrayList<WeightedString> mBigrams;
+
+    public Word(String word, int frequency, ArrayList<WeightedString> bigrams) {
+        mWord = word;
+        mFrequency = frequency;
+        mBigrams = bigrams;
+    }
+
+    /**
+     * Three-way comparison.
+     *
+     * A Word x is greater than a word y if x has a higher frequency. If they have the same
+     * frequency, they are sorted in lexicographic order.
+     */
+    @Override
+    public int compareTo(Word w) {
+        if (mFrequency < w.mFrequency) return 1;
+        if (mFrequency > w.mFrequency) return -1;
+        return mWord.compareTo(w.mWord);
+    }
+
+    /**
+     * Equality test.
+     *
+     * Words are equal if they have the same frequency, the same spellings, and the same
+     * attributes.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Word)) return false;
+        Word w = (Word)o;
+        return mFrequency == w.mFrequency && mWord.equals(w.mWord)
+                && mBigrams.equals(w.mBigrams);
+    }
+}
diff --git a/tools/makedict2/src/com/android/inputmethod/latin/XmlDictInputOutput.java b/tools/makedict2/src/com/android/inputmethod/latin/XmlDictInputOutput.java
new file mode 100644
index 0000000..096bfd1
--- /dev/null
+++ b/tools/makedict2/src/com/android/inputmethod/latin/XmlDictInputOutput.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2011 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;
+
+import com.android.inputmethod.latin.FusionDictionary.WeightedString;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.TreeSet;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Reads and writes XML files for a FusionDictionary.
+ *
+ * All functions in this class are static.
+ */
+public class XmlDictInputOutput {
+
+    private static final String WORD_TAG = "w";
+    private static final String BIGRAM_TAG = "bigram";
+    private static final String FREQUENCY_ATTR = "f";
+    private static final String WORD_ATTR = "word";
+
+    /**
+     * SAX handler for a unigram XML file.
+     */
+    static private class UnigramHandler extends DefaultHandler {
+        // Parser states
+        private static final int NONE = 0;
+        private static final int START = 1;
+        private static final int WORD = 2;
+        private static final int BIGRAM = 4;
+        private static final int END = 5;
+        private static final int UNKNOWN = 6;
+
+        final FusionDictionary mDictionary;
+        int mState; // the state of the parser
+        int mFreq; // the currently read freq
+        final HashMap<String, ArrayList<WeightedString>> mBigramsMap;
+
+        /**
+         * Create the handler.
+         *
+         * @param dict the dictionary to construct.
+         * @param bigrams the bigrams as a map. This may be empty, but may not be null.
+         */
+        public UnigramHandler(FusionDictionary dict,
+                HashMap<String, ArrayList<WeightedString>> bigrams) {
+            mDictionary = dict;
+            mBigramsMap = bigrams;
+            mState = START;
+            mFreq = 0;
+        }
+
+        @Override
+        public void startElement(String uri, String localName, String qName, Attributes attrs) {
+            if (WORD_TAG.equals(localName)) {
+                mState = WORD;
+                for (int attrIndex = 0; attrIndex < attrs.getLength(); ++attrIndex) {
+                    final String attrName = attrs.getLocalName(attrIndex);
+                    if (FREQUENCY_ATTR.equals(attrName)) {
+                        mFreq = Integer.parseInt(attrs.getValue(attrIndex));
+                    }
+                }
+            } else {
+                mState = UNKNOWN;
+            }
+        }
+
+        @Override
+        public void characters(char[] ch, int start, int length) {
+            if (WORD == mState) {
+                final String word = String.copyValueOf(ch, start, length);
+                mDictionary.add(word, mFreq, mBigramsMap.get(word));
+            }
+        }
+
+        @Override
+        public void endElement(String uri, String localName, String qName) {
+            if (WORD == mState) mState = START;
+        }
+    }
+
+    /**
+     * SAX handler for a bigram XML file.
+     */
+    static private class BigramHandler extends DefaultHandler {
+        private final static String BIGRAM_W1_TAG = "bi";
+        private final static String BIGRAM_W2_TAG = "w";
+        private final static String BIGRAM_W1_ATTRIBUTE = "w1";
+        private final static String BIGRAM_W2_ATTRIBUTE = "w2";
+        private final static String BIGRAM_FREQ_ATTRIBUTE = "p";
+
+        String mW1;
+        final HashMap<String, ArrayList<WeightedString>> mBigramsMap;
+
+        public BigramHandler() {
+            mW1 = null;
+            mBigramsMap = new HashMap<String, ArrayList<WeightedString>>();
+        }
+
+        @Override
+        public void startElement(String uri, String localName, String qName, Attributes attrs) {
+            if (BIGRAM_W1_TAG.equals(localName)) {
+                mW1 = attrs.getValue(uri, BIGRAM_W1_ATTRIBUTE);
+            } else if (BIGRAM_W2_TAG.equals(localName)) {
+                String w2 = attrs.getValue(uri, BIGRAM_W2_ATTRIBUTE);
+                int freq = Integer.parseInt(attrs.getValue(uri, BIGRAM_FREQ_ATTRIBUTE));
+                WeightedString bigram = new WeightedString(w2, freq / 8);
+                ArrayList<WeightedString> bigramList = mBigramsMap.get(mW1);
+                if (null == bigramList) bigramList = new ArrayList<WeightedString>();
+                bigramList.add(bigram);
+                mBigramsMap.put(mW1, bigramList);
+            }
+        }
+
+        public HashMap<String, ArrayList<WeightedString>> getBigramMap() {
+            return mBigramsMap;
+        }
+    }
+
+    /**
+     * Reads a dictionary from an XML file.
+     *
+     * This is the public method that will parse an XML file and return the corresponding memory
+     * representation.
+     *
+     * @param unigrams the file to read the data from.
+     * @return the in-memory representation of the dictionary.
+     */
+    public static FusionDictionary readDictionaryXml(InputStream unigrams, InputStream bigrams)
+            throws SAXException, IOException, ParserConfigurationException {
+        final SAXParserFactory factory = SAXParserFactory.newInstance();
+        factory.setNamespaceAware(true);
+        final SAXParser parser = factory.newSAXParser();
+        final BigramHandler bigramHandler = new BigramHandler();
+        if (null != bigrams) parser.parse(bigrams, bigramHandler);
+
+        final FusionDictionary dict = new FusionDictionary();
+        final UnigramHandler unigramHandler =
+                new UnigramHandler(dict, bigramHandler.getBigramMap());
+        parser.parse(unigrams, unigramHandler);
+        return dict;
+    }
+
+    /**
+     * Reads a dictionary in the first, legacy XML format
+     *
+     * This method reads data from the parser and creates a new FusionDictionary with it.
+     * The format parsed by this method is the format used before Ice Cream Sandwich,
+     * which has no support for bigrams or shortcuts.
+     * It is important to note that this method expects the parser to have already eaten
+     * the first, all-encompassing tag.
+     *
+     * @param xpp the parser to read the data from.
+     * @return the parsed dictionary.
+     */
+
+    /**
+     * Writes a dictionary to an XML file.
+     *
+     * The output format is the "second" format, which supports bigrams and shortcuts.
+     *
+     * @param destination a destination stream to write to.
+     * @param dict the dictionary to write.
+     */
+    public static void writeDictionaryXml(Writer destination, FusionDictionary dict)
+            throws IOException {
+        final TreeSet<Word> set = new TreeSet<Word>();
+        for (Word word : dict) {
+            set.add(word);
+        }
+        // TODO: use an XMLSerializer if this gets big
+        destination.write("<wordlist format=\"2\">\n");
+        for (Word word : set) {
+            destination.write("  <" + WORD_TAG + " " + WORD_ATTR + "=\"" + word.mWord + "\" "
+                    + FREQUENCY_ATTR + "=\"" + word.mFrequency + "\">");
+            if (null != word.mBigrams) {
+                destination.write("\n");
+                for (WeightedString bigram : word.mBigrams) {
+                    destination.write("    <" + BIGRAM_TAG + " " + FREQUENCY_ATTR + "=\""
+                            + bigram.mFrequency + "\">" + bigram.mWord + "</" + BIGRAM_TAG + ">\n");
+                }
+                destination.write("  ");
+            }
+            destination.write("</" + WORD_TAG + ">\n");
+        }
+        destination.write("</wordlist>\n");
+        destination.close();
+    }
+}
diff --git a/tools/makedict2/tests/com/android/inputmethod/latin/BinaryDictInputOutputTest.java b/tools/makedict2/tests/com/android/inputmethod/latin/BinaryDictInputOutputTest.java
new file mode 100644
index 0000000..79cf14b
--- /dev/null
+++ b/tools/makedict2/tests/com/android/inputmethod/latin/BinaryDictInputOutputTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 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;
+
+import com.android.inputmethod.latin.FusionDictionary.Node;
+
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for BinaryDictInputOutput.
+ */
+public class BinaryDictInputOutputTest extends TestCase {
+
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    // Test the flattened array contains the expected number of nodes, and
+    // that it does not contain any duplicates.
+    public void testFlattenNodes() {
+        final FusionDictionary dict = new FusionDictionary();
+        dict.add("foo", 1, null);
+        dict.add("fta", 1, null);
+        dict.add("ftb", 1, null);
+        dict.add("bar", 1, null);
+        dict.add("fool", 1, null);
+        final ArrayList<Node> result = BinaryDictInputOutput.flattenTree(dict.mRoot);
+        assertEquals(4, result.size());
+        while (!result.isEmpty()) {
+            final Node n = result.remove(0);
+            assertFalse("Flattened array contained the same node twice", result.contains(n));
+        }
+    }
+
+}
