diff --git a/tools/makedict/Android.mk b/tools/makedict/Android.mk
index b9fc553..6832b1c 100644
--- a/tools/makedict/Android.mk
+++ b/tools/makedict/Android.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2009 The Android Open Source Project
+# 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.
@@ -17,8 +17,11 @@
 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 := makedict
+LOCAL_JAVA_LIBRARIES := junit
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 include $(LOCAL_PATH)/etc/Android.mk
diff --git a/tools/makedict/etc/Android.mk b/tools/makedict/etc/Android.mk
index da16286..96a90cb 100644
--- a/tools/makedict/etc/Android.mk
+++ b/tools/makedict/etc/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 The Android Open Source Project
+# 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.
@@ -15,6 +15,7 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_MODULE_TAGS := eng
+
 LOCAL_PREBUILT_EXECUTABLES := makedict
 include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/makedict/etc/makedict b/tools/makedict/etc/makedict
index 8420d6e..7c1c02e 100755
--- a/tools/makedict/etc/makedict
+++ b/tools/makedict/etc/makedict
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright 2009, The Android Open Source Project
+# 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.
@@ -60,4 +60,4 @@
 
 # need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
 # might need more memory, e.g. -Xmx128M
-exec java -Djava.ext.dirs="$frameworkdir" -jar "$jarpath" "$@"
+exec java -ea -Djava.ext.dirs="$frameworkdir" -jar "$jarpath" "$@"
diff --git a/tools/makedict/etc/manifest.txt b/tools/makedict/etc/manifest.txt
index aa3a3e8..948609d 100644
--- a/tools/makedict/etc/manifest.txt
+++ b/tools/makedict/etc/manifest.txt
@@ -1 +1 @@
-Main-Class: com.android.tools.dict.MakeBinaryDictionary
+Main-Class: com.android.inputmethod.latin.DictionaryMaker
diff --git a/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java b/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java
new file mode 100644
index 0000000..92f402d
--- /dev/null
+++ b/tools/makedict/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/makedict/src/com/android/inputmethod/latin/CharGroupInfo.java b/tools/makedict/src/com/android/inputmethod/latin/CharGroupInfo.java
new file mode 100644
index 0000000..6badfd1
--- /dev/null
+++ b/tools/makedict/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/makedict/src/com/android/inputmethod/latin/DictionaryMaker.java b/tools/makedict/src/com/android/inputmethod/latin/DictionaryMaker.java
new file mode 100644
index 0000000..1ba0107
--- /dev/null
+++ b/tools/makedict/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: makedict "
+                    + "[-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/makedict/src/com/android/inputmethod/latin/FusionDictionary.java b/tools/makedict/src/com/android/inputmethod/latin/FusionDictionary.java
new file mode 100644
index 0000000..031f35d
--- /dev/null
+++ b/tools/makedict/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/makedict/src/com/android/inputmethod/latin/MakedictLog.java b/tools/makedict/src/com/android/inputmethod/latin/MakedictLog.java
new file mode 100644
index 0000000..badb2ff
--- /dev/null
+++ b/tools/makedict/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/makedict/src/com/android/inputmethod/latin/PendingAttribute.java b/tools/makedict/src/com/android/inputmethod/latin/PendingAttribute.java
new file mode 100644
index 0000000..e502021
--- /dev/null
+++ b/tools/makedict/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/makedict/src/com/android/inputmethod/latin/UnsupportedFormatException.java b/tools/makedict/src/com/android/inputmethod/latin/UnsupportedFormatException.java
new file mode 100644
index 0000000..511ad56
--- /dev/null
+++ b/tools/makedict/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/makedict/src/com/android/inputmethod/latin/Word.java b/tools/makedict/src/com/android/inputmethod/latin/Word.java
new file mode 100644
index 0000000..916165a
--- /dev/null
+++ b/tools/makedict/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/makedict/src/com/android/inputmethod/latin/XmlDictInputOutput.java b/tools/makedict/src/com/android/inputmethod/latin/XmlDictInputOutput.java
new file mode 100644
index 0000000..096bfd1
--- /dev/null
+++ b/tools/makedict/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/makedict/src/com/android/tools/dict/BigramDictionary.java b/tools/makedict/src/com/android/tools/dict/BigramDictionary.java
deleted file mode 100644
index 35115bf..0000000
--- a/tools/makedict/src/com/android/tools/dict/BigramDictionary.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2010 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.tools.dict;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Helper for MakeBinaryDictionary
- * Deals with all the bigram data
- */
-public class BigramDictionary {
-
-    /*
-     * Must match the values in the client side which is located in dictionary.cpp & dictionary.h
-     * Changing these values will generate totally different structure which must be also reflected
-     * on the client side.
-     */
-    public static final int FLAG_BIGRAM_READ = 0x80;
-    public static final int FLAG_BIGRAM_CHILDEXIST = 0x40;
-    public static final int FLAG_BIGRAM_CONTINUED = 0x80;
-    public static final int FLAG_BIGRAM_FREQ = 0x7F;
-
-    public static final int FOR_REVERSE_LOOKUPALL = -99;
-
-    public ArrayList<String> mBigramToFill = new ArrayList<String>();
-    public ArrayList<Integer> mBigramToFillAddress = new ArrayList<Integer>();
-
-    public HashMap<String, Bigram> mBi;
-
-    public boolean mHasBigram;
-
-    public BigramDictionary(String bigramSrcFilename, boolean hasBigram) {
-        mHasBigram = hasBigram;
-        loadBigram(bigramSrcFilename);
-    }
-
-    private void loadBigram(String filename) {
-        mBi = new HashMap<String, Bigram>();
-        if (!mHasBigram) {
-            System.out.println("Number of bigrams = " + Bigram.sBigramNum);
-            return;
-        }
-        try {
-            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
-            parser.parse(new File(filename), new DefaultHandler() {
-                String w1 = null;
-                boolean inWord1 = false;
-                boolean inWord2 = false;
-                int freq = 0, counter = 0;
-                Bigram tempBigram = null;
-
-                @Override
-                public void startElement(String uri, String localName,
-                        String qName, Attributes attributes) {
-                    if (qName.equals("bi")) {
-                        inWord1 = true;
-                        w1 = attributes.getValue(0);
-                        int count = Integer.parseInt(attributes.getValue(1));
-                        tempBigram = new Bigram(count);
-                        counter = 0;
-                    } else if (qName.equals("w")) {
-                        inWord2 = true;
-                        String word2 = attributes.getValue(0);
-                        int freq = Integer.parseInt(attributes.getValue(1));
-                        tempBigram.setWord2(counter, word2, freq);
-                        counter++;
-                        Bigram.sBigramNum++;
-                    }
-                }
-
-                @Override
-                public void endElement(String uri, String localName,
-                        String qName) {
-                    if (inWord2) {
-                        inWord2 = false;
-                    } else if (inWord1) {
-                        inWord1 = false;
-                        mBi.put(w1, tempBigram);
-                    }
-                }
-            });
-        } catch (Exception ioe) {
-            System.err.println("Exception in parsing bigram\n" + ioe);
-            ioe.printStackTrace();
-        }
-        System.out.println("Number of bigrams = " + Bigram.sBigramNum);
-    }
-
-    byte[] writeBigrams(byte[] dict, Map<String, Integer> mDictionary) {
-        for (int i = 0; i < mBigramToFill.size(); i++) {
-            String w1 = mBigramToFill.get(i);
-            int address = mBigramToFillAddress.get(i);
-
-            Bigram temp = mBi.get(w1);
-            int word2Count = temp.count;
-            int j4;
-            for (int j = 0; j < word2Count; j++) {
-                if (!mDictionary.containsKey(temp.word2[j])) {
-                    System.out.println("Not in dictionary: " + temp.word2[j]);
-                    System.exit(0);
-                } else {
-                    j4 = (j * 4);
-                    int addressOfWord2 = mDictionary.get(temp.word2[j]);
-                    dict[address + j4 + 0] = (byte) (((addressOfWord2 & 0x3F0000) >> 16)
-                            | FLAG_BIGRAM_READ);
-                    dict[address + j4 + 1] = (byte) ((addressOfWord2 & 0x00FF00) >> 8);
-                    dict[address + j4 + 2] = (byte) ((addressOfWord2 & 0x0000FF));
-
-                    if (j == (word2Count - 1)) {
-                        dict[address + j4 + 3] = (byte) (temp.freq[j] & FLAG_BIGRAM_FREQ);
-                    } else {
-                        dict[address + j4 + 3] = (byte) ((temp.freq[j] & FLAG_BIGRAM_FREQ)
-                                | FLAG_BIGRAM_CONTINUED);
-                    }
-                }
-            }
-        }
-
-        return dict;
-    }
-
-    void reverseLookupAll(Map<String, Integer> mDictionary, byte[] dict) {
-        Set<String> st = mDictionary.keySet();
-        for (String s : st) {
-            searchForTerminalNode(mDictionary.get(s), FOR_REVERSE_LOOKUPALL, dict);
-        }
-    }
-
-    void searchForTerminalNode(int bigramAddress, int frequency, byte[] dict) {
-        StringBuilder sb = new StringBuilder(48);
-        int pos;
-        boolean found = false;
-        int followDownBranchAddress = 2;
-        char followingChar = ' ';
-        int depth = 0;
-        int totalLoopCount = 0;
-
-        while (!found) {
-            boolean followDownAddressSearchStop = false;
-            boolean firstAddress = true;
-            boolean haveToSearchAll = true;
-
-            if (depth > 0) {
-                sb.append(followingChar);
-            }
-            pos = followDownBranchAddress; // pos start at count
-            int count = dict[pos] & 0xFF;
-            pos++;
-            for (int i = 0; i < count; i++) {
-                totalLoopCount++;
-                // pos at data
-                pos++;
-                // pos now at flag
-                if (!MakeBinaryDictionary.getFirstBitOfByte(pos, dict)) { // non-terminal
-                    if (!followDownAddressSearchStop) {
-                        int addr = MakeBinaryDictionary.get22BitAddress(pos, dict);
-                        if (addr > bigramAddress) {
-                            followDownAddressSearchStop = true;
-                            if (firstAddress) {
-                                firstAddress = false;
-                                haveToSearchAll = true;
-                            } else if (!haveToSearchAll) {
-                                break;
-                            }
-                        } else {
-                            followDownBranchAddress = addr;
-                            followingChar = (char) (0xFF & dict[pos-1]);
-                            if(firstAddress) {
-                                firstAddress = false;
-                                haveToSearchAll = false;
-                            }
-                        }
-                    }
-                    pos += 3;
-                } else if (MakeBinaryDictionary.getFirstBitOfByte(pos, dict)) { // terminal
-                    // found !!
-                    if (bigramAddress == (pos-1)) {
-                        sb.append((char) (0xFF & dict[pos-1]));
-                        found = true;
-                        break;
-                    }
-
-                    // address + freq (4 byte)
-                    if (MakeBinaryDictionary.getSecondBitOfByte(pos, dict)) {
-                        if (!followDownAddressSearchStop) {
-                            int addr = MakeBinaryDictionary.get22BitAddress(pos, dict);
-                            if (addr > bigramAddress) {
-                                followDownAddressSearchStop = true;
-                                if (firstAddress) {
-                                    firstAddress = false;
-                                    haveToSearchAll = true;
-                                } else if (!haveToSearchAll) {
-                                    break;
-                                }
-                            } else {
-                                followDownBranchAddress = addr;
-                                followingChar = (char) (0xFF & dict[pos-1]);
-                                if(firstAddress) {
-                                    firstAddress = false;
-                                    haveToSearchAll = true;
-                                }
-                            }
-                        }
-                        pos += 4;
-                    } else { // freq only (2 byte)
-                        pos += 2;
-                    }
-                    // skipping bigram
-                    int bigramExist = (dict[pos] & FLAG_BIGRAM_READ);
-                    if (bigramExist > 0) {
-                        int nextBigramExist = 1;
-                        while (nextBigramExist > 0) {
-                            pos += 3;
-                            nextBigramExist = (dict[pos++] & FLAG_BIGRAM_CONTINUED);
-                        }
-                    } else {
-                        pos++;
-                    }
-                }
-            }
-            depth++;
-            if (followDownBranchAddress == 2) {
-                System.out.println("ERROR!!! Cannot find bigram!!");
-                System.exit(0);
-            }
-        }
-
-        if (frequency == FOR_REVERSE_LOOKUPALL) {
-            System.out.println("Reverse: " + sb.toString() + " (" + bigramAddress + ")"
-                    + "   Loop: " + totalLoopCount);
-        } else {
-            System.out.println("   bigram: " + sb.toString() + " (" + bigramAddress + ") freq: "
-                    + frequency + "   Loop: " + totalLoopCount);
-        }
-    }
-
-    static class Bigram {
-        String[] word2;
-        int[] freq;
-        int count;
-        static int sBigramNum = 0;
-
-        String getSecondWord(int i) {
-            return word2[i];
-        }
-
-        int getFrequency(int i) {
-            return (freq[i] == 0) ? 1 : freq[i];
-        }
-
-        void setWord2(int index, String word2, int freq) {
-            this.word2[index] = word2;
-            this.freq[index] = freq;
-        }
-
-        public Bigram(int word2Count) {
-            count = word2Count;
-            word2 = new String[word2Count];
-            freq = new int[word2Count];
-        }
-    }
-}
diff --git a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java b/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
deleted file mode 100644
index 4a285ff..0000000
--- a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (C) 2009 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.tools.dict;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Compresses a list of words, frequencies, and bigram data
- * into a tree structured binary dictionary.
- * Dictionary Version: 200 (may contain bigrams)
- *  Version number started from 200 rather than 1 because we wanted to prevent number of roots in
- *  any old dictionaries being mistaken as the version number. There is not a chance that there
- *  will be more than 200 roots. Version number should be increased when there is structural change
- *  in the data. There is no need to increase the version when only the words in the data changes.
- */
-public class MakeBinaryDictionary {
-    private static final int VERSION_NUM = 200;
-
-    private static final String TAG_WORD = "w";
-    private static final String ATTR_FREQ = "f";
-
-    private static final int FLAG_ADDRESS_MASK  = 0x400000;
-    private static final int FLAG_TERMINAL_MASK = 0x800000;
-    private static final int ADDRESS_MASK = 0x3FFFFF;
-
-    private static final int INITIAL_STRING_BUILDER_CAPACITY = 48;
-
-    /**
-     * Unit for this variable is in bytes
-     * If destination file name is main.dict and file limit causes dictionary to be separated into
-     * multiple file, it will generate main0.dict, main1.dict, and so forth.
-     */
-    private static int sOutputFileSize;
-    private static boolean sSplitOutput;
-
-    private static final CharNode EMPTY_NODE = new CharNode();
-
-    private List<CharNode> mRoots;
-    private Map<String, Integer> mDictionary;
-    private int mWordCount;
-
-    private BigramDictionary mBigramDict;
-
-    private static class CharNode {
-        char data;
-        int freq;
-        boolean terminal;
-        List<CharNode> children;
-        static int sNodes;
-
-        public CharNode() {
-            sNodes++;
-        }
-    }
-
-    private static void usage() {
-        System.err.println("Usage: makedict -s <src_dict.xml> [-b <src_bigram.xml>] "
-                + "-d <dest.dict> [--size filesize]");
-        System.exit(-1);
-    }
-    
-    public static void main(String[] args) {
-        int checkSource = -1;
-        int checkBigram = -1;
-        int checkDest = -1;
-        int checkFileSize = -1;
-        for (int i = 0; i < args.length; i+=2) {
-            if (args[i].equals("-s")) checkSource = (i + 1);
-            if (args[i].equals("-b")) checkBigram = (i + 1);
-            if (args[i].equals("-d")) checkDest = (i + 1);
-            if (args[i].equals("--size")) checkFileSize = (i + 1);
-        }
-        if (checkFileSize >= 0) {
-            sSplitOutput = true;
-            sOutputFileSize = Integer.parseInt(args[checkFileSize]);
-        } else {
-            sSplitOutput = false;
-        }
-        if (checkDest >= 0 && !args[checkDest].endsWith(".dict")) {
-            System.err.println("Error: Dictionary output file extension should be \".dict\"");
-            usage();
-        } else if (checkSource >= 0 && checkBigram >= 0 && checkDest >= 0 &&
-                ((!sSplitOutput && args.length == 6) || (sSplitOutput && args.length == 8))) {
-            new MakeBinaryDictionary(args[checkSource], args[checkBigram], args[checkDest]);
-        } else if (checkSource >= 0 && checkDest >= 0 &&
-                ((!sSplitOutput && args.length == 4) || (sSplitOutput && args.length == 6))) {
-            new MakeBinaryDictionary(args[checkSource], null, args[checkDest]);
-        } else {
-            usage();
-        }
-    }
-
-    private MakeBinaryDictionary(String srcFilename, String bigramSrcFilename,
-            String destFilename) {
-        System.out.println("Generating dictionary version " + VERSION_NUM);
-        mBigramDict = new BigramDictionary(bigramSrcFilename, (bigramSrcFilename != null));
-        populateDictionary(srcFilename);
-        writeToDict(destFilename);
-
-        // Enable the code below to verify that the generated tree is traversable
-        // and bigram data is stored correctly.
-        if (false) {
-            mBigramDict.reverseLookupAll(mDictionary, mDict);
-            traverseDict(2, new char[32], 0);
-        }
-    }
-
-    private void populateDictionary(String filename) {
-        mRoots = new ArrayList<CharNode>();
-        mDictionary = new HashMap<String, Integer>();
-        try {
-            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
-            parser.parse(new File(filename), new DefaultHandler() {
-                boolean inWord;
-                int freq;
-                StringBuilder wordBuilder = new StringBuilder(INITIAL_STRING_BUILDER_CAPACITY);
-
-                @Override
-                public void startElement(String uri, String localName,
-                        String qName, Attributes attributes) {
-                    if (qName.equals(TAG_WORD)) {
-                        inWord = true;
-                        freq = Integer.parseInt(attributes.getValue(ATTR_FREQ));
-                        wordBuilder.setLength(0);
-                    }
-                }
-
-                @Override
-                public void characters(char[] data, int offset, int length) {
-                    // Ignore other whitespace
-                    if (!inWord) return;
-                    wordBuilder.append(data, offset, length);
-                }
-
-                @Override
-                public void endElement(String uri, String localName,
-                        String qName) {
-                    if (qName.equals(TAG_WORD)) {
-                        if (wordBuilder.length() >= 1) {
-                            addWordTop(wordBuilder.toString(), freq);
-                            mWordCount++;
-                        }
-                        inWord = false;
-                    }
-                }
-            });
-        } catch (Exception ioe) {
-            System.err.println("Exception in parsing\n" + ioe);
-            ioe.printStackTrace();
-        }
-        System.out.println("Nodes = " + CharNode.sNodes);
-    }
-
-    private static int indexOf(List<CharNode> children, char c) {
-        if (children == null) {
-            return -1;
-        }
-        for (int i = 0; i < children.size(); i++) {
-            if (children.get(i).data == c) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    private void addWordTop(String word, int freq) {
-        if (freq < 0) {
-            freq = 0;
-        } else if (freq > 255) {
-            freq = 255;
-        }
-        char firstChar = word.charAt(0);
-        int index = indexOf(mRoots, firstChar);
-        if (index == -1) {
-            CharNode newNode = new CharNode();
-            newNode.data = firstChar;
-            index = mRoots.size();
-            mRoots.add(newNode);
-        }
-        final CharNode node = mRoots.get(index);
-        if (word.length() > 1) {
-            addWordRec(node, word, 1, freq);
-        } else {
-            node.terminal = true;
-            node.freq = freq;
-        }
-    }
-
-    private void addWordRec(CharNode parent, String word, int charAt, int freq) {
-        CharNode child = null;
-        char data = word.charAt(charAt);
-        if (parent.children == null) {
-            parent.children = new ArrayList<CharNode>();
-        } else {
-            for (int i = 0; i < parent.children.size(); i++) {
-                CharNode node = parent.children.get(i);
-                if (node.data == data) {
-                    child = node;
-                    break;
-                }
-            }
-        }
-        if (child == null) {
-            child = new CharNode();
-            parent.children.add(child);
-        }
-        child.data = data;
-        if (word.length() > charAt + 1) {
-            addWordRec(child, word, charAt + 1, freq);
-        } else {
-            child.terminal = true;
-            child.freq = freq;
-        }
-    }
-
-    private byte[] mDict;
-    private int mDictSize;
-    private static final int CHAR_WIDTH = 8;
-    private static final int FLAGS_WIDTH = 1; // Terminal flag (word end)
-    private static final int ADDR_WIDTH = 23; // Offset to children
-    private static final int FREQ_WIDTH_BYTES = 1;
-    private static final int COUNT_WIDTH_BYTES = 1;
-
-    private void addCount(int count) {
-        mDict[mDictSize++] = (byte) (0xFF & count);
-    }
-
-    private void addNode(CharNode node, String word1) {
-        if (node.terminal) { // store address of each word1 for bigram dic generation
-            mDictionary.put(word1, mDictSize);
-        }
-
-        int charData = 0xFFFF & node.data;
-        if (charData > 254) {
-            mDict[mDictSize++] = (byte) 255;
-            mDict[mDictSize++] = (byte) ((node.data >> 8) & 0xFF);
-            mDict[mDictSize++] = (byte) (node.data & 0xFF);
-        } else {
-            mDict[mDictSize++] = (byte) (0xFF & node.data);
-        }
-        if (node.children != null) {
-            mDictSize += 3; // Space for children address
-        } else {
-            mDictSize += 1; // Space for just the terminal/address flags
-        }
-        if ((0xFFFFFF & node.freq) > 255) {
-            node.freq = 255;
-        }
-        if (node.terminal) {
-            byte freq = (byte) (0xFF & node.freq);
-            mDict[mDictSize++] = freq;
-            // bigram
-            if (mBigramDict.mBi.containsKey(word1)) {
-                int count = mBigramDict.mBi.get(word1).count;
-                mBigramDict.mBigramToFill.add(word1);
-                mBigramDict.mBigramToFillAddress.add(mDictSize);
-                mDictSize += (4 * count);
-            } else {
-                mDict[mDictSize++] = (byte) (0x00);
-            }
-        }
-    }
-
-    private int mNullChildrenCount = 0;
-    private int mNotTerminalCount = 0;
-
-    private void updateNodeAddress(int nodeAddress, CharNode node,
-            int childrenAddress) {
-        if ((mDict[nodeAddress] & 0xFF) == 0xFF) { // 3 byte character
-            nodeAddress += 2;
-        }
-        childrenAddress = ADDRESS_MASK & childrenAddress;
-        if (childrenAddress == 0) {
-            mNullChildrenCount++;
-        } else {
-            childrenAddress |= FLAG_ADDRESS_MASK;
-        }
-        if (node.terminal) {
-            childrenAddress |= FLAG_TERMINAL_MASK;
-        } else {
-            mNotTerminalCount++;
-        }
-        mDict[nodeAddress + 1] = (byte) (childrenAddress >> 16);
-        if ((childrenAddress & FLAG_ADDRESS_MASK) != 0) {
-            mDict[nodeAddress + 2] = (byte) ((childrenAddress & 0xFF00) >> 8);
-            mDict[nodeAddress + 3] = (byte) ((childrenAddress & 0xFF));
-        }
-    }
-
-    private void writeWordsRec(List<CharNode> children, StringBuilder word) {
-        if (children == null || children.size() == 0) {
-            return;
-        }
-        final int childCount = children.size();
-        addCount(childCount);
-        int[] childrenAddresses = new int[childCount];
-        for (int j = 0; j < childCount; j++) {
-            CharNode child = children.get(j);
-            childrenAddresses[j] = mDictSize;
-            word.append(child.data);
-            addNode(child, word.toString());
-            word.setLength(word.length() - 1);
-        }
-        for (int j = 0; j < childCount; j++) {
-            CharNode child = children.get(j);
-            int nodeAddress = childrenAddresses[j];
-            int cacheDictSize = mDictSize;
-            word.append(child.data);
-            writeWordsRec(child.children, word);
-            word.setLength(word.length() - 1);
-            updateNodeAddress(nodeAddress, child, child.children != null ? cacheDictSize : 0);
-        }
-    }
-
-    private void writeToDict(String dictFilename) {
-        // 4MB max, 22-bit offsets
-        mDict = new byte[4 * 1024 * 1024]; // 4MB upper limit. Actual is probably
-                                           // < 1MB in most cases, as there is a limit in the
-                                           // resource size in apks.
-        mDictSize = 0;
-
-        mDict[mDictSize++] = (byte) (0xFF & VERSION_NUM); // version info
-        mDict[mDictSize++] = (byte) (0xFF & (mBigramDict.mHasBigram ? 1 : 0));
-
-        final StringBuilder word = new StringBuilder(INITIAL_STRING_BUILDER_CAPACITY);
-        writeWordsRec(mRoots, word);
-        mDict = mBigramDict.writeBigrams(mDict, mDictionary);
-        System.out.println("Dict Size = " + mDictSize);
-        if (!sSplitOutput) {
-            sOutputFileSize = mDictSize;
-        }
-        try {
-            int currentLoc = 0;
-            int i = 0;
-            int extension = dictFilename.indexOf(".dict");
-            String filename = dictFilename.substring(0, extension);
-            while (mDictSize > 0) {
-                FileOutputStream fos;
-                if (sSplitOutput) {
-                    fos = new FileOutputStream(filename + i + ".dict");
-                } else {
-                    fos = new FileOutputStream(filename + ".dict");
-                }
-                if (mDictSize > sOutputFileSize) {
-                    fos.write(mDict, currentLoc, sOutputFileSize);
-                    mDictSize -= sOutputFileSize;
-                    currentLoc += sOutputFileSize;
-                } else {
-                    fos.write(mDict, currentLoc, mDictSize);
-                    mDictSize = 0;
-                }
-                fos.close();
-                i++;
-            }
-        } catch (IOException ioe) {
-            System.err.println("Error writing dict file:" + ioe);
-        }
-    }
-
-    private void traverseDict(int pos, char[] word, int depth) {
-        int count = mDict[pos++] & 0xFF;
-        for (int i = 0; i < count; i++) {
-            char c = (char) (mDict[pos++] & 0xFF);
-            if (c == 0xFF) { // two byte character
-                c = (char) (((mDict[pos] & 0xFF) << 8) | (mDict[pos+1] & 0xFF));
-                pos += 2;
-            }
-            word[depth] = c;
-            boolean terminal = getFirstBitOfByte(pos, mDict);
-            int address = 0;
-            if ((mDict[pos] & (FLAG_ADDRESS_MASK >> 16)) > 0) { // address check
-                address = get22BitAddress(pos, mDict);
-                pos += 3;
-            } else {
-                pos += 1;
-            }
-            if (terminal) {
-                showWord(word, depth + 1, mDict[pos] & 0xFF);
-                pos++;
-
-                int bigramExist = (mDict[pos] & mBigramDict.FLAG_BIGRAM_READ);
-                if (bigramExist > 0) {
-                    int nextBigramExist = 1;
-                    while (nextBigramExist > 0) {
-                        int bigramAddress = get22BitAddress(pos, mDict);
-                        pos += 3;
-                        int frequency = (mBigramDict.FLAG_BIGRAM_FREQ & mDict[pos]);
-                        mBigramDict.searchForTerminalNode(bigramAddress, frequency, mDict);
-                        nextBigramExist = (mDict[pos++] & mBigramDict.FLAG_BIGRAM_CONTINUED);
-                    }
-                } else {
-                    pos++;
-                }
-            }
-            if (address != 0) {
-                traverseDict(address, word, depth + 1);
-            }
-        }
-    }
-
-    private static void showWord(char[] word, int size, int freq) {
-        System.out.print(new String(word, 0, size) + " " + freq + "\n");
-    }
-
-    /* package */ static int get22BitAddress(int pos, byte[] dict) {
-        return ((dict[pos + 0] & 0x3F) << 16)
-                | ((dict[pos + 1] & 0xFF) << 8)
-                | ((dict[pos + 2] & 0xFF));
-    }
-
-    /* package */ static boolean getFirstBitOfByte(int pos, byte[] dict) {
-        return (dict[pos] & 0x80) > 0;
-    }
-
-    /* package */ static boolean getSecondBitOfByte(int pos, byte[] dict) {
-        return (dict[pos] & 0x40) > 0;
-    }
-}
diff --git a/tools/makedict/tests/com/android/inputmethod/latin/BinaryDictInputOutputTest.java b/tools/makedict/tests/com/android/inputmethod/latin/BinaryDictInputOutputTest.java
new file mode 100644
index 0000000..79cf14b
--- /dev/null
+++ b/tools/makedict/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));
+        }
+    }
+
+}
