diff --git a/java/proguard.flags b/java/proguard.flags
index 34e23aa..752ced3 100644
--- a/java/proguard.flags
+++ b/java/proguard.flags
@@ -41,13 +41,7 @@
 }
 
 -keep class com.android.inputmethod.latin.ResearchLogger {
-  void setLogFileManager(...);
-  void clearAll();
-  com.android.inputmethod.latin.ResearchLogger$LogFileManager getLogFileManager();
-}
-
--keep class com.android.inputmethod.latin.ResearchLogger$LogFileManager {
-  java.lang.String getContents();
+  void flush();
 }
 
 -keep class com.android.inputmethod.keyboard.KeyboardLayoutSet$Builder {
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index d5268ea..e20061d 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -23,7 +23,8 @@
     <bool name="config_enable_show_voice_key_option">true</bool>
     <bool name="config_enable_show_popup_on_keypress_option">true</bool>
     <bool name="config_enable_next_word_suggestions_option">true</bool>
-    <bool name="config_enable_usability_study_mode_option">false</bool>
+    <!-- TODO: Disable the following configuration for production. -->
+    <bool name="config_enable_usability_study_mode_option">true</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
     <bool name="config_default_popup_preview">true</bool>
     <!-- Default value for next word suggestion: while showing suggestions for a word should we weigh
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 21f175d..db84c20 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -422,67 +422,67 @@
      * This class parses Keyboard XML file and eventually build a Keyboard.
      * The Keyboard XML file looks like:
      * <pre>
-     *   &gt;!-- xml/keyboard.xml --&lt;
-     *   &gt;Keyboard keyboard_attributes*&lt;
-     *     &gt;!-- Keyboard Content --&lt;
-     *     &gt;Row row_attributes*&lt;
-     *       &gt;!-- Row Content --&lt;
-     *       &gt;Key key_attributes* /&lt;
-     *       &gt;Spacer horizontalGap="32.0dp" /&lt;
-     *       &gt;include keyboardLayout="@xml/other_keys"&lt;
+     *   &lt;!-- xml/keyboard.xml --&gt;
+     *   &lt;Keyboard keyboard_attributes*&gt;
+     *     &lt;!-- Keyboard Content --&gt;
+     *     &lt;Row row_attributes*&gt;
+     *       &lt;!-- Row Content --&gt;
+     *       &lt;Key key_attributes* /&gt;
+     *       &lt;Spacer horizontalGap="32.0dp" /&gt;
+     *       &lt;include keyboardLayout="@xml/other_keys"&gt;
      *       ...
-     *     &gt;/Row&lt;
-     *     &gt;include keyboardLayout="@xml/other_rows"&lt;
+     *     &lt;/Row&gt;
+     *     &lt;include keyboardLayout="@xml/other_rows"&gt;
      *     ...
-     *   &gt;/Keyboard&lt;
+     *   &lt;/Keyboard&gt;
      * </pre>
-     * The XML file which is included in other file must have &gt;merge&lt; as root element,
+     * The XML file which is included in other file must have &lt;merge&gt; as root element,
      * such as:
      * <pre>
-     *   &gt;!-- xml/other_keys.xml --&lt;
-     *   &gt;merge&lt;
-     *     &gt;Key key_attributes* /&lt;
+     *   &lt;!-- xml/other_keys.xml --&gt;
+     *   &lt;merge&gt;
+     *     &lt;Key key_attributes* /&gt;
      *     ...
-     *   &gt;/merge&lt;
+     *   &lt;/merge&gt;
      * </pre>
      * and
      * <pre>
-     *   &gt;!-- xml/other_rows.xml --&lt;
-     *   &gt;merge&lt;
-     *     &gt;Row row_attributes*&lt;
-     *       &gt;Key key_attributes* /&lt;
-     *     &gt;/Row&lt;
+     *   &lt;!-- xml/other_rows.xml --&gt;
+     *   &lt;merge&gt;
+     *     &lt;Row row_attributes*&gt;
+     *       &lt;Key key_attributes* /&gt;
+     *     &lt;/Row&gt;
      *     ...
-     *   &gt;/merge&lt;
+     *   &lt;/merge&gt;
      * </pre>
      * You can also use switch-case-default tags to select Rows and Keys.
      * <pre>
-     *   &gt;switch&lt;
-     *     &gt;case case_attribute*&lt;
-     *       &gt;!-- Any valid tags at switch position --&lt;
-     *     &gt;/case&lt;
+     *   &lt;switch&gt;
+     *     &lt;case case_attribute*&gt;
+     *       &lt;!-- Any valid tags at switch position --&gt;
+     *     &lt;/case&gt;
      *     ...
-     *     &gt;default&lt;
-     *       &gt;!-- Any valid tags at switch position --&lt;
-     *     &gt;/default&lt;
-     *   &gt;/switch&lt;
+     *     &lt;default&gt;
+     *       &lt;!-- Any valid tags at switch position --&gt;
+     *     &lt;/default&gt;
+     *   &lt;/switch&gt;
      * </pre>
      * You can declare Key style and specify styles within Key tags.
      * <pre>
-     *     &gt;switch&lt;
-     *       &gt;case mode="email"&lt;
-     *         &gt;key-style styleName="f1-key" parentStyle="modifier-key"
+     *     &lt;switch&gt;
+     *       &lt;case mode="email"&gt;
+     *         &lt;key-style styleName="f1-key" parentStyle="modifier-key"
      *           keyLabel=".com"
-     *         /&lt;
-     *       &gt;/case&lt;
-     *       &gt;case mode="url"&lt;
-     *         &gt;key-style styleName="f1-key" parentStyle="modifier-key"
+     *         /&gt;
+     *       &lt;/case&gt;
+     *       &lt;case mode="url"&gt;
+     *         &lt;key-style styleName="f1-key" parentStyle="modifier-key"
      *           keyLabel="http://"
-     *         /&lt;
-     *       &gt;/case&lt;
-     *     &gt;/switch&lt;
+     *         /&gt;
+     *       &lt;/case&gt;
+     *     &lt;/switch&gt;
      *     ...
-     *     &gt;Key keyStyle="shift-key" ... /&lt;
+     *     &lt;Key keyStyle="shift-key" ... /&gt;
      * </pre>
      */
 
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index babf6ec..34e428e 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -242,10 +242,6 @@
                     + " ignoreModifier=" + ignoreModifierKey
                     + " enabled=" + key.isEnabled());
         }
-        if (ProductionFlag.IS_EXPERIMENTAL) {
-            ResearchLogger.pointerTracker_callListenerOnPressAndCheckKeyboardLayoutChange(key,
-                    ignoreModifierKey);
-        }
         if (ignoreModifierKey) {
             return false;
         }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 43ffb85..5aa9a08 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -305,9 +305,6 @@
             Log.d(TAG, "onPressKey: code=" + Keyboard.printableCode(code)
                    + " single=" + isSinglePointer + " autoCaps=" + autoCaps + " " + this);
         }
-        if (ProductionFlag.IS_EXPERIMENTAL) {
-            ResearchLogger.keyboardState_onPressKey(code, this);
-        }
         if (code == Keyboard.CODE_SHIFT) {
             onPressShift();
         } else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
@@ -341,9 +338,6 @@
             Log.d(TAG, "onReleaseKey: code=" + Keyboard.printableCode(code)
                     + " sliding=" + withSliding + " " + this);
         }
-        if (ProductionFlag.IS_EXPERIMENTAL) {
-            ResearchLogger.keyboardState_onReleaseKey(this, code, withSliding);
-        }
         if (code == Keyboard.CODE_SHIFT) {
             onReleaseShift(withSliding);
         } else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
@@ -375,9 +369,6 @@
         if (DEBUG_EVENT) {
             Log.d(TAG, "onLongPressTimeout: code=" + Keyboard.printableCode(code) + " " + this);
         }
-        if (ProductionFlag.IS_EXPERIMENTAL) {
-            ResearchLogger.keyboardState_onLongPressTimeout(code, this);
-        }
         if (mIsAlphabetMode && code == Keyboard.CODE_SHIFT) {
             mLongPressShiftLockFired = true;
             mSwitchActions.hapticAndAudioFeedback(code);
@@ -509,9 +500,6 @@
         if (DEBUG_EVENT) {
             Log.d(TAG, "onCancelInput: single=" + isSinglePointer + " " + this);
         }
-        if (ProductionFlag.IS_EXPERIMENTAL) {
-            ResearchLogger.keyboardState_onCancelInput(isSinglePointer, this);
-        }
         // Switch back to the previous keyboard mode if the user cancels sliding input.
         if (isSinglePointer) {
             if (mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL) {
@@ -543,9 +531,6 @@
                     + " single=" + isSinglePointer
                     + " autoCaps=" + autoCaps + " " + this);
         }
-        if (ProductionFlag.IS_EXPERIMENTAL) {
-            ResearchLogger.keyboardState_onCodeInput(code, isSinglePointer, autoCaps, this);
-        }
 
         switch (mSwitchState) {
         case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
diff --git a/java/src/com/android/inputmethod/latin/EditingUtils.java b/java/src/com/android/inputmethod/latin/EditingUtils.java
index 0f34d50..479b3bf 100644
--- a/java/src/com/android/inputmethod/latin/EditingUtils.java
+++ b/java/src/com/android/inputmethod/latin/EditingUtils.java
@@ -55,7 +55,7 @@
      */
     public static String getWordAtCursor(InputConnection connection, String separators) {
         // getWordRangeAtCursor returns null if the connection is null
-        Range r = getWordRangeAtCursor(connection, separators);
+        Range r = getWordRangeAtCursor(connection, separators, 0);
         return (r == null) ? null : r.mWord;
     }
 
@@ -85,7 +85,17 @@
         }
     }
 
-    private static Range getWordRangeAtCursor(InputConnection connection, String sep) {
+    /**
+     * Returns the text surrounding the cursor.
+     *
+     * @param connection the InputConnection to the TextView
+     * @param sep a string of characters that split words.
+     * @param additionalPrecedingWordsCount the number of words before the current word that should
+     *   be included in the returned range
+     * @return a range containing the text surrounding the cursor
+     */
+    public static Range getWordRangeAtCursor(InputConnection connection, String sep,
+            int additionalPrecedingWordsCount) {
         if (connection == null || sep == null) {
             return null;
         }
@@ -95,14 +105,40 @@
             return null;
         }
 
-        // Find first word separator before the cursor
+        // Going backward, alternate skipping non-separators and separators until enough words
+        // have been read.
         int start = before.length();
-        while (start > 0 && !isWhitespace(before.charAt(start - 1), sep)) start--;
+        boolean isStoppingAtWhitespace = true;  // toggles to indicate what to stop at
+        while (true) { // see comments below for why this is guaranteed to halt
+            while (start > 0) {
+                final int codePoint = Character.codePointBefore(before, start);
+                if (isStoppingAtWhitespace == isSeparator(codePoint, sep)) {
+                    break;  // inner loop
+                }
+                --start;
+                if (Character.isSupplementaryCodePoint(codePoint)) {
+                    --start;
+                }
+            }
+            // isStoppingAtWhitespace is true every other time through the loop,
+            // so additionalPrecedingWordsCount is guaranteed to become < 0, which
+            // guarantees outer loop termination
+            if (isStoppingAtWhitespace && (--additionalPrecedingWordsCount < 0)) {
+                break;  // outer loop
+            }
+            isStoppingAtWhitespace = !isStoppingAtWhitespace;
+        }
 
         // Find last word separator after the cursor
         int end = -1;
-        while (++end < after.length() && !isWhitespace(after.charAt(end), sep)) {
-            // Nothing to do here.
+        while (++end < after.length()) {
+            final int codePoint = Character.codePointAt(after, end);
+            if (isSeparator(codePoint, sep)) {
+                break;
+            }
+            if (Character.isSupplementaryCodePoint(codePoint)) {
+                ++end;
+            }
         }
 
         int cursor = getCursorPosition(connection);
@@ -115,8 +151,8 @@
         return null;
     }
 
-    private static boolean isWhitespace(int code, String whitespace) {
-        return whitespace.contains(String.valueOf((char) code));
+    private static boolean isSeparator(int code, String sep) {
+        return sep.indexOf(code) != -1;
     }
 
     private static final Pattern spaceRegex = Pattern.compile("\\s+");
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index bfdc1e3..1738c57 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -393,7 +393,7 @@
         mPrefs = prefs;
         LatinImeLogger.init(this, prefs);
         if (ProductionFlag.IS_EXPERIMENTAL) {
-            ResearchLogger.init(this, prefs);
+            ResearchLogger.getInstance().init(this, prefs);
         }
         InputMethodManagerCompatWrapper.init(this);
         SubtypeSwitcher.init(this);
@@ -660,6 +660,7 @@
                     + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0));
         }
         if (ProductionFlag.IS_EXPERIMENTAL) {
+            ResearchLogger.getInstance().start();
             ResearchLogger.latinIME_onStartInputViewInternal(editorInfo, mPrefs);
         }
         if (InputAttributes.inPrivateImeOptions(null, NO_MICROPHONE_COMPAT, editorInfo)) {
@@ -739,6 +740,10 @@
 
     @Override
     public void onWindowHidden() {
+        if (ProductionFlag.IS_EXPERIMENTAL) {
+            ResearchLogger.latinIME_onWindowHidden(mLastSelectionStart, mLastSelectionEnd,
+                    getCurrentInputConnection());
+        }
         super.onWindowHidden();
         KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
         if (inputView != null) inputView.closing();
@@ -748,6 +753,9 @@
         super.onFinishInput();
 
         LatinImeLogger.commit();
+        if (ProductionFlag.IS_EXPERIMENTAL) {
+            ResearchLogger.getInstance().stop();
+        }
 
         KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
         if (inputView != null) inputView.closing();
@@ -768,7 +776,6 @@
             int composingSpanStart, int composingSpanEnd) {
         super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
                 composingSpanStart, composingSpanEnd);
-
         if (DEBUG) {
             Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart
                     + ", ose=" + oldSelEnd
@@ -780,9 +787,15 @@
                     + ", ce=" + composingSpanEnd);
         }
         if (ProductionFlag.IS_EXPERIMENTAL) {
+            final boolean expectingUpdateSelectionFromLogger =
+                    ResearchLogger.getAndClearLatinIMEExpectingUpdateSelection();
             ResearchLogger.latinIME_onUpdateSelection(mLastSelectionStart, mLastSelectionEnd,
                     oldSelStart, oldSelEnd, newSelStart, newSelEnd, composingSpanStart,
-                    composingSpanEnd);
+                    composingSpanEnd, mExpectingUpdateSelection,
+                    expectingUpdateSelectionFromLogger, getCurrentInputConnection());
+            if (expectingUpdateSelectionFromLogger) {
+                return;
+            }
         }
 
         // TODO: refactor the following code to be less contrived.
@@ -1270,9 +1283,7 @@
         mLastKeyTime = when;
 
         if (ProductionFlag.IS_EXPERIMENTAL) {
-            if (ResearchLogger.sIsLogging) {
-                ResearchLogger.getInstance().logKeyEvent(primaryCode, x, y);
-            }
+            ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
         }
 
         final KeyboardSwitcher switcher = mKeyboardSwitcher;
diff --git a/java/src/com/android/inputmethod/latin/ResearchLogger.java b/java/src/com/android/inputmethod/latin/ResearchLogger.java
index 66d6d58..1628509 100644
--- a/java/src/com/android/inputmethod/latin/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/latin/ResearchLogger.java
@@ -16,37 +16,42 @@
 
 package com.android.inputmethod.latin;
 
+import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET;
+
 import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
 import android.inputmethodservice.InputMethodService;
 import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Process;
 import android.os.SystemClock;
-import android.preference.PreferenceManager;
 import android.text.TextUtils;
+import android.util.JsonWriter;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
 
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.KeyDetector;
 import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.internal.KeyboardState;
+import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.define.ProductionFlag;
 
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileWriter;
 import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.charset.Charset;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
 import java.util.Map;
+import java.util.UUID;
 
 /**
  * Logs the use of the LatinIME keyboard.
@@ -58,373 +63,162 @@
  */
 public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
     private static final String TAG = ResearchLogger.class.getSimpleName();
-    private static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
     private static final boolean DEBUG = false;
+    /* package */ static boolean sIsLogging = false;
+    private static final int OUTPUT_FORMAT_VERSION = 1;
+    private static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
+    private static final String FILENAME_PREFIX = "researchLog";
+    private static final String FILENAME_SUFFIX = ".txt";
+    private static final JsonWriter NULL_JSON_WRITER = new JsonWriter(
+            new OutputStreamWriter(new NullOutputStream()));
+    private static final SimpleDateFormat TIMESTAMP_DATEFORMAT =
+            new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
 
-    private static final ResearchLogger sInstance = new ResearchLogger(new LogFileManager());
-    public static boolean sIsLogging = false;
-    /* package */ final Handler mLoggingHandler;
-    private InputMethodService mIms;
+    // constants related to specific log points
+    private static final String WHITESPACE_SEPARATORS = " \t\n\r";
+    private static final int MAX_INPUTVIEW_LENGTH_TO_CAPTURE = 8192; // must be >=1
+    private static final String PREF_RESEARCH_LOGGER_UUID_STRING = "pref_research_logger_uuid";
 
-    /**
-     * Isolates management of files. This variable should never be null, but can be changed
-     * to support testing.
-     */
-    /* package */ LogFileManager mLogFileManager;
+    private static final ResearchLogger sInstance = new ResearchLogger();
+    private HandlerThread mHandlerThread;
+    /* package */ Handler mLoggingHandler;
+    // to write to a different filename, e.g., for testing, set mFile before calling start()
+    private File mFilesDir;
+    /* package */ File mFile;
+    private JsonWriter mJsonWriter = NULL_JSON_WRITER; // should never be null
 
-    /**
-     * Manages the file(s) that stores the logs.
-     *
-     * Handles creation, deletion, and provides Readers, Writers, and InputStreams to access
-     * the logs.
-     */
-    /* package */ static class LogFileManager {
-        public static final String RESEARCH_LOG_FILENAME_KEY = "RESEARCH_LOG_FILENAME";
+    private int mLoggingState;
+    private static final int LOGGING_STATE_OFF = 0;
+    private static final int LOGGING_STATE_ON = 1;
+    private static final int LOGGING_STATE_STOPPING = 2;
 
-        private static final String DEFAULT_FILENAME = "researchLog.txt";
-        private static final long LOGFILE_PURGE_INTERVAL = 1000 * 60 * 60 * 24;
+    // set when LatinIME should ignore an onUpdateSelection() callback that
+    // arises from operations in this class
+    private static boolean sLatinIMEExpectingUpdateSelection = false;
 
-        protected InputMethodService mIms;
-        protected File mFile;
-        protected PrintWriter mPrintWriter;
-
-        /* package */ LogFileManager() {
+    private static class NullOutputStream extends OutputStream {
+        /** {@inheritDoc} */
+        @Override
+        public void write(byte[] buffer, int offset, int count) throws IOException {
+            // nop
         }
 
-        public void init(final InputMethodService ims) {
-            mIms = ims;
+        /** {@inheritDoc} */
+        @Override
+        public void write(byte[] buffer) throws IOException {
+            // nop
         }
 
-        public synchronized void createLogFile() throws IOException {
-            createLogFile(DEFAULT_FILENAME);
-        }
-
-        public synchronized void createLogFile(final SharedPreferences prefs)
-                throws IOException {
-            final String filename =
-                    prefs.getString(RESEARCH_LOG_FILENAME_KEY, DEFAULT_FILENAME);
-            createLogFile(filename);
-        }
-
-        public synchronized void createLogFile(final String filename)
-                throws IOException {
-            if (mIms == null) {
-                final String msg = "InputMethodService is not configured.  Logging is off.";
-                Log.w(TAG, msg);
-                throw new IOException(msg);
-            }
-            final File filesDir = mIms.getFilesDir();
-            if (filesDir == null || !filesDir.exists()) {
-                final String msg = "Storage directory does not exist.  Logging is off.";
-                Log.w(TAG, msg);
-                throw new IOException(msg);
-            }
-            close();
-            final File file = new File(filesDir, filename);
-            mFile = file;
-            boolean append = true;
-            if (file.exists() && file.lastModified() + LOGFILE_PURGE_INTERVAL <
-                    System.currentTimeMillis()) {
-                append = false;
-            }
-            mPrintWriter = new PrintWriter(new BufferedWriter(new FileWriter(file, append)), true);
-        }
-
-        public synchronized boolean append(final String s) {
-            PrintWriter printWriter = mPrintWriter;
-            if (printWriter == null || !mFile.exists()) {
-                if (DEBUG) {
-                    Log.w(TAG, "PrintWriter is null... attempting to create default log file");
-                }
-                try {
-                    createLogFile();
-                    printWriter = mPrintWriter;
-                } catch (IOException e) {
-                    Log.w(TAG, "Failed to create log file.  Not logging.");
-                    return false;
-                }
-            }
-            printWriter.print(s);
-            printWriter.flush();
-            return !printWriter.checkError();
-        }
-
-        public synchronized void reset() {
-            if (mPrintWriter != null) {
-                mPrintWriter.close();
-                mPrintWriter = null;
-                if (DEBUG) {
-                    Log.d(TAG, "logfile closed");
-                }
-            }
-            if (mFile != null) {
-                mFile.delete();
-                if (DEBUG) {
-                    Log.d(TAG, "logfile deleted");
-                }
-                mFile = null;
-            }
-        }
-
-        public synchronized void close() {
-            if (mPrintWriter != null) {
-                mPrintWriter.close();
-                mPrintWriter = null;
-                mFile = null;
-                if (DEBUG) {
-                    Log.d(TAG, "logfile closed");
-                }
-            }
-        }
-
-        /* package */ synchronized void flush() {
-            if (mPrintWriter != null) {
-                mPrintWriter.flush();
-            }
-        }
-
-        /* package */ synchronized String getContents() {
-            final File file = mFile;
-            if (file == null) {
-                return "";
-            }
-            if (mPrintWriter != null) {
-                mPrintWriter.flush();
-            }
-            FileInputStream stream = null;
-            FileChannel fileChannel = null;
-            String s = "";
-            try {
-                stream = new FileInputStream(file);
-                fileChannel = stream.getChannel();
-                final ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());
-                fileChannel.read(byteBuffer);
-                byteBuffer.rewind();
-                CharBuffer charBuffer = Charset.defaultCharset().decode(byteBuffer);
-                s = charBuffer.toString();
-            } catch (IOException e) {
-                e.printStackTrace();
-            } finally {
-                try {
-                    if (fileChannel != null) {
-                        fileChannel.close();
-                    }
-                } catch (IOException e) {
-                    e.printStackTrace();
-                } finally {
-                    try {
-                        if (stream != null) {
-                            stream.close();
-                        }
-                    } catch (IOException e) {
-                        e.printStackTrace();
-                    }
-                }
-            }
-            return s;
+        @Override
+        public void write(int oneByte) {
         }
     }
 
-    private ResearchLogger(final LogFileManager logFileManager) {
-        final HandlerThread handlerThread = new HandlerThread("ResearchLogger logging task",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        handlerThread.start();
-        mLoggingHandler = new Handler(handlerThread.getLooper());
-        mLogFileManager = logFileManager;
+    private ResearchLogger() {
+        mLoggingState = LOGGING_STATE_OFF;
     }
 
     public static ResearchLogger getInstance() {
         return sInstance;
     }
 
-    public static void init(final InputMethodService ims, final SharedPreferences prefs) {
-        sInstance.initInternal(ims, prefs);
-    }
-
-    /* package */ void initInternal(final InputMethodService ims, final SharedPreferences prefs) {
-        mIms = ims;
-        final LogFileManager logFileManager = mLogFileManager;
-        if (logFileManager != null) {
-            logFileManager.init(ims);
-            try {
-                logFileManager.createLogFile(prefs);
-            } catch (IOException e) {
-                e.printStackTrace();
+    public void init(final InputMethodService ims, final SharedPreferences prefs) {
+        assert ims != null;
+        if (ims == null) {
+            Log.w(TAG, "IMS is null; logging is off");
+        } else {
+            mFilesDir = ims.getFilesDir();
+            if (mFilesDir == null || !mFilesDir.exists()) {
+                Log.w(TAG, "IME storage directory does not exist.");
             }
         }
         if (prefs != null) {
             sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false);
-            prefs.registerOnSharedPreferenceChangeListener(this);
+            prefs.registerOnSharedPreferenceChangeListener(sInstance);
         }
     }
 
-    /**
-     * Represents a category of logging events that share the same subfield structure.
-     */
-    private static enum LogGroup {
-        MOTION_EVENT("m"),
-        KEY("k"),
-        CORRECTION("c"),
-        STATE_CHANGE("s"),
-        UNSTRUCTURED("u");
-
-        private final String mLogString;
-
-        private LogGroup(final String logString) {
-            mLogString = logString;
-        }
-    }
-
-    public void logMotionEvent(final int action, final long eventTime, final int id,
-            final int x, final int y, final float size, final float pressure) {
-        final String eventTag;
-        switch (action) {
-            case MotionEvent.ACTION_CANCEL: eventTag = "[Cancel]"; break;
-            case MotionEvent.ACTION_UP: eventTag = "[Up]"; break;
-            case MotionEvent.ACTION_DOWN: eventTag = "[Down]"; break;
-            case MotionEvent.ACTION_POINTER_UP: eventTag = "[PointerUp]"; break;
-            case MotionEvent.ACTION_POINTER_DOWN: eventTag = "[PointerDown]"; break;
-            case MotionEvent.ACTION_MOVE: eventTag = "[Move]"; break;
-            case MotionEvent.ACTION_OUTSIDE: eventTag = "[Outside]"; break;
-            default: eventTag = "[Action" + action + "]"; break;
-        }
-        if (!TextUtils.isEmpty(eventTag)) {
-            final StringBuilder sb = new StringBuilder();
-            sb.append(eventTag);
-            sb.append('\t'); sb.append(eventTime);
-            sb.append('\t'); sb.append(id);
-            sb.append('\t'); sb.append(x);
-            sb.append('\t'); sb.append(y);
-            sb.append('\t'); sb.append(size);
-            sb.append('\t'); sb.append(pressure);
-            write(LogGroup.MOTION_EVENT, sb.toString());
-        }
-    }
-
-    public void logKeyEvent(final int code, final int x, final int y) {
-        final StringBuilder sb = new StringBuilder();
-        sb.append(Keyboard.printableCode(code));
-        sb.append('\t'); sb.append(x);
-        sb.append('\t'); sb.append(y);
-        write(LogGroup.KEY, sb.toString());
-    }
-
-    public void logCorrection(final String subgroup, final String before, final String after,
-            final int position) {
-        final StringBuilder sb = new StringBuilder();
-        sb.append(subgroup);
-        sb.append('\t'); sb.append(before);
-        sb.append('\t'); sb.append(after);
-        sb.append('\t'); sb.append(position);
-        write(LogGroup.CORRECTION, sb.toString());
-    }
-
-    public void logStateChange(final String subgroup, final String details) {
-        write(LogGroup.STATE_CHANGE, subgroup + "\t" + details);
-    }
-
-    public static class UnsLogGroup {
-        private static final boolean DEFAULT_ENABLED = true;
-
-        private static final boolean KEYBOARDSTATE_ONCANCELINPUT_ENABLED = DEFAULT_ENABLED;
-        private static final boolean KEYBOARDSTATE_ONCODEINPUT_ENABLED = DEFAULT_ENABLED;
-        private static final boolean KEYBOARDSTATE_ONLONGPRESSTIMEOUT_ENABLED = DEFAULT_ENABLED;
-        private static final boolean KEYBOARDSTATE_ONPRESSKEY_ENABLED = DEFAULT_ENABLED;
-        private static final boolean KEYBOARDSTATE_ONRELEASEKEY_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_COMMITCURRENTAUTOCORRECTION_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_COMMITTEXT_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_DELETESURROUNDINGTEXT_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_DOUBLESPACEAUTOPERIOD_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_ONDISPLAYCOMPLETIONS_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_ONSTARTINPUTVIEWINTERNAL_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_ONUPDATESELECTION_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_PERFORMEDITORACTION_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION_ENABLED
-                = DEFAULT_ENABLED;
-        private static final boolean LATINIME_PICKPUNCTUATIONSUGGESTION_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_PICKSUGGESTIONMANUALLY_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_REVERTCOMMIT_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT_ENABLED
-                = DEFAULT_ENABLED;
-        private static final boolean LATINIME_REVERTSWAPPUNCTUATION_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_SENDKEYCODEPOINT_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT_ENABLED
-                = DEFAULT_ENABLED;
-        private static final boolean LATINIME_SWITCHTOKEYBOARDVIEW_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINKEYBOARDVIEW_ONLONGPRESS_ENABLED = DEFAULT_ENABLED;
-        private static final boolean LATINKEYBOARDVIEW_ONPROCESSMOTIONEVENT_ENABLED
-                = DEFAULT_ENABLED;
-        private static final boolean LATINKEYBOARDVIEW_SETKEYBOARD_ENABLED = DEFAULT_ENABLED;
-        private static final boolean POINTERTRACKER_CALLLISTENERONCANCELINPUT_ENABLED
-                = DEFAULT_ENABLED;
-        private static final boolean POINTERTRACKER_CALLLISTENERONCODEINPUT_ENABLED
-                = DEFAULT_ENABLED;
-        private static final boolean
-                POINTERTRACKER_CALLLISTENERONPRESSANDCHECKKEYBOARDLAYOUTCHANGE_ENABLED
-                = DEFAULT_ENABLED;
-        private static final boolean POINTERTRACKER_CALLLISTENERONRELEASE_ENABLED = DEFAULT_ENABLED;
-        private static final boolean POINTERTRACKER_ONDOWNEVENT_ENABLED = DEFAULT_ENABLED;
-        private static final boolean POINTERTRACKER_ONMOVEEVENT_ENABLED = DEFAULT_ENABLED;
-        private static final boolean SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT_ENABLED
-                = DEFAULT_ENABLED;
-        private static final boolean SUGGESTIONSVIEW_SETSUGGESTIONS_ENABLED = DEFAULT_ENABLED;
-    }
-
-    public static void logUnstructured(String logGroup, final String details) {
-        // TODO: improve performance by making entire class static and/or implementing natively
-        getInstance().write(LogGroup.UNSTRUCTURED, logGroup + "\t" + details);
-    }
-
-    private void write(final LogGroup logGroup, final String log) {
-        // TODO: rewrite in native for better performance
-        mLoggingHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                final long currentTime = System.currentTimeMillis();
-                final long upTime = SystemClock.uptimeMillis();
-                final StringBuilder builder = new StringBuilder();
-                builder.append(currentTime);
-                builder.append('\t'); builder.append(upTime);
-                builder.append('\t'); builder.append(logGroup.mLogString);
-                builder.append('\t'); builder.append(log);
-                builder.append('\n');
-                if (DEBUG) {
-                    Log.d(TAG, "Write: " + '[' + logGroup.mLogString + ']' + log);
+    public synchronized void start() {
+        Log.d(TAG, "start called");
+        if (mFilesDir == null || !mFilesDir.exists()) {
+            Log.w(TAG, "IME storage directory does not exist.  Cannot start logging.");
+        } else {
+            if (mHandlerThread == null || !mHandlerThread.isAlive()) {
+                mHandlerThread = new HandlerThread("ResearchLogger logging task",
+                        Process.THREAD_PRIORITY_BACKGROUND);
+                mHandlerThread.start();
+                mLoggingHandler = null;
+                mLoggingState = LOGGING_STATE_OFF;
+            }
+            if (mLoggingHandler == null) {
+                mLoggingHandler = new Handler(mHandlerThread.getLooper());
+                mLoggingState = LOGGING_STATE_OFF;
+            }
+            if (mFile == null) {
+                final String timestampString = TIMESTAMP_DATEFORMAT.format(new Date());
+                mFile = new File(mFilesDir, FILENAME_PREFIX + timestampString + FILENAME_SUFFIX);
+            }
+            if (mLoggingState == LOGGING_STATE_OFF) {
+                try {
+                    mJsonWriter = new JsonWriter(new BufferedWriter(new FileWriter(mFile)));
+                    mJsonWriter.setLenient(true);
+                    mJsonWriter.beginArray();
+                    mLoggingState = LOGGING_STATE_ON;
+                } catch (IOException e) {
+                    Log.w(TAG, "cannot start JsonWriter");
+                    mJsonWriter = NULL_JSON_WRITER;
+                    e.printStackTrace();
                 }
-                final String s = builder.toString();
-                if (mLogFileManager.append(s)) {
-                    // success
-                } else {
-                    if (DEBUG) {
-                        Log.w(TAG, "Unable to write to log.");
-                    }
-                    // perhaps logfile was deleted.  try to recreate and relog.
+            }
+        }
+    }
+
+    public synchronized void stop() {
+        Log.d(TAG, "stop called");
+        if (mLoggingHandler != null && mLoggingState == LOGGING_STATE_ON) {
+            mLoggingState = LOGGING_STATE_STOPPING;
+            // put this in the Handler queue so pending writes are processed first.
+            mLoggingHandler.post(new Runnable() {
+                @Override
+                public void run() {
                     try {
-                        mLogFileManager.createLogFile(PreferenceManager
-                                .getDefaultSharedPreferences(mIms));
-                        mLogFileManager.append(s);
+                        Log.d(TAG, "closing jsonwriter");
+                        mJsonWriter.endArray();
+                        mJsonWriter.flush();
+                        mJsonWriter.close();
+                    } catch (IllegalStateException e1) {
+                        // assume that this is just the json not being terminated properly.
+                        // ignore
+                        e1.printStackTrace();
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
+                    mJsonWriter = NULL_JSON_WRITER;
+                    mFile = null;
+                    mLoggingState = LOGGING_STATE_OFF;
+                    if (DEBUG) {
+                        Log.d(TAG, "logfile closed");
+                    }
+                    Log.d(TAG, "finished stop(), notifying");
+                    synchronized (ResearchLogger.this) {
+                        ResearchLogger.this.notify();
+                    }
                 }
+            });
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
             }
-        });
+        }
     }
 
-    public void clearAll() {
-        mLoggingHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                if (DEBUG) {
-                    Log.d(TAG, "Delete log file.");
-                }
-                mLogFileManager.reset();
-            }
-        });
-    }
-
-    /* package */ LogFileManager getLogFileManager() {
-        return mLogFileManager;
+    /* package */ synchronized void flush() {
+        try {
+            mJsonWriter.flush();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
     }
 
     @Override
@@ -435,323 +229,531 @@
         sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false);
     }
 
-    public static void keyboardState_onCancelInput(final boolean isSinglePointer,
-            final KeyboardState keyboardState) {
-        if (UnsLogGroup.KEYBOARDSTATE_ONCANCELINPUT_ENABLED) {
-            final String s = "onCancelInput: single=" + isSinglePointer + " " + keyboardState;
-            logUnstructured("KeyboardState_onCancelInput", s);
+    private static final String CURRENT_TIME_KEY = "_ct";
+    private static final String UPTIME_KEY = "_ut";
+    private static final String EVENT_TYPE_KEY = "_ty";
+    private static final Object[] EVENTKEYS_NULLVALUES = {};
+
+    /**
+     * Write a description of the event out to the ResearchLog.
+     *
+     * Runs in the background to avoid blocking the UI thread.
+     *
+     * @param keys an array containing a descriptive name for the event, followed by the keys
+     * @param values an array of values, either a String or Number.  length should be one
+     * less than the keys array
+     */
+    private synchronized void writeEvent(final String[] keys, final Object[] values) {
+        assert values.length + 1 == keys.length;
+        if (mLoggingState == LOGGING_STATE_ON) {
+            mLoggingHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        mJsonWriter.beginObject();
+                        mJsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis());
+                        mJsonWriter.name(UPTIME_KEY).value(SystemClock.uptimeMillis());
+                        mJsonWriter.name(EVENT_TYPE_KEY).value(keys[0]);
+                        final int length = values.length;
+                        for (int i = 0; i < length; i++) {
+                            mJsonWriter.name(keys[i + 1]);
+                            Object value = values[i];
+                            if (value instanceof String) {
+                                mJsonWriter.value((String) value);
+                            } else if (value instanceof Number) {
+                                mJsonWriter.value((Number) value);
+                            } else if (value instanceof Boolean) {
+                                mJsonWriter.value((Boolean) value);
+                            } else if (value instanceof CompletionInfo[]) {
+                                CompletionInfo[] ci = (CompletionInfo[]) value;
+                                mJsonWriter.beginArray();
+                                for (int j = 0; j < ci.length; j++) {
+                                    mJsonWriter.value(ci[j].toString());
+                                }
+                                mJsonWriter.endArray();
+                            } else if (value instanceof SharedPreferences) {
+                                SharedPreferences prefs = (SharedPreferences) value;
+                                mJsonWriter.beginObject();
+                                for (Map.Entry<String,?> entry : prefs.getAll().entrySet()) {
+                                    mJsonWriter.name(entry.getKey());
+                                    final Object innerValue = entry.getValue();
+                                    if (innerValue == null) {
+                                        mJsonWriter.nullValue();
+                                    } else if (innerValue instanceof Boolean) {
+                                        mJsonWriter.value((Boolean) innerValue);
+                                    } else if (innerValue instanceof Number) {
+                                        mJsonWriter.value((Number) innerValue);
+                                    } else {
+                                        mJsonWriter.value(innerValue.toString());
+                                    }
+                                }
+                                mJsonWriter.endObject();
+                            } else if (value instanceof Key[]) {
+                                Key[] keys = (Key[]) value;
+                                mJsonWriter.beginArray();
+                                for (Key key : keys) {
+                                    mJsonWriter.beginObject();
+                                    mJsonWriter.name("code").value(key.mCode);
+                                    mJsonWriter.name("altCode").value(key.mAltCode);
+                                    mJsonWriter.name("x").value(key.mX);
+                                    mJsonWriter.name("y").value(key.mY);
+                                    mJsonWriter.name("w").value(key.mWidth);
+                                    mJsonWriter.name("h").value(key.mHeight);
+                                    mJsonWriter.endObject();
+                                }
+                                mJsonWriter.endArray();
+                            } else if (value instanceof SuggestedWords) {
+                                SuggestedWords words = (SuggestedWords) value;
+                                mJsonWriter.beginObject();
+                                mJsonWriter.name("typedWordValid").value(words.mTypedWordValid);
+                                mJsonWriter.name("hasAutoCorrectionCandidate")
+                                    .value(words.mHasAutoCorrectionCandidate);
+                                mJsonWriter.name("isPunctuationSuggestions")
+                                    .value(words.mIsPunctuationSuggestions);
+                                mJsonWriter.name("allowsToBeAutoCorrected")
+                                    .value(words.mAllowsToBeAutoCorrected);
+                                mJsonWriter.name("isObsoleteSuggestions")
+                                    .value(words.mIsObsoleteSuggestions);
+                                mJsonWriter.name("isPrediction")
+                                    .value(words.mIsPrediction);
+                                mJsonWriter.name("words");
+                                mJsonWriter.beginArray();
+                                final int size = words.size();
+                                for (int j = 0; j < size; j++) {
+                                    SuggestedWordInfo wordInfo = words.getWordInfo(j);
+                                    mJsonWriter.value(wordInfo.toString());
+                                }
+                                mJsonWriter.endArray();
+                                mJsonWriter.endObject();
+                            } else if (value == null) {
+                                mJsonWriter.nullValue();
+                            } else {
+                                Log.w(TAG, "Unrecognized type to be logged: " +
+                                        (value == null ? "<null>" : value.getClass().getName()));
+                                mJsonWriter.nullValue();
+                            }
+                        }
+                        mJsonWriter.endObject();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                        Log.w(TAG, "Error in JsonWriter; disabling logging");
+                        try {
+                            mJsonWriter.close();
+                        } catch (IllegalStateException e1) {
+                            // assume that this is just the json not being terminated properly.
+                            // ignore
+                        } catch (IOException e1) {
+                            e1.printStackTrace();
+                        } finally {
+                            mJsonWriter = NULL_JSON_WRITER;
+                        }
+                    }
+                }
+            });
         }
     }
 
-    public static void keyboardState_onCodeInput(
-            final int code, final boolean isSinglePointer, final int autoCaps,
-            final KeyboardState keyboardState) {
-        if (UnsLogGroup.KEYBOARDSTATE_ONCODEINPUT_ENABLED) {
-            final String s = "onCodeInput: code=" + Keyboard.printableCode(code)
-                    + " single=" + isSinglePointer
-                    + " autoCaps=" + autoCaps + " " + keyboardState;
-            logUnstructured("KeyboardState_onCodeInput", s);
+    private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_PROCESSMOTIONEVENT = {
+        "LatinKeyboardViewProcessMotionEvent", "action", "eventTime", "id", "x", "y", "size",
+        "pressure"
+    };
+    public static void latinKeyboardView_processMotionEvent(final MotionEvent me, final int action,
+            final long eventTime, final int index, final int id, final int x, final int y) {
+        if (me != null) {
+            final String actionString;
+            switch (action) {
+                case MotionEvent.ACTION_CANCEL: actionString = "CANCEL"; break;
+                case MotionEvent.ACTION_UP: actionString = "UP"; break;
+                case MotionEvent.ACTION_DOWN: actionString = "DOWN"; break;
+                case MotionEvent.ACTION_POINTER_UP: actionString = "POINTER_UP"; break;
+                case MotionEvent.ACTION_POINTER_DOWN: actionString = "POINTER_DOWN"; break;
+                case MotionEvent.ACTION_MOVE: actionString = "MOVE"; break;
+                case MotionEvent.ACTION_OUTSIDE: actionString = "OUTSIDE"; break;
+                default: actionString = "ACTION_" + action; break;
+            }
+            final float size = me.getSize(index);
+            final float pressure = me.getPressure(index);
+            final Object[] values = {
+                actionString, eventTime, id, x, y, size, pressure
+            };
+            getInstance().writeEvent(EVENTKEYS_LATINKEYBOARDVIEW_PROCESSMOTIONEVENT, values);
         }
     }
 
-    public static void keyboardState_onLongPressTimeout(final int code,
-            final KeyboardState keyboardState) {
-        if (UnsLogGroup.KEYBOARDSTATE_ONLONGPRESSTIMEOUT_ENABLED) {
-            final String s = "onLongPressTimeout: code=" + Keyboard.printableCode(code) + " "
-                    + keyboardState;
-            logUnstructured("KeyboardState_onLongPressTimeout", s);
-        }
+    private static final String[] EVENTKEYS_LATINIME_ONCODEINPUT = {
+        "LatinIMEOnCodeInput", "code", "x", "y"
+    };
+    public static void latinIME_onCodeInput(final int code, final int x, final int y) {
+        final Object[] values = {
+            Keyboard.printableCode(code), x, y
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values);
     }
 
-    public static void keyboardState_onPressKey(final int code,
-            final KeyboardState keyboardState) {
-        if (UnsLogGroup.KEYBOARDSTATE_ONPRESSKEY_ENABLED) {
-            final String s = "onPressKey: code=" + Keyboard.printableCode(code) + " "
-                    + keyboardState;
-            logUnstructured("KeyboardState_onPressKey", s);
-        }
+    private static final String[] EVENTKEYS_CORRECTION = {
+        "LogCorrection", "subgroup", "before", "after", "position"
+    };
+    public static void logCorrection(final String subgroup, final String before, final String after,
+            final int position) {
+        final Object[] values = {
+            subgroup, before, after, position
+        };
+        getInstance().writeEvent(EVENTKEYS_CORRECTION, values);
     }
 
-    public static void keyboardState_onReleaseKey(final KeyboardState keyboardState, final int code,
-            final boolean withSliding) {
-        if (UnsLogGroup.KEYBOARDSTATE_ONRELEASEKEY_ENABLED) {
-            final String s = "onReleaseKey: code=" + Keyboard.printableCode(code)
-                    + " sliding=" + withSliding + " " + keyboardState;
-            logUnstructured("KeyboardState_onReleaseKey", s);
-        }
-    }
-
+    private static final String[] EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION = {
+        "LatinIMECommitCurrentAutoCorrection", "typedWord", "autoCorrection"
+    };
     public static void latinIME_commitCurrentAutoCorrection(final String typedWord,
             final String autoCorrection) {
-        if (UnsLogGroup.LATINIME_COMMITCURRENTAUTOCORRECTION_ENABLED) {
-            if (typedWord.equals(autoCorrection)) {
-                getInstance().logCorrection("[----]", typedWord, autoCorrection, -1);
-            } else {
-                getInstance().logCorrection("[Auto]", typedWord, autoCorrection, -1);
-            }
-        }
+        final Object[] values = {
+            typedWord, autoCorrection
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = {
+        "LatinIMECommitText", "typedWord"
+    };
     public static void latinIME_commitText(final CharSequence typedWord) {
-        if (UnsLogGroup.LATINIME_COMMITTEXT_ENABLED) {
-            logUnstructured("LatinIME_commitText", typedWord.toString());
-        }
+        final Object[] values = {
+            typedWord.toString()
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_COMMITTEXT, values);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = {
+        "LatinIMEDeleteSurroundingText", "length"
+    };
     public static void latinIME_deleteSurroundingText(final int length) {
-        if (UnsLogGroup.LATINIME_DELETESURROUNDINGTEXT_ENABLED) {
-            logUnstructured("LatinIME_deleteSurroundingText", String.valueOf(length));
-        }
+        final Object[] values = {
+            length
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT, values);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD = {
+        "LatinIMEDoubleSpaceAutoPeriod"
+    };
     public static void latinIME_doubleSpaceAutoPeriod() {
-        if (UnsLogGroup.LATINIME_DOUBLESPACEAUTOPERIOD_ENABLED) {
-            logUnstructured("LatinIME_doubleSpaceAutoPeriod", "");
-        }
+        getInstance().writeEvent(EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD, EVENTKEYS_NULLVALUES);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS = {
+        "LatinIMEOnDisplayCompletions", "applicationSpecifiedCompletions"
+    };
     public static void latinIME_onDisplayCompletions(
             final CompletionInfo[] applicationSpecifiedCompletions) {
-        if (UnsLogGroup.LATINIME_ONDISPLAYCOMPLETIONS_ENABLED) {
-            final StringBuilder builder = new StringBuilder();
-            builder.append("Received completions:");
-            if (applicationSpecifiedCompletions != null) {
-                for (int i = 0; i < applicationSpecifiedCompletions.length; i++) {
-                    builder.append("  #");
-                    builder.append(i);
-                    builder.append(": ");
-                    builder.append(applicationSpecifiedCompletions[i]);
-                    builder.append("\n");
+        final Object[] values = {
+            applicationSpecifiedCompletions
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS, values);
+    }
+
+    /* package */ static boolean getAndClearLatinIMEExpectingUpdateSelection() {
+        boolean returnValue = sLatinIMEExpectingUpdateSelection;
+        sLatinIMEExpectingUpdateSelection = false;
+        return returnValue;
+    }
+
+    private static final String[] EVENTKEYS_LATINIME_ONWINDOWHIDDEN = {
+        "LatinIMEOnWindowHidden", "isTextTruncated", "text"
+    };
+    public static void latinIME_onWindowHidden(final int savedSelectionStart,
+            final int savedSelectionEnd, final InputConnection ic) {
+        if (ic != null) {
+            ic.beginBatchEdit();
+            ic.performContextMenuAction(android.R.id.selectAll);
+            CharSequence charSequence = ic.getSelectedText(0);
+            ic.setSelection(savedSelectionStart, savedSelectionEnd);
+            ic.endBatchEdit();
+            sLatinIMEExpectingUpdateSelection = true;
+            Object[] values = new Object[2];
+            if (TextUtils.isEmpty(charSequence)) {
+                values[0] = false;
+                values[1] = "";
+            } else {
+                if (charSequence.length() > MAX_INPUTVIEW_LENGTH_TO_CAPTURE) {
+                    int length = MAX_INPUTVIEW_LENGTH_TO_CAPTURE;
+                    // do not cut in the middle of a supplementary character
+                    final char c = charSequence.charAt(length - 1);
+                    if (Character.isHighSurrogate(c)) {
+                        length--;
+                    }
+                    final CharSequence truncatedCharSequence = charSequence.subSequence(0, length);
+                    values[0] = true;
+                    values[1] = truncatedCharSequence.toString();
+                } else {
+                    values[0] = false;
+                    values[1] = charSequence.toString();
                 }
             }
-            logUnstructured("LatinIME_onDisplayCompletions", builder.toString());
+            getInstance().writeEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values);
         }
     }
 
+    private static final String[] EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL = {
+        "LatinIMEOnStartInputViewInternal", "uuid", "packageName", "inputType", "imeOptions",
+        "fieldId", "display", "model", "prefs", "outputFormatVersion"
+    };
     public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo,
             final SharedPreferences prefs) {
-        if (UnsLogGroup.LATINIME_ONSTARTINPUTVIEWINTERNAL_ENABLED) {
-            final StringBuilder builder = new StringBuilder();
-            builder.append("onStartInputView: editorInfo:");
-            builder.append("\tinputType=");
-            builder.append(Integer.toHexString(editorInfo.inputType));
-            builder.append("\timeOptions=");
-            builder.append(Integer.toHexString(editorInfo.imeOptions));
-            builder.append("\tdisplay="); builder.append(Build.DISPLAY);
-            builder.append("\tmodel="); builder.append(Build.MODEL);
-            for (Map.Entry<String,?> entry : prefs.getAll().entrySet()) {
-                builder.append("\t" + entry.getKey());
-                Object value = entry.getValue();
-                builder.append("=" + ((value == null) ? "<null>" : value.toString()));
-            }
-            logUnstructured("LatinIME_onStartInputViewInternal", builder.toString());
+        if (editorInfo != null) {
+            final Object[] values = {
+                getUUID(prefs), editorInfo.packageName, Integer.toHexString(editorInfo.inputType),
+                Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId, Build.DISPLAY,
+                Build.MODEL, prefs, OUTPUT_FORMAT_VERSION
+            };
+            getInstance().writeEvent(EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL, values);
         }
     }
 
+    private static String getUUID(final SharedPreferences prefs) {
+        String uuidString = prefs.getString(PREF_RESEARCH_LOGGER_UUID_STRING, null);
+        if (null == uuidString) {
+            UUID uuid = UUID.randomUUID();
+            uuidString = uuid.toString();
+            Editor editor = prefs.edit();
+            editor.putString(PREF_RESEARCH_LOGGER_UUID_STRING, uuidString);
+            editor.apply();
+        }
+        return uuidString;
+    }
+
+    private static final String[] EVENTKEYS_LATINIME_ONUPDATESELECTION = {
+        "LatinIMEOnUpdateSelection", "lastSelectionStart", "lastSelectionEnd", "oldSelStart",
+        "oldSelEnd", "newSelStart", "newSelEnd", "composingSpanStart", "composingSpanEnd",
+        "expectingUpdateSelection", "expectingUpdateSelectionFromLogger", "context"
+    };
     public static void latinIME_onUpdateSelection(final int lastSelectionStart,
             final int lastSelectionEnd, final int oldSelStart, final int oldSelEnd,
             final int newSelStart, final int newSelEnd, final int composingSpanStart,
-            final int composingSpanEnd) {
-        if (UnsLogGroup.LATINIME_ONUPDATESELECTION_ENABLED) {
-            final String s = "onUpdateSelection: oss=" + oldSelStart
-                    + ", ose=" + oldSelEnd
-                    + ", lss=" + lastSelectionStart
-                    + ", lse=" + lastSelectionEnd
-                    + ", nss=" + newSelStart
-                    + ", nse=" + newSelEnd
-                    + ", cs=" + composingSpanStart
-                    + ", ce=" + composingSpanEnd;
-            logUnstructured("LatinIME_onUpdateSelection", s);
-        }
+            final int composingSpanEnd, final boolean expectingUpdateSelection,
+            final boolean expectingUpdateSelectionFromLogger, final InputConnection connection) {
+        final Object[] values = {
+            lastSelectionStart, lastSelectionEnd, oldSelStart, oldSelEnd, newSelStart,
+            newSelEnd, composingSpanStart, composingSpanEnd, expectingUpdateSelection,
+            expectingUpdateSelectionFromLogger,
+            EditingUtils.getWordRangeAtCursor(connection, WHITESPACE_SEPARATORS, 1).mWord
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_ONUPDATESELECTION, values);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_PERFORMEDITORACTION = {
+        "LatinIMEPerformEditorAction", "imeActionNext"
+    };
     public static void latinIME_performEditorAction(final int imeActionNext) {
-        if (UnsLogGroup.LATINIME_PERFORMEDITORACTION_ENABLED) {
-            logUnstructured("LatinIME_performEditorAction", String.valueOf(imeActionNext));
-        }
+        final Object[] values = {
+            imeActionNext
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_PERFORMEDITORACTION, values);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION = {
+        "LatinIMEPickApplicationSpecifiedCompletion", "index", "text", "x", "y"
+    };
     public static void latinIME_pickApplicationSpecifiedCompletion(final int index,
             final CharSequence text, int x, int y) {
-        if (UnsLogGroup.LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION_ENABLED) {
-            final String s = String.valueOf(index) + '\t' + text + '\t' + x + '\t' + y;
-            logUnstructured("LatinIME_pickApplicationSpecifiedCompletion", s);
-        }
+        final Object[] values = {
+            index, text.toString(), x, y
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = {
+        "LatinIMEPickSuggestionManually", "replacedWord", "index", "suggestion", "x", "y"
+    };
     public static void latinIME_pickSuggestionManually(final String replacedWord,
             final int index, CharSequence suggestion, int x, int y) {
-        if (UnsLogGroup.LATINIME_PICKSUGGESTIONMANUALLY_ENABLED) {
-            final String s = String.valueOf(index) + '\t' + suggestion + '\t' + x + '\t' + y;
-            logUnstructured("LatinIME_pickSuggestionManually", s);
-        }
+        final Object[] values = {
+            replacedWord, index, suggestion.toString(), x, y
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY, values);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = {
+        "LatinIMEPunctuationSuggestion", "index", "suggestion", "x", "y"
+    };
     public static void latinIME_punctuationSuggestion(final int index,
             final CharSequence suggestion, int x, int y) {
-        if (UnsLogGroup.LATINIME_PICKPUNCTUATIONSUGGESTION_ENABLED) {
-            final String s = String.valueOf(index) + '\t' + suggestion + '\t' + x + '\t' + y;
-            logUnstructured("LatinIME_pickPunctuationSuggestion", s);
-        }
+        final Object[] values = {
+            index, suggestion.toString(), x, y
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION, values);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT = {
+        "LatinIMERevertDoubleSpaceWhileInBatchEdit"
+    };
     public static void latinIME_revertDoubleSpaceWhileInBatchEdit() {
-        if (UnsLogGroup.LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT_ENABLED) {
-            logUnstructured("LatinIME_revertDoubleSpaceWhileInBatchEdit", "");
-        }
+        getInstance().writeEvent(EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT,
+                EVENTKEYS_NULLVALUES);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION = {
+        "LatinIMERevertSwapPunctuation"
+    };
     public static void latinIME_revertSwapPunctuation() {
-        if (UnsLogGroup.LATINIME_REVERTSWAPPUNCTUATION_ENABLED) {
-            logUnstructured("LatinIME_revertSwapPunctuation", "");
-        }
+        getInstance().writeEvent(EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION, EVENTKEYS_NULLVALUES);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_SENDKEYCODEPOINT = {
+        "LatinIMESendKeyCodePoint", "code"
+    };
     public static void latinIME_sendKeyCodePoint(final int code) {
-        if (UnsLogGroup.LATINIME_SENDKEYCODEPOINT_ENABLED) {
-            logUnstructured("LatinIME_sendKeyCodePoint", String.valueOf(code));
-        }
+        final Object[] values = {
+            code
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_SENDKEYCODEPOINT, values);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT = {
+        "LatinIMESwapSwapperAndSpaceWhileInBatchEdit"
+    };
     public static void latinIME_swapSwapperAndSpaceWhileInBatchEdit() {
-        if (UnsLogGroup.LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT_ENABLED) {
-            logUnstructured("latinIME_swapSwapperAndSpaceWhileInBatchEdit", "");
-        }
+        getInstance().writeEvent(EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT,
+                EVENTKEYS_NULLVALUES);
     }
 
+    private static final String[] EVENTKEYS_LATINIME_SWITCHTOKEYBOARDVIEW = {
+        "LatinIMESwitchToKeyboardView"
+    };
     public static void latinIME_switchToKeyboardView() {
-        if (UnsLogGroup.LATINIME_SWITCHTOKEYBOARDVIEW_ENABLED) {
-            final String s = "Switch to keyboard view.";
-            logUnstructured("LatinIME_switchToKeyboardView", s);
-        }
+        getInstance().writeEvent(EVENTKEYS_LATINIME_SWITCHTOKEYBOARDVIEW, EVENTKEYS_NULLVALUES);
     }
 
+    private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_ONLONGPRESS = {
+        "LatinKeyboardViewOnLongPress"
+    };
     public static void latinKeyboardView_onLongPress() {
-        if (UnsLogGroup.LATINKEYBOARDVIEW_ONLONGPRESS_ENABLED) {
-            final String s = "long press detected";
-            logUnstructured("LatinKeyboardView_onLongPress", s);
-        }
+        getInstance().writeEvent(EVENTKEYS_LATINKEYBOARDVIEW_ONLONGPRESS, EVENTKEYS_NULLVALUES);
     }
 
-    public static void latinKeyboardView_processMotionEvent(MotionEvent me, int action,
-            long eventTime, int index, int id, int x, int y) {
-        if (UnsLogGroup.LATINKEYBOARDVIEW_ONPROCESSMOTIONEVENT_ENABLED) {
-            final float size = me.getSize(index);
-            final float pressure = me.getPressure(index);
-            if (action != MotionEvent.ACTION_MOVE) {
-                getInstance().logMotionEvent(action, eventTime, id, x, y, size, pressure);
-            }
-        }
-    }
-
+    private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_SETKEYBOARD = {
+        "LatinKeyboardViewSetKeyboard", "elementId", "locale", "orientation", "width",
+        "modeName", "action", "navigateNext", "navigatePrevious", "clobberSettingsKey",
+        "passwordInput", "shortcutKeyEnabled", "hasShortcutKey", "languageSwitchKeyEnabled",
+        "isMultiLine", "tw", "th", "keys"
+    };
     public static void latinKeyboardView_setKeyboard(final Keyboard keyboard) {
-        if (UnsLogGroup.LATINKEYBOARDVIEW_SETKEYBOARD_ENABLED) {
-            StringBuilder builder = new StringBuilder();
-            builder.append("id=");
-            builder.append(keyboard.mId);
-            builder.append("\tw=");
-            builder.append(keyboard.mOccupiedWidth);
-            builder.append("\th=");
-            builder.append(keyboard.mOccupiedHeight);
-            builder.append("\tkeys=[");
-            boolean first = true;
-            for (Key key : keyboard.mKeys) {
-                if (first) {
-                    first = false;
-                } else {
-                    builder.append(",");
-                }
-                builder.append("{code:");
-                builder.append(key.mCode);
-                builder.append(",altCode:");
-                builder.append(key.mAltCode);
-                builder.append(",x:");
-                builder.append(key.mX);
-                builder.append(",y:");
-                builder.append(key.mY);
-                builder.append(",w:");
-                builder.append(key.mWidth);
-                builder.append(",h:");
-                builder.append(key.mHeight);
-                builder.append("}");
-            }
-            builder.append("]");
-            logUnstructured("LatinKeyboardView_setKeyboard", builder.toString());
+        if (keyboard != null) {
+            final KeyboardId kid = keyboard.mId;
+            final Object[] values = {
+                    KeyboardId.elementIdToName(kid.mElementId),
+                    kid.mLocale + ":" + kid.mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
+                    kid.mOrientation,
+                    kid.mWidth,
+                    KeyboardId.modeName(kid.mMode),
+                    kid.imeAction(),
+                    kid.navigateNext(),
+                    kid.navigatePrevious(),
+                    kid.mClobberSettingsKey,
+                    kid.passwordInput(),
+                    kid.mShortcutKeyEnabled,
+                    kid.mHasShortcutKey,
+                    kid.mLanguageSwitchKeyEnabled,
+                    kid.isMultiLine(),
+                    keyboard.mOccupiedWidth,
+                    keyboard.mOccupiedHeight,
+                    keyboard.mKeys
+                };
+            getInstance().writeEvent(EVENTKEYS_LATINKEYBOARDVIEW_SETKEYBOARD, values);
         }
     }
 
+    private static final String[] EVENTKEYS_LATINIME_REVERTCOMMIT = {
+        "LatinIMERevertCommit", "originallyTypedWord"
+    };
     public static void latinIME_revertCommit(final String originallyTypedWord) {
-        if (UnsLogGroup.LATINIME_REVERTCOMMIT_ENABLED) {
-            logUnstructured("LatinIME_revertCommit", originallyTypedWord);
-        }
+        final Object[] values = {
+            originallyTypedWord
+        };
+        getInstance().writeEvent(EVENTKEYS_LATINIME_REVERTCOMMIT, values);
     }
 
+    private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT = {
+        "PointerTrackerCallListenerOnCancelInput"
+    };
     public static void pointerTracker_callListenerOnCancelInput() {
-        final String s = "onCancelInput";
-        if (UnsLogGroup.POINTERTRACKER_CALLLISTENERONCANCELINPUT_ENABLED) {
-            logUnstructured("PointerTracker_callListenerOnCancelInput", s);
-        }
+        getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT,
+                EVENTKEYS_NULLVALUES);
     }
 
+    private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT = {
+        "PointerTrackerCallListenerOnCodeInput", "code", "outputText", "x", "y",
+        "ignoreModifierKey", "altersCode", "isEnabled"
+    };
     public static void pointerTracker_callListenerOnCodeInput(final Key key, final int x,
             final int y, final boolean ignoreModifierKey, final boolean altersCode,
             final int code) {
-        if (UnsLogGroup.POINTERTRACKER_CALLLISTENERONCODEINPUT_ENABLED) {
-            final String s = "onCodeInput: " + Keyboard.printableCode(code)
-                    + " text=" + key.mOutputText + " x=" + x + " y=" + y
-                    + " ignoreModifier=" + ignoreModifierKey + " altersCode=" + altersCode
-                    + " enabled=" + key.isEnabled();
-            logUnstructured("PointerTracker_callListenerOnCodeInput", s);
+        if (key != null) {
+            CharSequence outputText = key.mOutputText;
+            final Object[] values = {
+                Keyboard.printableCode(code), outputText == null ? "" : outputText.toString(),
+                x, y, ignoreModifierKey, altersCode, key.isEnabled()
+            };
+            getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT, values);
         }
     }
 
-    public static void pointerTracker_callListenerOnPressAndCheckKeyboardLayoutChange(
-            final Key key, final boolean ignoreModifierKey) {
-        if (UnsLogGroup.POINTERTRACKER_CALLLISTENERONPRESSANDCHECKKEYBOARDLAYOUTCHANGE_ENABLED) {
-            final String s = "onPress    : " + KeyDetector.printableCode(key)
-                    + " ignoreModifier=" + ignoreModifierKey
-                    + " enabled=" + key.isEnabled();
-            logUnstructured("PointerTracker_callListenerOnPressAndCheckKeyboardLayoutChange", s);
-        }
-    }
-
+    private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE = {
+        "PointerTrackerCallListenerOnRelease", "code", "withSliding", "ignoreModifierKey",
+        "isEnabled"
+    };
     public static void pointerTracker_callListenerOnRelease(final Key key, final int primaryCode,
             final boolean withSliding, final boolean ignoreModifierKey) {
-        if (UnsLogGroup.POINTERTRACKER_CALLLISTENERONRELEASE_ENABLED) {
-            final String s = "onRelease  : " + Keyboard.printableCode(primaryCode)
-                    + " sliding=" + withSliding + " ignoreModifier=" + ignoreModifierKey
-                    + " enabled="+ key.isEnabled();
-            logUnstructured("PointerTracker_callListenerOnRelease", s);
+        if (key != null) {
+            final Object[] values = {
+                Keyboard.printableCode(primaryCode), withSliding, ignoreModifierKey,
+                key.isEnabled()
+            };
+            getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE, values);
         }
     }
 
+    private static final String[] EVENTKEYS_POINTERTRACKER_ONDOWNEVENT = {
+        "PointerTrackerOnDownEvent", "deltaT", "distanceSquared"
+    };
     public static void pointerTracker_onDownEvent(long deltaT, int distanceSquared) {
-        if (UnsLogGroup.POINTERTRACKER_ONDOWNEVENT_ENABLED) {
-            final String s = "onDownEvent: ignore potential noise: time=" + deltaT
-                    + " distance=" + distanceSquared;
-            logUnstructured("PointerTracker_onDownEvent", s);
-        }
+        final Object[] values = {
+            deltaT, distanceSquared
+        };
+        getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_ONDOWNEVENT, values);
     }
 
+    private static final String[] EVENTKEYS_POINTERTRACKER_ONMOVEEVENT = {
+        "PointerTrackerOnMoveEvent", "x", "y", "lastX", "lastY"
+    };
     public static void pointerTracker_onMoveEvent(final int x, final int y, final int lastX,
             final int lastY) {
-        if (UnsLogGroup.POINTERTRACKER_ONMOVEEVENT_ENABLED) {
-            final String s = String.format("onMoveEvent: sudden move is translated to "
-                    + "up[%d,%d]/down[%d,%d] events", lastX, lastY, x, y);
-            logUnstructured("PointerTracker_onMoveEvent", s);
-        }
+        final Object[] values = {
+            x, y, lastX, lastY
+        };
+        getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_ONMOVEEVENT, values);
     }
 
+    private static final String[] EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT = {
+        "SuddenJumpingTouchEventHandlerOnTouchEvent", "motionEvent"
+    };
     public static void suddenJumpingTouchEventHandler_onTouchEvent(final MotionEvent me) {
-        if (UnsLogGroup.SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT_ENABLED) {
-            final String s = "onTouchEvent: ignore sudden jump " + me;
-            logUnstructured("SuddenJumpingTouchEventHandler_onTouchEvent", s);
+        if (me != null) {
+            final Object[] values = {
+                me.toString()
+            };
+            getInstance().writeEvent(EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT,
+                    values);
         }
     }
 
-    public static void suggestionsView_setSuggestions(final SuggestedWords mSuggestedWords) {
-        if (UnsLogGroup.SUGGESTIONSVIEW_SETSUGGESTIONS_ENABLED) {
-            logUnstructured("SuggestionsView_setSuggestions", mSuggestedWords.toString());
+    private static final String[] EVENTKEYS_SUGGESTIONSVIEW_SETSUGGESTIONS = {
+        "SuggestionsViewSetSuggestions", "suggestedWords"
+    };
+    public static void suggestionsView_setSuggestions(final SuggestedWords suggestedWords) {
+        if (suggestedWords != null) {
+            final Object[] values = {
+                suggestedWords
+            };
+            getInstance().writeEvent(EVENTKEYS_SUGGESTIONSVIEW_SETSUGGESTIONS, values);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 8128779..802322c 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -496,20 +496,32 @@
         }
 
         private static class SuggestionsCache {
+            private static final char CHAR_DELIMITER = '\uFFFC';
             private static final int MAX_CACHE_SIZE = 50;
-            // TODO: support bigram
             private final LruCache<String, SuggestionsParams> mUnigramSuggestionsInfoCache =
                     new LruCache<String, SuggestionsParams>(MAX_CACHE_SIZE);
 
-            public SuggestionsParams getSuggestionsFromCache(String query) {
-                return mUnigramSuggestionsInfoCache.get(query);
+            // TODO: Support n-gram input
+            private static String generateKey(String query, String prevWord) {
+                if (TextUtils.isEmpty(query) || TextUtils.isEmpty(prevWord)) {
+                    return query;
+                }
+                return query + CHAR_DELIMITER + prevWord;
             }
 
-            public void putSuggestionsToCache(String query, String[] suggestions, int flags) {
+            // TODO: Support n-gram input
+            public SuggestionsParams getSuggestionsFromCache(String query, String prevWord) {
+                return mUnigramSuggestionsInfoCache.get(generateKey(query, prevWord));
+            }
+
+            // TODO: Support n-gram input
+            public void putSuggestionsToCache(
+                    String query, String prevWord, String[] suggestions, int flags) {
                 if (suggestions == null || TextUtils.isEmpty(query)) {
                     return;
                 }
-                mUnigramSuggestionsInfoCache.put(query, new SuggestionsParams(suggestions, flags));
+                mUnigramSuggestionsInfoCache.put(
+                        generateKey(query, prevWord), new SuggestionsParams(suggestions, flags));
             }
         }
 
@@ -604,6 +616,7 @@
             final ArrayList<Integer> additionalLengths = new ArrayList<Integer>();
             final ArrayList<SuggestionsInfo> additionalSuggestionsInfos =
                     new ArrayList<SuggestionsInfo>();
+            String currentWord = null;
             for (int i = 0; i < N; ++i) {
                 final SuggestionsInfo si = ssi.getSuggestionsInfoAt(i);
                 final int flags = si.getSuggestionsAttributes();
@@ -613,6 +626,8 @@
                 final int offset = ssi.getOffsetAt(i);
                 final int length = ssi.getLengthAt(i);
                 final String subText = typedText.substring(offset, offset + length);
+                final String prevWord = currentWord;
+                currentWord = subText;
                 if (!subText.contains(SINGLE_QUOTE)) {
                     continue;
                 }
@@ -626,7 +641,8 @@
                     if (TextUtils.isEmpty(splitText)) {
                         continue;
                     }
-                    if (mSuggestionsCache.getSuggestionsFromCache(splitText) == null) {
+                    if (mSuggestionsCache.getSuggestionsFromCache(
+                            splitText, prevWord) == null) {
                         continue;
                     }
                     final int newLength = splitText.length();
@@ -722,7 +738,7 @@
             try {
                 final String inText = textInfo.getText();
                 final SuggestionsParams cachedSuggestionsParams =
-                        mSuggestionsCache.getSuggestionsFromCache(inText);
+                        mSuggestionsCache.getSuggestionsFromCache(inText, prevWord);
                 if (cachedSuggestionsParams != null) {
                     if (DBG) {
                         Log.d(TAG, "Cache hit: " + inText + ", " + cachedSuggestionsParams.mFlags);
@@ -814,7 +830,7 @@
                                         .getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS()
                                 : 0);
                 final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions);
-                mSuggestionsCache.putSuggestionsToCache(text, result.mSuggestions, flags);
+                mSuggestionsCache.putSuggestionsToCache(text, prevWord, result.mSuggestions, flags);
                 return retval;
             } catch (RuntimeException e) {
                 // Don't kill the keyboard if there is a bug in the spell checker
diff --git a/tests/src/com/android/inputmethod/latin/EditingUtilsTests.java b/tests/src/com/android/inputmethod/latin/EditingUtilsTests.java
new file mode 100644
index 0000000..c73f889
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/EditingUtilsTests.java
@@ -0,0 +1,161 @@
+/*
+ * 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.inputmethod.latin;
+
+import android.test.AndroidTestCase;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputConnectionWrapper;
+
+import com.android.inputmethod.latin.EditingUtils.Range;
+
+public class EditingUtilsTests extends AndroidTestCase {
+
+    // The following is meant to be a reasonable default for
+    // the "word_separators" resource.
+    private static final String sSeparators = ".,:;!?-";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    private class MockConnection extends InputConnectionWrapper {
+        final String mTextBefore;
+        final String mTextAfter;
+        final ExtractedText mExtractedText;
+
+        public MockConnection(String textBefore, String textAfter, ExtractedText extractedText) {
+            super(null, false);
+            mTextBefore = textBefore;
+            mTextAfter = textAfter;
+            mExtractedText = extractedText;
+        }
+
+        /* (non-Javadoc)
+         * @see android.view.inputmethod.InputConnectionWrapper#getTextBeforeCursor(int, int)
+         */
+        @Override
+        public CharSequence getTextBeforeCursor(int n, int flags) {
+            return mTextBefore;
+        }
+
+        /* (non-Javadoc)
+         * @see android.view.inputmethod.InputConnectionWrapper#getTextAfterCursor(int, int)
+         */
+        @Override
+        public CharSequence getTextAfterCursor(int n, int flags) {
+            return mTextAfter;
+        }
+
+        /* (non-Javadoc)
+         * @see android.view.inputmethod.InputConnectionWrapper#getExtractedText(ExtractedTextRequest, int)
+         */
+        @Override
+        public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
+            return mExtractedText;
+        }
+    }
+
+    /************************** Tests ************************/
+
+    /**
+     * Test for getting previous word (for bigram suggestions)
+     */
+    public void testGetPreviousWord() {
+        // If one of the following cases breaks, the bigram suggestions won't work.
+        assertEquals(EditingUtils.getPreviousWord("abc def", sSeparators), "abc");
+        assertNull(EditingUtils.getPreviousWord("abc", sSeparators));
+        assertNull(EditingUtils.getPreviousWord("abc. def", sSeparators));
+
+        // The following tests reflect the current behavior of the function
+        // EditingUtils#getPreviousWord.
+        // TODO: However at this time, the code does never go
+        // into such a path, so it should be safe to change the behavior of
+        // this function if needed - especially since it does not seem very
+        // logical. These tests are just there to catch any unintentional
+        // changes in the behavior of the EditingUtils#getPreviousWord method.
+        assertEquals(EditingUtils.getPreviousWord("abc def ", sSeparators), "abc");
+        assertEquals(EditingUtils.getPreviousWord("abc def.", sSeparators), "abc");
+        assertEquals(EditingUtils.getPreviousWord("abc def .", sSeparators), "def");
+        assertNull(EditingUtils.getPreviousWord("abc ", sSeparators));
+    }
+
+    /**
+     * Test for getting the word before the cursor (for bigram)
+     */
+    public void testGetThisWord() {
+        assertEquals(EditingUtils.getThisWord("abc def", sSeparators), "def");
+        assertEquals(EditingUtils.getThisWord("abc def ", sSeparators), "def");
+        assertNull(EditingUtils.getThisWord("abc def.", sSeparators));
+        assertNull(EditingUtils.getThisWord("abc def .", sSeparators));
+    }
+
+    /**
+     * Test logic in getting the word range at the cursor.
+     */
+    public void testGetWordRangeAtCursor() {
+        ExtractedText et = new ExtractedText();
+        InputConnection mockConnection;
+        mockConnection = new MockConnection("word wo", "rd", et);
+        et.startOffset = 0;
+        et.selectionStart = 7;
+        Range r;
+
+        // basic case
+        r = EditingUtils.getWordRangeAtCursor(mockConnection, " ", 0);
+        assertEquals("word", r.mWord);
+        r = null;
+
+        // more than one word
+        r = EditingUtils.getWordRangeAtCursor(mockConnection, " ", 1);
+        assertEquals("word word", r.mWord);
+        r = null;
+
+        // tab character instead of space
+        mockConnection = new MockConnection("one\tword\two", "rd", et);
+        r = EditingUtils.getWordRangeAtCursor(mockConnection, "\t", 1);
+        assertEquals("word\tword", r.mWord);
+        r = null;
+
+        // only one word doesn't go too far
+        mockConnection = new MockConnection("one\tword\two", "rd", et);
+        r = EditingUtils.getWordRangeAtCursor(mockConnection, "\t", 1);
+        assertEquals("word\tword", r.mWord);
+        r = null;
+
+        // tab or space
+        mockConnection = new MockConnection("one word\two", "rd", et);
+        r = EditingUtils.getWordRangeAtCursor(mockConnection, " \t", 1);
+        assertEquals("word\tword", r.mWord);
+        r = null;
+
+        // tab or space multiword
+        mockConnection = new MockConnection("one word\two", "rd", et);
+        r = EditingUtils.getWordRangeAtCursor(mockConnection, " \t", 2);
+        assertEquals("one word\tword", r.mWord);
+        r = null;
+
+        // splitting on supplementary character
+        final String supplementaryChar = "\uD840\uDC8A";
+        mockConnection = new MockConnection("one word" + supplementaryChar + "wo", "rd", et);
+        r = EditingUtils.getWordRangeAtCursor(mockConnection, supplementaryChar, 0);
+        assertEquals("word", r.mWord);
+        r = null;
+    }
+}
diff --git a/tests/src/com/android/inputmethod/latin/UtilsTests.java b/tests/src/com/android/inputmethod/latin/UtilsTests.java
deleted file mode 100644
index 2ef4e2f..0000000
--- a/tests/src/com/android/inputmethod/latin/UtilsTests.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2010,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 android.test.AndroidTestCase;
-
-public class UtilsTests extends AndroidTestCase {
-
-    // The following is meant to be a reasonable default for
-    // the "word_separators" resource.
-    private static final String sSeparators = ".,:;!?-";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    /************************** Tests ************************/
-
-    /**
-     * Test for getting previous word (for bigram suggestions)
-     */
-    public void testGetPreviousWord() {
-        // If one of the following cases breaks, the bigram suggestions won't work.
-        assertEquals(EditingUtils.getPreviousWord("abc def", sSeparators), "abc");
-        assertNull(EditingUtils.getPreviousWord("abc", sSeparators));
-        assertNull(EditingUtils.getPreviousWord("abc. def", sSeparators));
-
-        // The following tests reflect the current behavior of the function
-        // EditingUtils#getPreviousWord.
-        // TODO: However at this time, the code does never go
-        // into such a path, so it should be safe to change the behavior of
-        // this function if needed - especially since it does not seem very
-        // logical. These tests are just there to catch any unintentional
-        // changes in the behavior of the EditingUtils#getPreviousWord method.
-        assertEquals(EditingUtils.getPreviousWord("abc def ", sSeparators), "abc");
-        assertEquals(EditingUtils.getPreviousWord("abc def.", sSeparators), "abc");
-        assertEquals(EditingUtils.getPreviousWord("abc def .", sSeparators), "def");
-        assertNull(EditingUtils.getPreviousWord("abc ", sSeparators));
-    }
-
-    /**
-     * Test for getting the word before the cursor (for bigram)
-     */
-    public void testGetThisWord() {
-        assertEquals(EditingUtils.getThisWord("abc def", sSeparators), "def");
-        assertEquals(EditingUtils.getThisWord("abc def ", sSeparators), "def");
-        assertNull(EditingUtils.getThisWord("abc def.", sSeparators));
-        assertNull(EditingUtils.getThisWord("abc def .", sSeparators));
-    }
-}
diff --git a/tools/dicttool/Android.mk b/tools/dicttool/Android.mk
new file mode 100644
index 0000000..9e8dbe0
--- /dev/null
+++ b/tools/dicttool/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_JAR_MANIFEST := etc/manifest.txt
+LOCAL_MODULE := dicttool
+LOCAL_MODULE_TAGS := eng
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+include $(LOCAL_PATH)/etc/Android.mk
diff --git a/tools/dicttool/etc/Android.mk b/tools/dicttool/etc/Android.mk
new file mode 100644
index 0000000..03d4a96
--- /dev/null
+++ b/tools/dicttool/etc/Android.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := eng
+LOCAL_PREBUILT_EXECUTABLES := dicttool
+include $(BUILD_HOST_PREBUILT)
diff --git a/tools/dicttool/etc/dicttool b/tools/dicttool/etc/dicttool
new file mode 100755
index 0000000..8a39694
--- /dev/null
+++ b/tools/dicttool/etc/dicttool
@@ -0,0 +1,62 @@
+#!/bin/sh
+# Copyright 2011, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=dicttool.jar
+frameworkdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# might need more memory, e.g. -Xmx128M
+exec java -ea -jar "$jarpath" "$@"
diff --git a/tools/dicttool/etc/manifest.txt b/tools/dicttool/etc/manifest.txt
new file mode 100644
index 0000000..67c8521
--- /dev/null
+++ b/tools/dicttool/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.inputmethod.latin.dicttool.Dicttool
diff --git a/tools/dicttool/src/android/inputmethod/latin/dicttool/Compress.java b/tools/dicttool/src/android/inputmethod/latin/dicttool/Compress.java
new file mode 100644
index 0000000..307f596
--- /dev/null
+++ b/tools/dicttool/src/android/inputmethod/latin/dicttool/Compress.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin.dicttool;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+public class Compress {
+
+    private static OutputStream getCompressedStream(final OutputStream out)
+        throws java.io.IOException {
+        return new GZIPOutputStream(out);
+    }
+
+    private static InputStream getUncompressedStream(final InputStream in) throws IOException {
+        return new GZIPInputStream(in);
+    }
+
+    public static void copy(final InputStream input, final OutputStream output) throws IOException {
+        final byte[] buffer = new byte[1000];
+        for (int readBytes = input.read(buffer); readBytes >= 0; readBytes = input.read(buffer))
+            output.write(buffer, 0, readBytes);
+        input.close();
+        output.close();
+    }
+
+    static public class Compressor extends Dicttool.Command {
+        public static final String COMMAND = "compress";
+        private static final String SUFFIX = ".compressed";
+
+        public Compressor() {
+        }
+
+        public String getHelp() {
+            return "compress <filename>: Compresses a file using gzip compression";
+        }
+
+        public int getArity() {
+            return 1;
+        }
+
+        public void run() throws IOException {
+            final String inFilename = mArgs[0];
+            final String outFilename = inFilename + SUFFIX;
+            final FileInputStream input = new FileInputStream(new File(inFilename));
+            final FileOutputStream output = new FileOutputStream(new File(outFilename));
+            copy(input, new GZIPOutputStream(output));
+        }
+    }
+
+    static public class Uncompressor extends Dicttool.Command {
+        public static final String COMMAND = "uncompress";
+        private static final String SUFFIX = ".uncompressed";
+
+        public Uncompressor() {
+        }
+
+        public String getHelp() {
+            return "uncompress <filename>: Uncompresses a file compressed with gzip compression";
+        }
+
+        public int getArity() {
+            return 1;
+        }
+
+        public void run() throws IOException {
+            final String inFilename = mArgs[0];
+            final String outFilename = inFilename + SUFFIX;
+            final FileInputStream input = new FileInputStream(new File(inFilename));
+            final FileOutputStream output = new FileOutputStream(new File(outFilename));
+            copy(new GZIPInputStream(input), output);
+        }
+    }
+}
diff --git a/tools/dicttool/src/android/inputmethod/latin/dicttool/Dicttool.java b/tools/dicttool/src/android/inputmethod/latin/dicttool/Dicttool.java
new file mode 100644
index 0000000..b78be79
--- /dev/null
+++ b/tools/dicttool/src/android/inputmethod/latin/dicttool/Dicttool.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin.dicttool;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+public class Dicttool {
+
+    public static abstract class Command {
+        protected String[] mArgs;
+        public void setArgs(String[] args) throws IllegalArgumentException {
+            mArgs = args;
+        }
+        abstract public int getArity();
+        abstract public String getHelp();
+        abstract public void run() throws Exception;
+    }
+    static HashMap<String, Class<? extends Command>> sCommands =
+            new HashMap<String, Class<? extends Command>>();
+    static {
+        sCommands.put("info", Info.class);
+        sCommands.put("compress", Compress.Compressor.class);
+        sCommands.put("uncompress", Compress.Uncompressor.class);
+    }
+
+    private static Command getCommandInstance(final String commandName) {
+        try {
+            return sCommands.get(commandName).newInstance();
+        } catch (InstantiationException e) {
+            throw new RuntimeException(commandName + " is not installed");
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(commandName + " is not installed");
+        }
+    }
+
+    private static void help() {
+        System.out.println("Syntax: dicttool <command [arguments]>\nAvailable commands:\n");
+        for (final String commandName : sCommands.keySet()) {
+            System.out.println("*** " + commandName);
+            System.out.println(getCommandInstance(commandName).getHelp());
+            System.out.println("");
+        }
+    }
+
+    private static boolean isCommand(final String commandName) {
+        return sCommands.containsKey(commandName);
+    }
+
+    private String mPreviousCommand = null; // local to the getNextCommand function
+    private Command getNextCommand(final ArrayList<String> arguments) {
+        final String firstArgument = arguments.get(0);
+        final String commandName;
+        if (isCommand(firstArgument)) {
+            commandName = firstArgument;
+            arguments.remove(0);
+        } else if (isCommand(mPreviousCommand)) {
+            commandName = mPreviousCommand;
+        } else {
+            throw new RuntimeException("Unknown command : " + firstArgument);
+        }
+        final Command command = getCommandInstance(commandName);
+        final int arity = command.getArity();
+        if (arguments.size() < arity) {
+            throw new RuntimeException("Not enough arguments to command " + commandName);
+        }
+        final String[] argsArray = new String[arity];
+        arguments.subList(0, arity).toArray(argsArray);
+        for (int i = 0; i < arity; ++i) {
+            // For some reason, ArrayList#removeRange is protected
+            arguments.remove(0);
+        }
+        command.setArgs(argsArray);
+        mPreviousCommand = commandName;
+        return command;
+    }
+
+    private void execute(final ArrayList<String> arguments) {
+        ArrayList<Command> commandsToExecute = new ArrayList<Command>();
+        while (!arguments.isEmpty()) {
+            commandsToExecute.add(getNextCommand(arguments));
+        }
+        for (final Command command : commandsToExecute) {
+            try {
+                command.run();
+            } catch (Exception e) {
+                System.out.println("Exception while processing command "
+                        + command.getClass().getSimpleName() + " : " + e);
+                return;
+            }
+        }
+    }
+
+    public static void main(final String[] args) {
+        if (0 == args.length) {
+            help();
+            return;
+        }
+        if (!isCommand(args[0])) throw new RuntimeException("Unknown command : " + args[0]);
+
+        final ArrayList<String> arguments = new ArrayList<String>(args.length);
+        arguments.addAll(Arrays.asList(args));
+        new Dicttool().execute(arguments);
+    }
+}
diff --git a/tools/dicttool/src/android/inputmethod/latin/dicttool/Info.java b/tools/dicttool/src/android/inputmethod/latin/dicttool/Info.java
new file mode 100644
index 0000000..cb032dd
--- /dev/null
+++ b/tools/dicttool/src/android/inputmethod/latin/dicttool/Info.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin.dicttool;
+
+public class Info extends Dicttool.Command {
+    public Info() {
+    }
+
+    public String getHelp() {
+        return "info <filename>: prints various information about a dictionary file";
+    }
+
+    public int getArity() {
+        return 1;
+    }
+
+    public void run() {
+        // TODO: implement this
+        System.out.println("Not implemented yet");
+    }
+}
