diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
index 0576f666c7393509f2422fbd7779058ea70b8658..77f3234406d48f74a29687dc52162c28eb647c69 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
@@ -35,8 +35,8 @@ import android.view.inputmethod.EditorInfo;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardView;
-import com.android.inputmethod.latin.CollectionUtils;
-import com.android.inputmethod.latin.CoordinateUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.CoordinateUtils;
 
 /**
  * Exposes a virtual view sub-tree for {@link KeyboardView} and generates
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
index ee52de1d1a70f1dbabff578d604e12895990ff43..8929dc7e9664ddd74762e2126952ce41136ed9f3 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -33,8 +33,8 @@ import android.view.accessibility.AccessibilityManager;
 import android.view.inputmethod.EditorInfo;
 
 import com.android.inputmethod.compat.SettingsSecureCompatUtils;
-import com.android.inputmethod.latin.InputTypeUtils;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.InputTypeUtils;
 
 public final class AccessibilityUtils {
     private static final String TAG = AccessibilityUtils.class.getSimpleName();
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index 05d8269b7515916a4242d027c0268e67b9f69b32..41f5b9a249df601b8098867977dc154909443df6 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -25,9 +25,9 @@ import android.view.inputmethod.EditorInfo;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.HashMap;
 
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index 141e08a8d7fbe776bbd1075fe63149989a5cc200..e195a5406f959e7af18a16284583a79881ace659 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -23,10 +23,10 @@ import android.text.Spanned;
 import android.text.TextUtils;
 import android.text.style.SuggestionSpan;
 
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
diff --git a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
index bf22305537a644d4750c91383ffb2d771d8d667f..be9f8793094bf7306bfcd6d275fcd6cbb733ddba 100644
--- a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
+++ b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
@@ -28,6 +28,8 @@ import android.util.Log;
 
 import com.android.inputmethod.compat.DownloadManagerCompatUtils;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.LogUtils;
+import com.android.inputmethod.latin.utils.Utils;
 
 import java.util.LinkedList;
 import java.util.Queue;
@@ -98,7 +100,7 @@ public final class ActionBatch {
         final boolean mForceStartNow;
         public StartDownloadAction(final String clientId,
                 final WordListMetadata wordList, final boolean forceStartNow) {
-            Utils.l("New download action for client ", clientId, " : ", wordList);
+            LogUtils.l("New download action for client ", clientId, " : ", wordList);
             mClientId = clientId;
             mWordList = wordList;
             mForceStartNow = forceStartNow;
@@ -110,7 +112,7 @@ public final class ActionBatch {
                 Log.e(TAG, "UpdateAction with a null parameter!");
                 return;
             }
-            Utils.l("Downloading word list");
+            LogUtils.l("Downloading word list");
             final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId);
             final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db,
                     mWordList.mId, mWordList.mVersion);
@@ -132,7 +134,7 @@ public final class ActionBatch {
                         + " for an upgrade action. Fall back to download.");
             }
             // Download it.
-            Utils.l("Upgrade word list, downloading", mWordList.mRemoteFilename);
+            LogUtils.l("Upgrade word list, downloading", mWordList.mRemoteFilename);
 
             // TODO: if DownloadManager is disabled or not installed, download by ourselves
             if (null == manager) return;
@@ -142,7 +144,7 @@ public final class ActionBatch {
             // DownloadManager also stupidly cuts the extension to replace with its own that it
             // gets from the content-type. We need to circumvent this.
             final String disambiguator = "#" + System.currentTimeMillis()
-                    + com.android.inputmethod.latin.Utils.getVersionName(context) + ".dict";
+                    + Utils.getVersionName(context) + ".dict";
             final Uri uri = Uri.parse(mWordList.mRemoteFilename + disambiguator);
             final Request request = new Request(uri);
 
@@ -178,7 +180,7 @@ public final class ActionBatch {
 
             final long downloadId = UpdateHandler.registerDownloadRequest(manager, request, db,
                     mWordList.mId, mWordList.mVersion);
-            Utils.l("Starting download of", uri, "with id", downloadId);
+            LogUtils.l("Starting download of", uri, "with id", downloadId);
             PrivateLog.log("Starting download of " + uri + ", id : " + downloadId);
         }
     }
@@ -195,7 +197,8 @@ public final class ActionBatch {
 
         public InstallAfterDownloadAction(final String clientId,
                 final ContentValues wordListValues) {
-            Utils.l("New InstallAfterDownloadAction for client ", clientId, " : ", wordListValues);
+            LogUtils.l("New InstallAfterDownloadAction for client ", clientId, " : ",
+                    wordListValues);
             mClientId = clientId;
             mWordListValues = wordListValues;
         }
@@ -213,7 +216,7 @@ public final class ActionBatch {
                         + " for an InstallAfterDownload action. Bailing out.");
                 return;
             }
-            Utils.l("Setting word list as installed");
+            LogUtils.l("Setting word list as installed");
             final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId);
             MetadataDbHelper.markEntryAsFinishedDownloadingAndInstalled(db, mWordListValues);
         }
@@ -229,7 +232,7 @@ public final class ActionBatch {
         final WordListMetadata mWordList;
 
         public EnableAction(final String clientId, final WordListMetadata wordList) {
-            Utils.l("New EnableAction for client ", clientId, " : ", wordList);
+            LogUtils.l("New EnableAction for client ", clientId, " : ", wordList);
             mClientId = clientId;
             mWordList = wordList;
         }
@@ -240,7 +243,7 @@ public final class ActionBatch {
                 Log.e(TAG, "EnableAction with a null parameter!");
                 return;
             }
-            Utils.l("Enabling word list");
+            LogUtils.l("Enabling word list");
             final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId);
             final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db,
                     mWordList.mId, mWordList.mVersion);
@@ -264,7 +267,7 @@ public final class ActionBatch {
         // The word list to disable. May not be null.
         final WordListMetadata mWordList;
         public DisableAction(final String clientId, final WordListMetadata wordlist) {
-            Utils.l("New Disable action for client ", clientId, " : ", wordlist);
+            LogUtils.l("New Disable action for client ", clientId, " : ", wordlist);
             mClientId = clientId;
             mWordList = wordlist;
         }
@@ -275,7 +278,7 @@ public final class ActionBatch {
                 Log.e(TAG, "DisableAction with a null word list!");
                 return;
             }
-            Utils.l("Disabling word list : " + mWordList);
+            LogUtils.l("Disabling word list : " + mWordList);
             final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId);
             final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db,
                     mWordList.mId, mWordList.mVersion);
@@ -311,7 +314,7 @@ public final class ActionBatch {
         // The word list to make available. May not be null.
         final WordListMetadata mWordList;
         public MakeAvailableAction(final String clientId, final WordListMetadata wordlist) {
-            Utils.l("New MakeAvailable action", clientId, " : ", wordlist);
+            LogUtils.l("New MakeAvailable action", clientId, " : ", wordlist);
             mClientId = clientId;
             mWordList = wordlist;
         }
@@ -328,7 +331,7 @@ public final class ActionBatch {
                 Log.e(TAG, "Unexpected state of the word list '" + mWordList.mId + "' "
                         + " for a makeavailable action. Marking as available anyway.");
             }
-            Utils.l("Making word list available : " + mWordList);
+            LogUtils.l("Making word list available : " + mWordList);
             // If mLocalFilename is null, then it's a remote file that hasn't been downloaded
             // yet, so we set the local filename to the empty string.
             final ContentValues values = MetadataDbHelper.makeContentValues(0,
@@ -360,7 +363,7 @@ public final class ActionBatch {
         // The word list to mark pre-installed. May not be null.
         final WordListMetadata mWordList;
         public MarkPreInstalledAction(final String clientId, final WordListMetadata wordlist) {
-            Utils.l("New MarkPreInstalled action", clientId, " : ", wordlist);
+            LogUtils.l("New MarkPreInstalled action", clientId, " : ", wordlist);
             mClientId = clientId;
             mWordList = wordlist;
         }
@@ -377,7 +380,7 @@ public final class ActionBatch {
                 Log.e(TAG, "Unexpected state of the word list '" + mWordList.mId + "' "
                         + " for a markpreinstalled action. Marking as preinstalled anyway.");
             }
-            Utils.l("Marking word list preinstalled : " + mWordList);
+            LogUtils.l("Marking word list preinstalled : " + mWordList);
             // This word list is pre-installed : we don't have its file. We should reset
             // the local file name to the empty string so that we don't try to open it
             // accidentally. The remote filename may be set by the application if it so wishes.
@@ -401,7 +404,7 @@ public final class ActionBatch {
         private final String mClientId;
         final WordListMetadata mWordList;
         public UpdateDataAction(final String clientId, final WordListMetadata wordlist) {
-            Utils.l("New UpdateData action for client ", clientId, " : ", wordlist);
+            LogUtils.l("New UpdateData action for client ", clientId, " : ", wordlist);
             mClientId = clientId;
             mWordList = wordlist;
         }
@@ -419,7 +422,7 @@ public final class ActionBatch {
                 Log.e(TAG, "Trying to update data about a non-existing word list. Bailing out.");
                 return;
             }
-            Utils.l("Updating data about a word list : " + mWordList);
+            LogUtils.l("Updating data about a word list : " + mWordList);
             final ContentValues values = MetadataDbHelper.makeContentValues(
                     oldValues.getAsInteger(MetadataDbHelper.PENDINGID_COLUMN),
                     oldValues.getAsInteger(MetadataDbHelper.TYPE_COLUMN),
@@ -453,7 +456,7 @@ public final class ActionBatch {
         final boolean mHasNewerVersion;
         public ForgetAction(final String clientId, final WordListMetadata wordlist,
                 final boolean hasNewerVersion) {
-            Utils.l("New TryRemove action for client ", clientId, " : ", wordlist);
+            LogUtils.l("New TryRemove action for client ", clientId, " : ", wordlist);
             mClientId = clientId;
             mWordList = wordlist;
             mHasNewerVersion = hasNewerVersion;
@@ -465,7 +468,7 @@ public final class ActionBatch {
                 Log.e(TAG, "TryRemoveAction with a null word list!");
                 return;
             }
-            Utils.l("Trying to remove word list : " + mWordList);
+            LogUtils.l("Trying to remove word list : " + mWordList);
             final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId);
             final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db,
                     mWordList.mId, mWordList.mVersion);
@@ -525,7 +528,7 @@ public final class ActionBatch {
         // The word list to delete. May not be null.
         final WordListMetadata mWordList;
         public StartDeleteAction(final String clientId, final WordListMetadata wordlist) {
-            Utils.l("New StartDelete action for client ", clientId, " : ", wordlist);
+            LogUtils.l("New StartDelete action for client ", clientId, " : ", wordlist);
             mClientId = clientId;
             mWordList = wordlist;
         }
@@ -536,7 +539,7 @@ public final class ActionBatch {
                 Log.e(TAG, "StartDeleteAction with a null word list!");
                 return;
             }
-            Utils.l("Trying to delete word list : " + mWordList);
+            LogUtils.l("Trying to delete word list : " + mWordList);
             final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId);
             final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db,
                     mWordList.mId, mWordList.mVersion);
@@ -564,7 +567,7 @@ public final class ActionBatch {
         // The word list to delete. May not be null.
         final WordListMetadata mWordList;
         public FinishDeleteAction(final String clientId, final WordListMetadata wordlist) {
-            Utils.l("New FinishDelete action for client", clientId, " : ", wordlist);
+            LogUtils.l("New FinishDelete action for client", clientId, " : ", wordlist);
             mClientId = clientId;
             mWordList = wordlist;
         }
@@ -575,7 +578,7 @@ public final class ActionBatch {
                 Log.e(TAG, "FinishDeleteAction with a null word list!");
                 return;
             }
-            Utils.l("Trying to delete word list : " + mWordList);
+            LogUtils.l("Trying to delete word list : " + mWordList);
             final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId);
             final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db,
                     mWordList.mId, mWordList.mVersion);
@@ -632,7 +635,7 @@ public final class ActionBatch {
      * @param reporter a Reporter to send errors to.
      */
     public void execute(final Context context, final ProblemReporter reporter) {
-        Utils.l("Executing a batch of actions");
+        LogUtils.l("Executing a batch of actions");
         Queue<Action> remainingActions = mActions;
         while (!remainingActions.isEmpty()) {
             final Action a = remainingActions.poll();
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java
index 5ad5900d4f47b66e2d62fccbb4268f2759f2211c..f1a2a8333b3525d7d64a43533301015d13f610bc 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.dictionarypack;
 
 import android.view.View;
 
-import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.HashMap;
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
index 4fbe16233f8cfb05f1edfea380a7893091e1b5d8..4aa4d4b430f4de5c28df9b17d0aca2cbac5829d1 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
@@ -31,6 +31,7 @@ import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.LogUtils;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -219,7 +220,7 @@ public final class DictionaryProvider extends ContentProvider {
     @Override
     public Cursor query(final Uri uri, final String[] projection, final String selection,
             final String[] selectionArgs, final String sortOrder) {
-        Utils.l("Uri =", uri);
+        LogUtils.l("Uri =", uri);
         PrivateLog.log("Query : " + uri);
         final String clientId = getClientId(uri);
         final int match = matchUri(uri);
@@ -227,7 +228,7 @@ public final class DictionaryProvider extends ContentProvider {
             case DICTIONARY_V1_WHOLE_LIST:
             case DICTIONARY_V2_WHOLE_LIST:
                 final Cursor c = MetadataDbHelper.queryDictionaries(getContext(), clientId);
-                Utils.l("List of dictionaries with count", c.getCount());
+                LogUtils.l("List of dictionaries with count", c.getCount());
                 PrivateLog.log("Returned a list of " + c.getCount() + " items");
                 return c;
             case DICTIONARY_V2_DICT_INFO:
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
index dac12137d44e4c8fdc30ebf8f096fdb084399827..c6cadb8231fef14a586597ba6a90c0f381cfd758 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
@@ -25,6 +25,7 @@ import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.LogUtils;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -772,12 +773,12 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
         if (TextUtils.isEmpty(valuesClientId) || null == valuesMetadataUri
                 || null == valuesMetadataAdditionalId) {
             // We need all these columns to be filled in
-            Utils.l("Missing parameter for updateClientInfo");
+            LogUtils.l("Missing parameter for updateClientInfo");
             return;
         }
         if (!clientId.equals(valuesClientId)) {
             // Mismatch! The client violates the protocol.
-            Utils.l("Received an updateClientInfo request for ", clientId, " but the values "
+            LogUtils.l("Received an updateClientInfo request for ", clientId, " but the values "
                     + "contain a different ID : ", valuesClientId);
             return;
         }
@@ -847,7 +848,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
             final ContentValues r) {
         switch (r.getAsInteger(TYPE_COLUMN)) {
             case TYPE_BULK:
-                Utils.l("Ended processing a wordlist");
+                LogUtils.l("Ended processing a wordlist");
                 // Updating a bulk word list is a three-step operation:
                 // - Add the new entry to the table
                 // - Remove the old entry from the table
@@ -869,7 +870,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
                         // the phone is suddenly cut during an update.
                         final int filenameIndex = c.getColumnIndex(LOCAL_FILENAME_COLUMN);
                         do {
-                            Utils.l("Setting for removal", c.getString(filenameIndex));
+                            LogUtils.l("Setting for removal", c.getString(filenameIndex));
                             filenames.add(c.getString(filenameIndex));
                         } while (c.moveToNext());
                     }
diff --git a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
index 3f917f13fac7a031d014973917217c63714786f0..936d00d2513bf94b9c81e6922c74fa18a477c7f9 100644
--- a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
+++ b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
@@ -38,6 +38,8 @@ import android.util.Log;
 import com.android.inputmethod.compat.ConnectivityManagerCompatUtils;
 import com.android.inputmethod.compat.DownloadManagerCompatUtils;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.LogUtils;
+import com.android.inputmethod.latin.utils.Utils;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -183,8 +185,8 @@ public final class UpdateHandler {
                 final String clientId = cursor.getString(0);
                 final String metadataUri =
                         MetadataDbHelper.getMetadataUriAsString(context, clientId);
-                PrivateLog.log("Update for clientId " + Utils.s(clientId));
-                Utils.l("Update for clientId", clientId, " which uses URI ", metadataUri);
+                PrivateLog.log("Update for clientId " + LogUtils.s(clientId));
+                LogUtils.l("Update for clientId", clientId, " which uses URI ", metadataUri);
                 uris.add(metadataUri);
             } while (cursor.moveToNext());
         } finally {
@@ -211,14 +213,14 @@ public final class UpdateHandler {
      */
     private static void updateClientsWithMetadataUri(final Context context,
             final boolean updateNow, final String metadataUri) {
-        PrivateLog.log("Update for metadata URI " + Utils.s(metadataUri));
+        PrivateLog.log("Update for metadata URI " + LogUtils.s(metadataUri));
         // Adding a disambiguator to circumvent a bug in older versions of DownloadManager.
         // DownloadManager also stupidly cuts the extension to replace with its own that it
         // gets from the content-type. We need to circumvent this.
         final String disambiguator = "#" + System.currentTimeMillis()
-                + com.android.inputmethod.latin.Utils.getVersionName(context) + ".json";
+                + Utils.getVersionName(context) + ".json";
         final Request metadataRequest = new Request(Uri.parse(metadataUri + disambiguator));
-        Utils.l("Request =", metadataRequest);
+        LogUtils.l("Request =", metadataRequest);
 
         final Resources res = context.getResources();
         // By default, download over roaming is allowed and all network types are allowed too.
@@ -254,7 +256,7 @@ public final class UpdateHandler {
         final long downloadId;
         synchronized (sSharedIdProtector) {
             downloadId = manager.enqueue(metadataRequest);
-            Utils.l("Metadata download requested with id", downloadId);
+            LogUtils.l("Metadata download requested with id", downloadId);
             // If there is already a download in progress, it's been there for a while and
             // there is probably something wrong with download manager. It's best to just
             // overwrite the id and request it again. If the old one happens to finish
@@ -326,11 +328,11 @@ public final class UpdateHandler {
      */
     public static long registerDownloadRequest(final DownloadManager manager, final Request request,
             final SQLiteDatabase db, final String id, final int version) {
-        Utils.l("RegisterDownloadRequest for word list id : ", id, ", version ", version);
+        LogUtils.l("RegisterDownloadRequest for word list id : ", id, ", version ", version);
         final long downloadId;
         synchronized (sSharedIdProtector) {
             downloadId = manager.enqueue(request);
-            Utils.l("Download requested with id", downloadId);
+            LogUtils.l("Download requested with id", downloadId);
             MetadataDbHelper.markEntryAsDownloading(db, id, version, downloadId);
         }
         return downloadId;
@@ -416,7 +418,7 @@ public final class UpdateHandler {
         // Get and check the ID of the file that was downloaded
         final long fileId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, NOT_AN_ID);
         PrivateLog.log("Download finished with id " + fileId);
-        Utils.l("DownloadFinished with id", fileId);
+        LogUtils.l("DownloadFinished with id", fileId);
         if (NOT_AN_ID == fileId) return; // Spurious wake-up: ignore
 
         final DownloadManager manager =
@@ -426,7 +428,7 @@ public final class UpdateHandler {
         final ArrayList<DownloadRecord> recordList =
                 getDownloadRecordsForCompletedDownloadInfo(context, downloadInfo);
         if (null == recordList) return; // It was someone else's download.
-        Utils.l("Received result for download ", fileId);
+        LogUtils.l("Received result for download ", fileId);
 
         // TODO: handle gracefully a null pointer here. This is practically impossible because
         // we come here only when DownloadManager explicitly called us when it ended a
@@ -503,7 +505,7 @@ public final class UpdateHandler {
     private static void publishUpdateCycleCompletedEvent(final Context context) {
         // Even if this is not successful, we have to publish the new state.
         PrivateLog.log("Publishing update cycle completed event");
-        Utils.l("Publishing update cycle completed event");
+        LogUtils.l("Publishing update cycle completed event");
         for (UpdateEventListener listener : linkedCopyOfList(sUpdateEventListeners)) {
             listener.updateCycleCompleted();
         }
@@ -517,12 +519,12 @@ public final class UpdateHandler {
             // {@link handleWordList(Context,InputStream,ContentValues)}.
             // Handle the downloaded file according to its type
             if (downloadRecord.isMetadata()) {
-                Utils.l("Data D/L'd is metadata for", downloadRecord.mClientId);
+                LogUtils.l("Data D/L'd is metadata for", downloadRecord.mClientId);
                 // #handleMetadata() closes its InputStream argument
                 handleMetadata(context, new ParcelFileDescriptor.AutoCloseInputStream(
                         manager.openDownloadedFile(fileId)), downloadRecord.mClientId);
             } else {
-                Utils.l("Data D/L'd is a word list");
+                LogUtils.l("Data D/L'd is a word list");
                 final int wordListStatus = downloadRecord.mAttributes.getAsInteger(
                         MetadataDbHelper.STATUS_COLUMN);
                 if (MetadataDbHelper.STATUS_DOWNLOADING == wordListStatus) {
@@ -582,7 +584,7 @@ public final class UpdateHandler {
      */
     private static void handleMetadata(final Context context, final InputStream stream,
             final String clientId) throws IOException, BadFormatException {
-        Utils.l("Entering handleMetadata");
+        LogUtils.l("Entering handleMetadata");
         final List<WordListMetadata> newMetadata;
         final InputStreamReader reader = new InputStreamReader(stream);
         try {
@@ -592,7 +594,7 @@ public final class UpdateHandler {
             reader.close();
         }
 
-        Utils.l("Downloaded metadata :", newMetadata);
+        LogUtils.l("Downloaded metadata :", newMetadata);
         PrivateLog.log("Downloaded metadata\n" + newMetadata);
 
         final ActionBatch actions = computeUpgradeTo(context, clientId, newMetadata);
@@ -617,7 +619,7 @@ public final class UpdateHandler {
         // DownloadManager does not have the ability to put the file directly where we want
         // it, so we had it download to a temporary place. Now we move it. It will be deleted
         // automatically by DownloadManager.
-        Utils.l("Downloaded a new word list :", downloadRecord.mAttributes.getAsString(
+        LogUtils.l("Downloaded a new word list :", downloadRecord.mAttributes.getAsString(
                 MetadataDbHelper.DESCRIPTION_COLUMN), "for", downloadRecord.mClientId);
         PrivateLog.log("Downloaded a new word list with description : "
                 + downloadRecord.mAttributes.getAsString(MetadataDbHelper.DESCRIPTION_COLUMN)
@@ -676,9 +678,9 @@ public final class UpdateHandler {
      */
     private static void copyFile(final InputStream in, final OutputStream out)
             throws IOException {
-        Utils.l("Copying files");
+        LogUtils.l("Copying files");
         if (!(in instanceof FileInputStream) || !(out instanceof FileOutputStream)) {
-            Utils.l("Not the right types");
+            LogUtils.l("Not the right types");
             copyFileFallback(in, out);
         } else {
             try {
@@ -687,7 +689,7 @@ public final class UpdateHandler {
                 sourceChannel.transferTo(0, Integer.MAX_VALUE, destinationChannel);
             } catch (IOException e) {
                 // Can't work with channels, or something went wrong. Copy by hand.
-                Utils.l("Won't work");
+                LogUtils.l("Won't work");
                 copyFileFallback(in, out);
             }
         }
@@ -702,7 +704,7 @@ public final class UpdateHandler {
      */
     private static void copyFileFallback(final InputStream in, final OutputStream out)
             throws IOException {
-        Utils.l("Falling back to slow copy");
+        LogUtils.l("Falling back to slow copy");
         final byte[] buffer = new byte[FILE_COPY_BUFFER_SIZE];
         for (int readBytes = in.read(buffer); readBytes >= 0; readBytes = in.read(buffer))
             out.write(buffer, 0, readBytes);
@@ -717,10 +719,10 @@ public final class UpdateHandler {
      */
     private static String getTempFileName(final Context context, final String locale)
             throws IOException {
-        Utils.l("Entering openTempFileOutput");
+        LogUtils.l("Entering openTempFileOutput");
         final File dir = context.getFilesDir();
         final File f = File.createTempFile(locale + "___", DICT_FILE_SUFFIX, dir);
-        Utils.l("File name is", f.getName());
+        LogUtils.l("File name is", f.getName());
         return f.getName();
     }
 
@@ -741,7 +743,7 @@ public final class UpdateHandler {
             final String clientId, List<WordListMetadata> from, List<WordListMetadata> to) {
         final ActionBatch actions = new ActionBatch();
         // Upgrade existing word lists
-        Utils.l("Comparing dictionaries");
+        LogUtils.l("Comparing dictionaries");
         final Set<String> wordListIds = new TreeSet<String>();
         // TODO: Can these be null?
         if (null == from) from = new ArrayList<WordListMetadata>();
@@ -756,7 +758,7 @@ public final class UpdateHandler {
             final WordListMetadata newInfo = null == metadataInfo
                     || metadataInfo.mFormatVersion > MAXIMUM_SUPPORTED_FORMAT_VERSION
                             ? null : metadataInfo;
-            Utils.l("Considering updating ", id, "currentInfo =", currentInfo);
+            LogUtils.l("Considering updating ", id, "currentInfo =", currentInfo);
 
             if (null == currentInfo && null == newInfo) {
                 // This may happen if a new word list appeared that we can't handle.
diff --git a/java/src/com/android/inputmethod/event/EventInterpreter.java b/java/src/com/android/inputmethod/event/EventInterpreter.java
index 6efe899bb4a0d3557571b9a4727761487b5766b1..726b9206bdc966b4f5f76bafed937f96b274cb2b 100644
--- a/java/src/com/android/inputmethod/event/EventInterpreter.java
+++ b/java/src/com/android/inputmethod/event/EventInterpreter.java
@@ -19,9 +19,9 @@ package com.android.inputmethod.event;
 import android.util.SparseArray;
 import android.view.KeyEvent;
 
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.ArrayList;
 
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 4ef8653f628b33e28d7bc715b9a4ff7a3243b6a8..09f1145e94b11746d3fda331eade23c1b2dc391d 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -41,7 +41,7 @@ import com.android.inputmethod.keyboard.internal.KeyboardRow;
 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.StringUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index e87ecbc7e3658226bf9ca4e3e0b45d8d813d4af0..fefac96fd70324d3e20df4f6a826edc54f28a3e1 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -21,8 +21,8 @@ import android.util.SparseArray;
 import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
 import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
 import com.android.inputmethod.keyboard.internal.KeyboardParams;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 /**
  * Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 4c5dd25c4106fbf0af9731f84891406c2dc713b2..d00521c5841ef9d713f14cbdba0ed6849a66320d 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -25,8 +25,8 @@ import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.inputmethod.compat.EditorInfoCompatUtils;
-import com.android.inputmethod.latin.InputTypeUtils;
 import com.android.inputmethod.latin.SubtypeLocale;
+import com.android.inputmethod.latin.utils.InputTypeUtils;
 
 import java.util.Arrays;
 import java.util.Locale;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index a074b633460c7a4430d8276e30f9b00e03099dcf..c4f5eb0358b84033660aa3fc20f22e151c2a8e75 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -42,15 +42,15 @@ import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
 import com.android.inputmethod.keyboard.internal.KeyboardParams;
 import com.android.inputmethod.keyboard.internal.KeysCache;
 import com.android.inputmethod.latin.AdditionalSubtype;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.InputAttributes;
-import com.android.inputmethod.latin.InputTypeUtils;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResourceUtils;
 import com.android.inputmethod.latin.SubtypeLocale;
 import com.android.inputmethod.latin.SubtypeSwitcher;
-import com.android.inputmethod.latin.XmlParseUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.InputTypeUtils;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+import com.android.inputmethod.latin.utils.XmlParseUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 7941fcba257ba86813cfd77398e92c641053b046..4cee4cfa61df2341b9a963b1b5a164951bfd83f9 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -32,11 +32,11 @@ import android.view.View;
 
 import com.android.inputmethod.keyboard.internal.KeyDrawParams;
 import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.research.ResearchLogger;
 
 import java.util.HashSet;
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 7f335027f8eea9e011cdb4eaa84665aab1b3057a..8a926d65505273c039b035e87938787ea5e40121 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -58,21 +58,21 @@ import com.android.inputmethod.keyboard.internal.PreviewPlacerView;
 import com.android.inputmethod.keyboard.internal.SlidingKeyInputPreview;
 import com.android.inputmethod.keyboard.internal.TouchScreenRegulator;
 import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.CoordinateUtils;
 import com.android.inputmethod.latin.DebugSettings;
 import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResourceUtils;
 import com.android.inputmethod.latin.Settings;
-import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
-import com.android.inputmethod.latin.StringUtils;
 import com.android.inputmethod.latin.SubtypeLocale;
 import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils;
 import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.CoordinateUtils;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
+import com.android.inputmethod.latin.utils.StringUtils;
+import com.android.inputmethod.latin.utils.Utils.UsabilityStudyLogUtils;
 import com.android.inputmethod.research.ResearchLogger;
 
 import java.util.Locale;
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index ae08a5953d9970c2cadf24c396d1bd37ebe1346b..3b1f6d510bf50e90ce0025482a4216dd15bbf079 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -28,7 +28,7 @@ import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
 import com.android.inputmethod.keyboard.internal.KeyboardParams;
 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.StringUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 public final class MoreKeysKeyboard extends Keyboard {
     private final int mDefaultKeyCoordX;
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index a82fb79bd2a23828aab04a0a65a0393db82c2179..897ad1d1381f3a77c09195592be72c2a82bfeac1 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -23,8 +23,8 @@ import android.view.MotionEvent;
 import android.view.View;
 
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.CoordinateUtils;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.CoordinateUtils;
 
 /**
  * A view that renders a virtual {@link MoreKeysKeyboard}. It handles rendering of keys and
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 958aaf569343cfb8f31b6b44466c9a7083b76726..7b14259a02928ae6e7319dff347e331aa36dc4d8 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -27,13 +27,13 @@ import com.android.inputmethod.keyboard.internal.GestureStroke.GestureStrokePara
 import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints;
 import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints.GestureStrokePreviewParams;
 import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.CoordinateUtils;
 import com.android.inputmethod.latin.InputPointers;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.CoordinateUtils;
 import com.android.inputmethod.research.ResearchLogger;
 
 import java.util.ArrayList;
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 0e86b051de898deb72a49c51c9b6e6fdb2ac4d6e..9b0a33cec99a82f7232538f8d1d1dd6f6af5b5a3 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -22,7 +22,7 @@ import android.util.Log;
 
 import com.android.inputmethod.keyboard.internal.TouchPositionCorrection;
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.JniUtils;
+import com.android.inputmethod.latin.utils.JniUtils;
 
 import java.util.Arrays;
 
diff --git a/java/src/com/android/inputmethod/keyboard/TypefaceUtils.java b/java/src/com/android/inputmethod/keyboard/TypefaceUtils.java
index 6a54e119ceb12f3a43d6a46bffd258434a5c68ea..c3b9520379f959679eca5b53e1d80a6fea0439e3 100644
--- a/java/src/com/android/inputmethod/keyboard/TypefaceUtils.java
+++ b/java/src/com/android/inputmethod/keyboard/TypefaceUtils.java
@@ -21,7 +21,7 @@ import android.graphics.Rect;
 import android.graphics.Typeface;
 import android.util.SparseArray;
 
-import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 public final class TypefaceUtils {
     private TypefaceUtils() {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
index ab810a580ea8a430d8dca704ac4520ed83c14697..9bfddba42326610661cba475d9916e63e337f066 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
@@ -26,9 +26,9 @@ import android.text.TextUtils;
 import android.view.View;
 
 import com.android.inputmethod.keyboard.PointerTracker;
-import com.android.inputmethod.latin.CoordinateUtils;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.utils.CoordinateUtils;
 
 /**
  * The class for single gesture preview text. The class for multiple gesture preview text will be
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
index 70363e6022c75668b7cce67a8d0315f2435d4dc3..f29ade8614ae64ba4eb9351f90b933aa34e0475f 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
@@ -21,8 +21,8 @@ import android.util.Log;
 
 import com.android.inputmethod.latin.InputPointers;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResizableIntArray;
-import com.android.inputmethod.latin.ResourceUtils;
+import com.android.inputmethod.latin.utils.ResizableIntArray;
+import com.android.inputmethod.latin.utils.ResourceUtils;
 
 public class GestureStroke {
     private static final String TAG = GestureStroke.class.getSimpleName();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
index 8deadbf969933a20cc6c72bbdfd16da362634cb2..ecc67dd448b31045b6bebc9dce7d1d3f3a442344 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard.internal;
 import android.content.res.TypedArray;
 
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResizableIntArray;
+import com.android.inputmethod.latin.utils.ResizableIntArray;
 
 public final class GestureStrokeWithPreviewPoints extends GestureStroke {
     public static final int PREVIEW_CAPACITY = 256;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrail.java
index fb69e22e755c533b7296e139731c53f87585282e..aca667919d3dbb5507286a1e5a5dc9f0ddb1fdfc 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrail.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrail.java
@@ -26,7 +26,7 @@ import android.os.SystemClock;
 
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResizableIntArray;
+import com.android.inputmethod.latin.utils.ResizableIntArray;
 
 /*
  * @attr ref R.styleable#MainKeyboardView_gestureTrailFadeoutStartDelay
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java
index 1e4c43ee56322ff31e98b3a3d41e5be8cc8c9c9f..dff5177ce37335cf8341644a454d49eaeb3ac284 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java
@@ -30,8 +30,8 @@ import android.view.View;
 
 import com.android.inputmethod.keyboard.PointerTracker;
 import com.android.inputmethod.keyboard.internal.GestureTrail.Params;
-import com.android.inputmethod.latin.CollectionUtils;
-import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
 
 /**
  * Draw gesture trail preview graphics during gesture.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
index 5dcd842f7a2a5cc91e62aa694556c4e95eebba6a..1716fa049514d51d1fd87a4a34639d300ac85c54 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.keyboard.internal;
 
 import android.graphics.Typeface;
 
-import com.android.inputmethod.latin.ResourceUtils;
+import com.android.inputmethod.latin.utils.ResourceUtils;
 
 public final class KeyDrawParams {
     public Typeface mTypeface;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
index ba449eeb3e0b34e6739c66709402729abe2c02d7..22f5b3dd132073ba0f793a2f26da9a39d9da15fe 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -21,10 +21,10 @@ import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
 
 import android.text.TextUtils;
 
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.StringUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Arrays;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
index a048ad09fded45c021eae82b230bc7c0dc5188fb..6aab3e7b332a059fdbcc11d80a19585faf9c16ea 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
@@ -20,9 +20,9 @@ import android.content.res.TypedArray;
 import android.util.Log;
 import android.util.SparseArray;
 
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.XmlParseUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.XmlParseUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java b/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
index 6ddd2a6fb32ddd702e8bf58f449cbcaf3b39dafe..7a2622cbb2df832ec7154cdea7288d57c84df9a6 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
@@ -21,7 +21,7 @@ import android.graphics.Typeface;
 import android.util.SparseIntArray;
 
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResourceUtils;
+import com.android.inputmethod.latin.utils.ResourceUtils;
 
 public final class KeyVisualAttributes {
     public final Typeface mTypeface;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index be178f51620a8650fe469cd7dfd7a92f586b2ffc..26bbd7de945a9a1e17ed8a8db022ece570c70c8a 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -29,12 +29,12 @@ import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResourceUtils;
-import com.android.inputmethod.latin.StringUtils;
 import com.android.inputmethod.latin.SubtypeLocale;
-import com.android.inputmethod.latin.XmlParseUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
+import com.android.inputmethod.latin.utils.XmlParseUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
index a9e04bccf13f3d5fe224d9f21d918c870de34035..d65aae2dc5d6291579072fe62687b8d1e0e8d18a 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
@@ -16,8 +16,8 @@
 
 package com.android.inputmethod.keyboard.internal;
 
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.HashMap;
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
index 4ac2549c753b9a2a6d31513e83e639a0c7d66feb..4e3f7618bdb22b75e684225250c5d502456a2c6f 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -22,8 +22,8 @@ import android.graphics.drawable.Drawable;
 import android.util.Log;
 import android.util.SparseIntArray;
 
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.HashMap;
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
index 84319eb337079d2f9c5e67c1f5dbbf8006795c81..a57b83ac05f21c7e18701a0904a57ef38651c2a7 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
@@ -20,8 +20,8 @@ import android.util.SparseIntArray;
 
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.TreeSet;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
index 855f65507dba19c28e4f2441cfdadf25ddcf3348..5fe84a7044dc9c3e15b0dbf0d47238286e9b9da4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
@@ -23,7 +23,7 @@ import android.util.Xml;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResourceUtils;
+import com.android.inputmethod.latin.utils.ResourceUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index e1cee427e08a2f7fc04b42b19a7efd1fc2d5177a..370d0cb93ebde30602260cf37a170ddf3e964c6f 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -20,7 +20,7 @@ import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.RecapitalizeStatus;
+import com.android.inputmethod.latin.utils.RecapitalizeStatus;
 
 /**
  * Keyboard state machine.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index 7ec1c9406a1950f2615b240cf9260e81c08e5d4d..467c15ffd430f3682a09d027723c2c41d83a35ab 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -20,7 +20,7 @@ import android.content.Context;
 import android.content.res.Resources;
 
 import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.HashMap;
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
index db154a3911fb9965b17c902de02f9e5e3da64d3b..7c2e3e174e4ed90cb8e4edd3b8dfe086b07d23a3 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
@@ -17,7 +17,7 @@
 package com.android.inputmethod.keyboard.internal;
 
 import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.HashMap;
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
index b38d79f7be1fa7d534ba43bf0ca91c28e055cec0..110936f8fff6fdf6292d2f000fcae04b73a7235e 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard.internal;
 import android.text.TextUtils;
 
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.StringUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.Locale;
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
index 31ef3cd8f3d8026188657200ad9b19c652c58cf7..3dbb7b7e9a25f51b593b4e3a5dc1a9a7cbea6f23 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.keyboard.internal;
 
 import android.util.Log;
 
-import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.ArrayList;
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
index 23761103f5e2fec9c4faf26fe01621322072c21b..3388c5701100b759fada0b39deb75e5118e335e1 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
@@ -24,8 +24,8 @@ import android.graphics.PorterDuffXfermode;
 import android.util.AttributeSet;
 import android.widget.RelativeLayout;
 
-import com.android.inputmethod.latin.CollectionUtils;
-import com.android.inputmethod.latin.CoordinateUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.CoordinateUtils;
 
 import java.util.ArrayList;
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java b/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java
index 33dbbafa3f42a9eb1a5b5f133a3e6bbf3d723961..5c9d36702b7b1912282ea0d57077bee583ce03c2 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/SlidingKeyInputPreview.java
@@ -23,8 +23,8 @@ import android.graphics.Path;
 import android.view.View;
 
 import com.android.inputmethod.keyboard.PointerTracker;
-import com.android.inputmethod.latin.CoordinateUtils;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.CoordinateUtils;
 
 /**
  * Draw rubber band preview graphics during sliding key input.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java b/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java
index d6b1cc6fc4676262fc635957282d6db73629b4b9..fddd9856ef2524b2ad6c5df0c9953b89d3ab2ac3 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/TouchScreenRegulator.java
@@ -23,8 +23,8 @@ import android.view.MotionEvent;
 import com.android.inputmethod.keyboard.MainKeyboardView;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResourceUtils;
 import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.utils.ResourceUtils;
 import com.android.inputmethod.research.ResearchLogger;
 
 public final class TouchScreenRegulator {
diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java b/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
index 85b14d8490f75c82414248011bfc44cf2d6eb316..0bddeb5cef0c71765ae79c56bb3d12e3c1dbe9a9 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
+++ b/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
@@ -25,6 +25,9 @@ import android.os.Build;
 import android.text.TextUtils;
 import android.view.inputmethod.InputMethodSubtype;
 
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
+
 import java.util.ArrayList;
 
 public final class AdditionalSubtype {
diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
index ff5e33949dcfb951a3cfecce916eca6d4a2d83e1..8128e3a178caacbf6722f514fa6c743ecf0b2a66 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
+++ b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
@@ -44,6 +44,9 @@ import android.widget.Spinner;
 import android.widget.SpinnerAdapter;
 import android.widget.Toast;
 
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.IntentUtils;
+
 import java.util.ArrayList;
 import java.util.TreeSet;
 
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index aad129d765889a4344730fcac4d911b18cab0850..05b1a2ee19af5d321d44d29eff4f2a95c033a9cc 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -21,6 +21,10 @@ import android.util.SparseArray;
 
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.utils.AdditionalFeaturesSettingUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.JniUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Arrays;
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index c038db87c2d97c0797314b6ef8ba44314ce0820d..321e806112d4f49bef2112ba9e6b1c5bb65cdb90 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -28,7 +28,10 @@ import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
-import com.android.inputmethod.latin.DictionaryInfoUtils.DictionaryInfo;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
+import com.android.inputmethod.latin.utils.DictionaryInfoUtils.DictionaryInfo;
+import com.android.inputmethod.latin.utils.MetadataFileUriGetter;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 272f36e4f3792b44f68ae200a64a92990ea1e178..d0af59db0820e2df4e77c47483a7c191a30b5267 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -16,10 +16,6 @@
 
 package com.android.inputmethod.latin;
 
-import com.android.inputmethod.latin.define.ProductionFlag;
-import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
-import com.android.inputmethod.latin.makedict.FormatSpec;
-
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
@@ -27,6 +23,13 @@ import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.AssetFileDescriptor;
 import android.util.Log;
 
+import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
+import com.android.inputmethod.latin.makedict.FormatSpec;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -39,7 +42,7 @@ import java.util.Locale;
 /**
  * Helper class to get the address of a mmap'able dictionary file.
  */
-final class BinaryDictionaryGetter {
+final public class BinaryDictionaryGetter {
 
     /**
      * Used for Log actions from this class
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index b9db9a09281eb51c49ad58efaee7fea31af40874..110be9db3ad3c833d8081217b3438e6ae3419362 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -30,6 +30,8 @@ import android.provider.ContactsContract.Contacts;
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.inputmethod.latin.utils.StringUtils;
+
 import java.util.List;
 import java.util.Locale;
 
diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java
index 5969a63dea3483f041fdb15e33d56dc1b71a8207..d1cb39cd947532aa8bf2d3804d7ad5a05b70e033 100644
--- a/java/src/com/android/inputmethod/latin/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/DebugSettings.java
@@ -29,6 +29,7 @@ import android.preference.PreferenceScreen;
 import android.util.Log;
 
 import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.latin.utils.Utils;
 import com.android.inputmethod.research.ResearchLogger;
 
 public final class DebugSettings extends PreferenceFragment
diff --git a/java/src/com/android/inputmethod/latin/DicTraverseSession.java b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
index 534e2116b8679a63f05189464c070ec3cdeee0dc..45b2813188dffa725d7ea4349690163ad381ddde 100644
--- a/java/src/com/android/inputmethod/latin/DicTraverseSession.java
+++ b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
@@ -16,6 +16,8 @@
 
 package com.android.inputmethod.latin;
 
+import com.android.inputmethod.latin.utils.JniUtils;
+
 import java.util.Locale;
 
 public final class DicTraverseSession {
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index ed2b4422355f0d396b503eacf9bfe063c66285a3..d05bb1e5501c4905918ba7d61bfb72a3734796f5 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -16,10 +16,11 @@
 
 package com.android.inputmethod.latin;
 
+import android.util.Log;
+
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-
-import android.util.Log;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.Collection;
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index 4514ec2ec330c8921a9e2c84195d8f1c7de04da5..5b98613a4e15ccd87b574a76b64a9e2c4227c773 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -22,6 +22,8 @@ import android.content.res.Resources;
 import android.util.Log;
 
 import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
 
 import java.io.File;
 import java.util.ArrayList;
diff --git a/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java
index 56096127e7bab4d77ee63ec1bd8f8479f799e941..2dcfdb0b76b338b38bb7cfa6969362f6054c4c67 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java
@@ -17,6 +17,7 @@
 package com.android.inputmethod.latin;
 
 import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
+import com.android.inputmethod.latin.utils.TargetPackageInfoGetterTask;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 887d657e97953effc6db3e6fd472938ccdfe3187..f357e2a1e34c79548b5f0ddd2d0c6c63c54345d4 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -28,6 +28,7 @@ import com.android.inputmethod.latin.makedict.FusionDictionary;
 import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
 import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
 import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.io.File;
 import java.io.FileOutputStream;
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index 0dabdb835716ffdb40acb7ce1e5f9a55176ec036..a67c919b30316be38676cdff074ec64f1e1e72a4 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -22,7 +22,8 @@ import android.util.Log;
 
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.UserHistoryForgettingCurveUtils.ForgettingCurveParams;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils.ForgettingCurveParams;
 
 import java.util.ArrayList;
 import java.util.LinkedList;
diff --git a/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java
index 9f91639a2e18a84ecc2de10e054c1c20f9fdd981..18f4920d925f6bd2898ea22ff7a4e70f42119c3c 100644
--- a/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java
+++ b/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java
@@ -23,6 +23,9 @@ import android.content.DialogInterface.OnClickListener;
 import android.os.Environment;
 
 import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java
index 1f673e9b007cee7493addd9ee64a8b5b78c7ead4..21b103e5a362ca8ca465a34d9e8badf205acbe58 100644
--- a/java/src/com/android/inputmethod/latin/InputAttributes.java
+++ b/java/src/com/android/inputmethod/latin/InputAttributes.java
@@ -20,6 +20,9 @@ import android.text.InputType;
 import android.util.Log;
 import android.view.inputmethod.EditorInfo;
 
+import com.android.inputmethod.latin.utils.InputTypeUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
+
 /**
  * Class to hold attributes of the input field.
  */
diff --git a/java/src/com/android/inputmethod/latin/InputPointers.java b/java/src/com/android/inputmethod/latin/InputPointers.java
index 81c83300091241a635b733dda4490d38fe000912..e96a46e12fd826269134efdc7d283d2cae288f34 100644
--- a/java/src/com/android/inputmethod/latin/InputPointers.java
+++ b/java/src/com/android/inputmethod/latin/InputPointers.java
@@ -17,6 +17,7 @@
 package com.android.inputmethod.latin;
 
 import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.utils.ResizableIntArray;
 
 import android.util.Log;
 
diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java
index 826dc11e75d4a7cab540f4b625254a40aa452378..cdeadc74fb4745e80ff70d7cbe0db689029c1921 100644
--- a/java/src/com/android/inputmethod/latin/LastComposedWord.java
+++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java
@@ -16,6 +16,8 @@
 
 package com.android.inputmethod.latin;
 
+import com.android.inputmethod.latin.utils.StringUtils;
+
 import android.text.TextUtils;
 
 /**
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 52a9b9a6cc89523e62b06a0b7c03e89de4ee239b..6689e50a46f5c303eb91dcc5f9e7d880bb27fbe2 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -76,9 +76,19 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.keyboard.MainKeyboardView;
 import com.android.inputmethod.latin.RichInputConnection.Range;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.Utils.Stats;
 import com.android.inputmethod.latin.define.ProductionFlag;
 import com.android.inputmethod.latin.suggestions.SuggestionStripView;
+import com.android.inputmethod.latin.utils.CapsModeUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.CompletionInfoUtils;
+import com.android.inputmethod.latin.utils.InputTypeUtils;
+import com.android.inputmethod.latin.utils.IntentUtils;
+import com.android.inputmethod.latin.utils.PositionalInfoForUserDictPendingAddition;
+import com.android.inputmethod.latin.utils.RecapitalizeStatus;
+import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
+import com.android.inputmethod.latin.utils.TargetPackageInfoGetterTask;
+import com.android.inputmethod.latin.utils.Utils;
+import com.android.inputmethod.latin.utils.Utils.Stats;
 import com.android.inputmethod.research.ResearchLogger;
 
 import java.io.FileDescriptor;
diff --git a/java/src/com/android/inputmethod/latin/NativeSuggestOptions.java b/java/src/com/android/inputmethod/latin/NativeSuggestOptions.java
index 291551301ff1da8cf7fa7ceefdef420254a47c93..07ccd75e6d613dab79f4ab963949eebe5bc5dbfe 100644
--- a/java/src/com/android/inputmethod/latin/NativeSuggestOptions.java
+++ b/java/src/com/android/inputmethod/latin/NativeSuggestOptions.java
@@ -16,6 +16,8 @@
 
 package com.android.inputmethod.latin;
 
+import com.android.inputmethod.latin.utils.AdditionalFeaturesSettingUtils;
+
 public class NativeSuggestOptions {
     // Need to update suggest_options.h when you add, remove or reorder options.
     private static final int IS_GESTURE = 0;
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 980215de6f67cdcfed20b022e88d33d18a6180b6..be7f93c720103d0e46edc63009642f213f17a24e 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -28,6 +28,9 @@ import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.InputConnection;
 
 import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.utils.CapsModeUtils;
+import com.android.inputmethod.latin.utils.LogUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 import com.android.inputmethod.research.ResearchLogger;
 
 import java.util.Locale;
@@ -105,7 +108,7 @@ public final class RichInputConnection {
                     + "\nActual text = " + reference.length() + " " + reference;
             ((LatinIME)mParent).debugDumpStateAndCrashWithException(context);
         } else {
-            Log.e(TAG, Utils.getStackTrace(2));
+            Log.e(TAG, LogUtils.getStackTrace(2));
             Log.e(TAG, "Exp <> Actual : " + mCurrentCursorPosition + " <> " + et.selectionStart);
         }
     }
@@ -154,7 +157,7 @@ public final class RichInputConnection {
         if (mNestLevel != 1) {
             // TODO: exception instead
             Log.e(TAG, "Batch edit level incorrect : " + mNestLevel);
-            Log.e(TAG, Utils.getStackTrace(4));
+            Log.e(TAG, LogUtils.getStackTrace(4));
         }
     }
 
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index 86f75635d608365854b57dc8d80ca06c5d10a1c2..5b1a2dde4c6cb6a65c700e9943bdaee1a2a9567e 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -28,6 +28,7 @@ import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.Collections;
 import java.util.HashMap;
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index a6149c6ec32ebd199cda5483df92a0e8d687f7c2..084d3308cb248d357e5a9d31dc4a164035b64181 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -23,7 +23,9 @@ import android.content.res.Resources;
 import android.preference.PreferenceManager;
 import android.util.Log;
 
-import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.LocaleUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.ResourceUtils;
 
 import java.util.HashMap;
 import java.util.Locale;
diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java
index 8017ce16192f46b36e3ac970165470e1807b6691..46fa1913cb579fb5a04154ba2d91a718693c5592 100644
--- a/java/src/com/android/inputmethod/latin/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java
@@ -35,16 +35,19 @@ import android.preference.PreferenceScreen;
 import android.util.Log;
 import android.view.inputmethod.InputMethodSubtype;
 
-import java.util.TreeSet;
-
 import com.android.inputmethod.dictionarypack.DictionarySettingsActivity;
 import com.android.inputmethod.latin.define.ProductionFlag;
 import com.android.inputmethod.latin.setup.LauncherIconVisibilityManager;
 import com.android.inputmethod.latin.userdictionary.UserDictionaryList;
 import com.android.inputmethod.latin.userdictionary.UserDictionarySettings;
+import com.android.inputmethod.latin.utils.AdditionalFeaturesSettingUtils;
+import com.android.inputmethod.latin.utils.FeedbackUtils;
+import com.android.inputmethod.latin.utils.Utils;
 import com.android.inputmethod.research.ResearchLogger;
 import com.android.inputmethodcommon.InputMethodSettingsFragment;
 
+import java.util.TreeSet;
+
 public final class SettingsFragment extends InputMethodSettingsFragment
         implements SharedPreferences.OnSharedPreferenceChangeListener {
     private static final String TAG = SettingsFragment.class.getSimpleName();
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 09102447f041e2c6b3d9fed4146b7675054a9cbb..8eadf73b22abd13f74891449572a0e4fef5657b2 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -24,6 +24,10 @@ import android.view.inputmethod.EditorInfo;
 
 import com.android.inputmethod.keyboard.internal.KeySpecParser;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.utils.AdditionalFeaturesSettingUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.InputTypeUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Arrays;
diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
index 4d88ecc0c81b9c1c6630ad5e404692120e76c628..3f94aca3ab4ccf9893cb7e928637db85e60d6d6b 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
@@ -25,7 +25,11 @@ import android.os.Build;
 import android.util.Log;
 import android.view.inputmethod.InputMethodSubtype;
 
-import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.LogUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.HashMap;
 import java.util.Locale;
@@ -238,7 +242,7 @@ public final class SubtypeLocale {
                             + " nameResId=" + subtype.getNameResId()
                             + " locale=" + subtype.getLocale()
                             + " extra=" + subtype.getExtraValue()
-                            + "\n" + Utils.getStackTrace());
+                            + "\n" + LogUtils.getStackTrace());
                     return "";
                 }
             }
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index e783e6d514f6d82cce9701f08a22760bccac8272..8b31f4e998cd3646caa3cc31ecb6256c1cdfae07 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -22,6 +22,9 @@ import android.text.TextUtils;
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.utils.BoundedTreeSet;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Comparator;
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 7a16595a7a999095875085df931ffd5755d6ae8a..5b47dda0d1ea999dc2acac200169e3ae9842fedc 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -19,6 +19,9 @@ package com.android.inputmethod.latin;
 import android.text.TextUtils;
 import android.view.inputmethod.CompletionInfo;
 
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index 90f92972a7b42363341852cc4b68c417b1eccbbc..ba84c1ad36682eb05aa30952a70cb61df7184af8 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -28,6 +28,7 @@ import android.provider.UserDictionary.Words;
 import android.text.TextUtils;
 
 import com.android.inputmethod.compat.UserDictionaryCompatUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils;
 
 import java.util.Arrays;
 import java.util.Locale;
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
index ab5724724cdb6331774f06d7083e0b8b1dfc86c7..ca2d8840b3b7f01a3252669df8e8d83792725e3a 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
@@ -24,10 +24,13 @@ import android.util.Log;
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.UserHistoryDictIOUtils.BigramDictionaryInterface;
-import com.android.inputmethod.latin.UserHistoryDictIOUtils.OnAddWordListener;
-import com.android.inputmethod.latin.UserHistoryForgettingCurveUtils.ForgettingCurveParams;
 import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils;
+import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.BigramDictionaryInterface;
+import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.OnAddWordListener;
+import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils;
+import com.android.inputmethod.latin.utils.UserHistoryForgettingCurveUtils.ForgettingCurveParams;
 
 import java.io.File;
 import java.io.FileInputStream;
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionaryBigramList.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionaryBigramList.java
index 316f096033b2e7f0543f4c8878b4b7362753f91c..28941c4a185892efc8e9d7454bc74b9c1be35bf8 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictionaryBigramList.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionaryBigramList.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin;
 import android.util.Log;
 
 import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.HashMap;
 import java.util.Set;
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
index 13fa9d9c85ac7ca1acee197b1a7ad25beeb83e0d..978c0642d5a48947d560f6fbfd6e756fefea5185 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
@@ -35,10 +35,10 @@ import android.widget.VideoView;
 
 import com.android.inputmethod.compat.TextViewCompatUtils;
 import com.android.inputmethod.compat.ViewCompatUtils;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.SettingsActivity;
-import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
 
 import java.util.ArrayList;
 
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 13fcaf48a473882f97657f6df10ac0f29fa441f2..692e7392c24ca43adb0d0d4173c694847fb09bb2 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -25,17 +25,17 @@ import android.view.textservice.SuggestionsInfo;
 
 import com.android.inputmethod.keyboard.KeyboardLayoutSet;
 import com.android.inputmethod.latin.BinaryDictionary;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.ContactsBinaryDictionary;
 import com.android.inputmethod.latin.Dictionary;
 import com.android.inputmethod.latin.DictionaryCollection;
 import com.android.inputmethod.latin.DictionaryFactory;
-import com.android.inputmethod.latin.LocaleUtils;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.StringUtils;
 import com.android.inputmethod.latin.SynchronouslyLoadedContactsBinaryDictionary;
 import com.android.inputmethod.latin.SynchronouslyLoadedUserBinaryDictionary;
 import com.android.inputmethod.latin.UserBinaryDictionary;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
index 9a1114f7f746ff00c91035d42864181b57a1d1c0..ddda52d710213a8f936d30ac2f43956ab8bca25d 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
@@ -23,7 +23,7 @@ import android.view.textservice.SentenceSuggestionsInfo;
 import android.view.textservice.SuggestionsInfo;
 import android.view.textservice.TextInfo;
 
-import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.ArrayList;
 
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 16e9fb77e63455a83f256ae944b14eb3ee5e9a5f..6719e98daf8a7e818e146215ba9ee669b1eb6924 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -30,11 +30,11 @@ import android.view.textservice.TextInfo;
 import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.LocaleUtils;
-import com.android.inputmethod.latin.StringUtils;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.WordComposer;
 import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer;
+import com.android.inputmethod.latin.utils.LocaleUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Locale;
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
index a20e09ee850b77ca7c8a9ec0e41abd3419b0fac6..ac8f68781ec0edf2f596ae2688fa333be10fc7af 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
@@ -19,10 +19,10 @@ package com.android.inputmethod.latin.spellcheck;
 import android.util.Log;
 
 import com.android.inputmethod.keyboard.ProximityInfo;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Dictionary;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.WordComposer;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.Locale;
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java
index 5ce9d8e477ddf8e801738d061af92790fa425b81..da58126038fa771101207257d8b8613c36344b7b 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java
@@ -21,7 +21,7 @@ import android.preference.PreferenceFragment;
 import android.preference.PreferenceScreen;
 
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.utils.Utils;
 
 /**
  * Preference screen.
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index 322ae5b0fe35d64edb1a43c53b5c86db3416959d..2218b3bc60600ea6804283784f2043e1749315f9 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -31,7 +31,7 @@ import com.android.inputmethod.keyboard.internal.KeyboardParams;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.utils.Utils;
 
 public final class MoreSuggestions extends Keyboard {
     public static final int SUGGESTION_CODE_BASE = 1024;
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 916f483b98a6dfa500a38e75bc173995d5a0404a..b6caf9b7b90c14e07a7fb6631628fe742f5d356a 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -49,9 +49,9 @@ import com.android.inputmethod.keyboard.ViewLayoutUtils;
 import com.android.inputmethod.latin.AutoCorrection;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResourceUtils;
 import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+import com.android.inputmethod.latin.utils.Utils;
 
 import java.util.ArrayList;
 
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 2284a4607053e0c823c113eeb782661b98a591a1..fcebdd457c881c80efbcf5dbe785536732e301c3 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -34,7 +34,6 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher;
 import com.android.inputmethod.keyboard.MainKeyboardView;
 import com.android.inputmethod.keyboard.MoreKeysPanel;
 import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
@@ -42,6 +41,7 @@ import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.define.ProductionFlag;
 import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionsListener;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.research.ResearchLogger;
 
 import java.util.ArrayList;
diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java
index 89ec7466e0fe863f2bcf9a80a38e5237bf002538..dad72963dad2f007a403cc80c8cfa439a0e8f9b7 100644
--- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java
+++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java
@@ -16,10 +16,6 @@
 
 package com.android.inputmethod.latin.userdictionary;
 
-import com.android.inputmethod.compat.UserDictionaryCompatUtils;
-import com.android.inputmethod.latin.LocaleUtils;
-import com.android.inputmethod.latin.R;
-
 import android.app.Activity;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -30,6 +26,10 @@ import android.text.TextUtils;
 import android.view.View;
 import android.widget.EditText;
 
+import com.android.inputmethod.compat.UserDictionaryCompatUtils;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.LocaleUtils;
+
 import java.util.ArrayList;
 import java.util.Locale;
 import java.util.TreeSet;
diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java
index 6e64882b69c9bc0e61c9f7917d1746171105712c..e7cf0d3af397a59aa2de4f1ed5a0df1b04619f02 100644
--- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java
+++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java
@@ -16,9 +16,6 @@
 
 package com.android.inputmethod.latin.userdictionary;
 
-import com.android.inputmethod.latin.LocaleUtils;
-import com.android.inputmethod.latin.R;
-
 import android.app.Activity;
 import android.content.Intent;
 import android.database.Cursor;
@@ -29,6 +26,9 @@ import android.preference.PreferenceGroup;
 import android.provider.UserDictionary;
 import android.text.TextUtils;
 
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.LocaleUtils;
+
 import java.util.Locale;
 import java.util.TreeSet;
 
diff --git a/java/src/com/android/inputmethod/latin/AdditionalFeaturesSettingUtils.java b/java/src/com/android/inputmethod/latin/utils/AdditionalFeaturesSettingUtils.java
similarity index 94%
rename from java/src/com/android/inputmethod/latin/AdditionalFeaturesSettingUtils.java
rename to java/src/com/android/inputmethod/latin/utils/AdditionalFeaturesSettingUtils.java
index 0fdaea50ce70b2e98e77bbbd066a3b11819f5364..18dfb3dbaaa0b7a49262d052a9ccccb5fc66bcaa 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalFeaturesSettingUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/AdditionalFeaturesSettingUtils.java
@@ -14,13 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
-
-import com.android.inputmethodcommon.InputMethodSettingsFragment;
+package com.android.inputmethod.latin.utils;
 
 import android.content.Context;
 import android.content.SharedPreferences;
 
+import com.android.inputmethod.latin.Settings;
+import com.android.inputmethodcommon.InputMethodSettingsFragment;
+
 /**
  * Utility class for managing additional features settings.
  */
diff --git a/java/src/com/android/inputmethod/latin/BoundedTreeSet.java b/java/src/com/android/inputmethod/latin/utils/BoundedTreeSet.java
similarity index 97%
rename from java/src/com/android/inputmethod/latin/BoundedTreeSet.java
rename to java/src/com/android/inputmethod/latin/utils/BoundedTreeSet.java
index 489a74ef16346629953117d9d6c92bb29a9233e7..ae1fd3f796bbda7d879e7e195eea85766520e2e5 100644
--- a/java/src/com/android/inputmethod/latin/BoundedTreeSet.java
+++ b/java/src/com/android/inputmethod/latin/utils/BoundedTreeSet.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 
diff --git a/java/src/com/android/inputmethod/latin/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
similarity index 98%
rename from java/src/com/android/inputmethod/latin/CapsModeUtils.java
rename to java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
index 4b8d1ac11a443a7760fe66efaffec9a17cb4026c..2f91c5743a094753f6f77f089acd17e4c017ca27 100644
--- a/java/src/com/android/inputmethod/latin/CapsModeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.text.InputType;
 import android.text.TextUtils;
 
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.WordComposer;
+
 import java.util.Locale;
 
 public final class CapsModeUtils {
diff --git a/java/src/com/android/inputmethod/latin/CollectionUtils.java b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
similarity index 98%
rename from java/src/com/android/inputmethod/latin/CollectionUtils.java
rename to java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
index a8623cc6332ebe754dd358e3757c7ecbd2ea3429..98f0d8b6863403ef064c0fc9dcd6bc6c0e926d0a 100644
--- a/java/src/com/android/inputmethod/latin/CollectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.util.SparseArray;
 
diff --git a/java/src/com/android/inputmethod/latin/CompletionInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/CompletionInfoUtils.java
similarity index 96%
rename from java/src/com/android/inputmethod/latin/CompletionInfoUtils.java
rename to java/src/com/android/inputmethod/latin/utils/CompletionInfoUtils.java
index 792a446c97fad85b1803194487ea80a3ef517332..5ccf0e0791460f307c4fe73cd122b7075a64b9e1 100644
--- a/java/src/com/android/inputmethod/latin/CompletionInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CompletionInfoUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.text.TextUtils;
 import android.view.inputmethod.CompletionInfo;
diff --git a/java/src/com/android/inputmethod/latin/CoordinateUtils.java b/java/src/com/android/inputmethod/latin/utils/CoordinateUtils.java
similarity index 97%
rename from java/src/com/android/inputmethod/latin/CoordinateUtils.java
rename to java/src/com/android/inputmethod/latin/utils/CoordinateUtils.java
index af270e1e4b810941e665f719f48a7ebf84f96faf..72f2cd2d9e26070bda944aec85c577afb4eb22ee 100644
--- a/java/src/com/android/inputmethod/latin/CoordinateUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CoordinateUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 public final class CoordinateUtils {
     private static final int INDEX_X = 0;
diff --git a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
index 999c2f0de18f2943b7630ff9298a70710ddd90b9..159ebb1b9d6ce66d298bd0bd65cee338033a329e 100644
--- a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
@@ -17,7 +17,6 @@
 package com.android.inputmethod.latin.utils;
 
 import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.CollectionUtils;
 
 import java.util.ArrayList;
 
diff --git a/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
similarity index 98%
rename from java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java
rename to java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
index 9d478491a59c666b3c38f1f3ea3bf30eee69f58a..b3d37d78cd6501b0a79dafe0455455ac2dd01a70 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.content.ContentValues;
 import android.content.Context;
@@ -23,6 +23,9 @@ import android.content.res.Resources;
 import android.text.format.DateUtils;
 import android.util.Log;
 
+import com.android.inputmethod.latin.AssetFileAddress;
+import com.android.inputmethod.latin.BinaryDictionaryGetter;
+import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.makedict.BinaryDictIOUtils;
 import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
 import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
@@ -38,9 +41,7 @@ import java.util.Locale;
  */
 public class DictionaryInfoUtils {
     private static final String TAG = DictionaryInfoUtils.class.getSimpleName();
-    // This class must be located in the same package as LatinIME.java.
-    private static final String RESOURCE_PACKAGE_NAME =
-            DictionaryInfoUtils.class.getPackage().getName();
+    private static final String RESOURCE_PACKAGE_NAME = R.class.getPackage().getName();
     private static final String DEFAULT_MAIN_DICT = "main";
     private static final String MAIN_DICT_PREFIX = "main_";
     // 6 digits - unicode is limited to 21 bits
diff --git a/java/src/com/android/inputmethod/latin/FeedbackUtils.java b/java/src/com/android/inputmethod/latin/utils/FeedbackUtils.java
similarity index 95%
rename from java/src/com/android/inputmethod/latin/FeedbackUtils.java
rename to java/src/com/android/inputmethod/latin/utils/FeedbackUtils.java
index 0582763fefa99bd827b561ea0e4bc8b972576664..ec7eaf4a0e046f710213ad067cca29dd513e1469 100644
--- a/java/src/com/android/inputmethod/latin/FeedbackUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/FeedbackUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.content.Context;
 import android.content.Intent;
diff --git a/java/src/com/android/inputmethod/latin/InputTypeUtils.java b/java/src/com/android/inputmethod/latin/utils/InputTypeUtils.java
similarity index 99%
rename from java/src/com/android/inputmethod/latin/InputTypeUtils.java
rename to java/src/com/android/inputmethod/latin/utils/InputTypeUtils.java
index 46194f6e4711d30aa197266990c4c948885adc2c..19cd34011950b0ea3a6afd081f3ca328fb051a3a 100644
--- a/java/src/com/android/inputmethod/latin/InputTypeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/InputTypeUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.text.InputType;
 import android.view.inputmethod.EditorInfo;
diff --git a/java/src/com/android/inputmethod/latin/IntentUtils.java b/java/src/com/android/inputmethod/latin/utils/IntentUtils.java
similarity index 97%
rename from java/src/com/android/inputmethod/latin/IntentUtils.java
rename to java/src/com/android/inputmethod/latin/utils/IntentUtils.java
index d175af5040986ea31af3b5d2d56183884eacfe62..ea016811772568d71c417773908c691fa9c5c206 100644
--- a/java/src/com/android/inputmethod/latin/IntentUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/IntentUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.content.Intent;
 import android.text.TextUtils;
diff --git a/java/src/com/android/inputmethod/latin/JniUtils.java b/java/src/com/android/inputmethod/latin/utils/JniUtils.java
similarity index 96%
rename from java/src/com/android/inputmethod/latin/JniUtils.java
rename to java/src/com/android/inputmethod/latin/utils/JniUtils.java
index 8aedee576e56274165ce637d6591c8a228ec79a1..e7fdafaebd66c174f201e5bd9f7c0a7b6426a8ef 100644
--- a/java/src/com/android/inputmethod/latin/JniUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/JniUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.util.Log;
 
diff --git a/java/src/com/android/inputmethod/latin/LocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java
similarity index 99%
rename from java/src/com/android/inputmethod/latin/LocaleUtils.java
rename to java/src/com/android/inputmethod/latin/utils/LocaleUtils.java
index a1e40502ee4e17f83f24aa6f608d9244d1fa4347..58d062bbd885464681a940534898c1eec2adcacf 100644
--- a/java/src/com/android/inputmethod/latin/LocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -166,6 +166,7 @@ public final class LocaleUtils {
 
     static final Object sLockForRunInLocale = new Object();
 
+    // TODO: Make this an external class
     public abstract static class RunInLocale<T> {
         protected abstract T job(Resources res);
 
diff --git a/java/src/com/android/inputmethod/dictionarypack/Utils.java b/java/src/com/android/inputmethod/latin/utils/LogUtils.java
similarity index 76%
rename from java/src/com/android/inputmethod/dictionarypack/Utils.java
rename to java/src/com/android/inputmethod/latin/utils/LogUtils.java
index c4a42dbbffe1cc4642229631a6f9b00088084c56..a0d2e04954cdc1fb824fa66df9793a893e9c938c 100644
--- a/java/src/com/android/inputmethod/dictionarypack/Utils.java
+++ b/java/src/com/android/inputmethod/latin/utils/LogUtils.java
@@ -14,16 +14,18 @@
  * the License.
  */
 
-package com.android.inputmethod.dictionarypack;
+package com.android.inputmethod.latin.utils;
 
 import android.util.Log;
 
+import com.android.inputmethod.latin.LatinImeLogger;
+
 /**
- * A class for various utility methods, especially debugging.
+ * A class for logging and debugging utility methods.
  */
-public final class Utils {
-    private final static String TAG = Utils.class.getSimpleName() + ":DEBUG --";
-    private final static boolean DEBUG = DictionaryProvider.DEBUG;
+public final class LogUtils {
+    private final static String TAG = LogUtils.class.getSimpleName();
+    private final static boolean sDBG = LatinImeLogger.sDBG;
 
     /**
      * Calls .toString() on its non-null argument or returns "null"
@@ -39,13 +41,22 @@ public final class Utils {
      * @return a readable, carriage-return-separated string for the current stack trace.
      */
     public static String getStackTrace() {
+        return getStackTrace(Integer.MAX_VALUE - 1);
+    }
+
+    /**
+     * Get the string representation of the current stack trace, for debugging purposes.
+     * @param limit the maximum number of stack frames to be returned.
+     * @return a readable, carriage-return-separated string for the current stack trace.
+     */
+    public static String getStackTrace(final int limit) {
         final StringBuilder sb = new StringBuilder();
         try {
             throw new RuntimeException();
-        } catch (RuntimeException e) {
-            StackTraceElement[] frames = e.getStackTrace();
+        } catch (final RuntimeException e) {
+            final StackTraceElement[] frames = e.getStackTrace();
             // Start at 1 because the first frame is here and we don't care about it
-            for (int j = 1; j < frames.length; ++j) {
+            for (int j = 1; j < frames.length && j < limit + 1; ++j) {
                 sb.append(frames[j].toString() + "\n");
             }
         }
@@ -75,7 +86,7 @@ public final class Utils {
      * @param args the stuff to send to the log
      */
     public static void l(final Object... args) {
-        if (!DEBUG) return;
+        if (!sDBG) return;
         final StringBuilder sb = new StringBuilder();
         for (final Object o : args) {
             sb.append(s(o).toString());
@@ -92,7 +103,7 @@ public final class Utils {
      * @param args the stuff to send to the log
      */
     public static void r(final Object... args) {
-        if (!DEBUG) return;
+        if (!sDBG) return;
         final StringBuilder sb = new StringBuilder("\u001B[31m");
         for (final Object o : args) {
             sb.append(s(o).toString());
diff --git a/java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java b/java/src/com/android/inputmethod/latin/utils/MetadataFileUriGetter.java
similarity index 92%
rename from java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java
rename to java/src/com/android/inputmethod/latin/utils/MetadataFileUriGetter.java
index a98ecc7b6be289e7a23687d78f4a4930f1190e91..9ad319da6b391e485d5611fba9577a2ab9c5716a 100644
--- a/java/src/com/android/inputmethod/latin/MetadataFileUriGetter.java
+++ b/java/src/com/android/inputmethod/latin/utils/MetadataFileUriGetter.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
+
+import com.android.inputmethod.latin.R;
 
 import android.content.Context;
 
diff --git a/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java b/java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java
similarity index 98%
rename from java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java
rename to java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java
index a8800007a68b849675481f5205d7531834b97bf1..1fc7eccc6c16463c59c3f6fb552b0ab157797d2a 100644
--- a/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java
+++ b/java/src/com/android/inputmethod/latin/utils/PositionalInfoForUserDictPendingAddition.java
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.view.inputmethod.EditorInfo;
 
+import com.android.inputmethod.latin.RichInputConnection;
+
 import java.util.Locale;
 
 /**
diff --git a/java/src/com/android/inputmethod/latin/RecapitalizeStatus.java b/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
similarity index 98%
rename from java/src/com/android/inputmethod/latin/RecapitalizeStatus.java
rename to java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
index b9d7dcf7877922ed13d18a6a4efb92c5a2dead45..0f5cd80dbfd9db8c4e179e4245f78976ac1722f3 100644
--- a/java/src/com/android/inputmethod/latin/RecapitalizeStatus.java
+++ b/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
@@ -14,9 +14,7 @@
  * the License.
  */
 
-package com.android.inputmethod.latin;
-
-import com.android.inputmethod.latin.StringUtils;
+package com.android.inputmethod.latin.utils;
 
 import java.util.Locale;
 
diff --git a/java/src/com/android/inputmethod/latin/ResizableIntArray.java b/java/src/com/android/inputmethod/latin/utils/ResizableIntArray.java
similarity index 99%
rename from java/src/com/android/inputmethod/latin/ResizableIntArray.java
rename to java/src/com/android/inputmethod/latin/utils/ResizableIntArray.java
index 691f0602a912a04e7a575b4e5c500769496117b8..4c7739a7ab8e7db705c5271c83349ba1b82ab443 100644
--- a/java/src/com/android/inputmethod/latin/ResizableIntArray.java
+++ b/java/src/com/android/inputmethod/latin/utils/ResizableIntArray.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import java.util.Arrays;
 
diff --git a/java/src/com/android/inputmethod/latin/ResourceUtils.java b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
similarity index 99%
rename from java/src/com/android/inputmethod/latin/ResourceUtils.java
rename to java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
index 0eb8b4f090ad43ea1fbb8eab1460d65384ee3c8d..ffec57548af8b28ddfd493dd93cb92d9c92483bf 100644
--- a/java/src/com/android/inputmethod/latin/ResourceUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.content.res.Resources;
 import android.content.res.TypedArray;
diff --git a/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java b/java/src/com/android/inputmethod/latin/utils/StaticInnerHandlerWrapper.java
similarity index 96%
rename from java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java
rename to java/src/com/android/inputmethod/latin/utils/StaticInnerHandlerWrapper.java
index e50af4d2d5f1083b90dc537ee2f5d37e3be3a11e..44e5d17b46ed2437b06f448fe22aaacb36a17082 100644
--- a/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java
+++ b/java/src/com/android/inputmethod/latin/utils/StaticInnerHandlerWrapper.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.os.Handler;
 import android.os.Looper;
diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
similarity index 99%
rename from java/src/com/android/inputmethod/latin/StringUtils.java
rename to java/src/com/android/inputmethod/latin/utils/StringUtils.java
index c2fd4fb32c571f9751fe5e18fd78151df769690f..7406d855a3cbc50b1bf34295bdb34bf13076f473 100644
--- a/java/src/com/android/inputmethod/latin/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.text.TextUtils;
 
+import com.android.inputmethod.latin.Constants;
+
 import java.util.ArrayList;
 import java.util.Locale;
 
diff --git a/java/src/com/android/inputmethod/latin/TargetPackageInfoGetterTask.java b/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java
similarity index 98%
rename from java/src/com/android/inputmethod/latin/TargetPackageInfoGetterTask.java
rename to java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java
index 947b0c58687b49e8440acf8c8aa25ea2cc33195d..afbe2ecad9f3d03004844626382b261176b5664c 100644
--- a/java/src/com/android/inputmethod/latin/TargetPackageInfoGetterTask.java
+++ b/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.content.Context;
 import android.content.pm.PackageInfo;
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java
similarity index 98%
rename from java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
rename to java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java
index 5233ed7d380a76563f03306ce707adfa717fa1c4..32eb0b2c52f0e1c34b49878910625164c873b8b5 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtils.java
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.util.Log;
 
 import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.UserHistoryDictionaryBigramList;
 import com.android.inputmethod.latin.makedict.BinaryDictIOUtils;
 import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
 import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryForgettingCurveUtils.java b/java/src/com/android/inputmethod/latin/utils/UserHistoryForgettingCurveUtils.java
similarity index 99%
rename from java/src/com/android/inputmethod/latin/UserHistoryForgettingCurveUtils.java
rename to java/src/com/android/inputmethod/latin/utils/UserHistoryForgettingCurveUtils.java
index 9053d709bccf4943a897bd40e76a0b9c72d7a111..9f842f9760ce32b122dbb5b307954db03381f6d9 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryForgettingCurveUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/UserHistoryForgettingCurveUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.text.format.DateUtils;
 import android.util.Log;
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/utils/Utils.java
similarity index 95%
rename from java/src/com/android/inputmethod/latin/Utils.java
rename to java/src/com/android/inputmethod/latin/utils/Utils.java
index 949720fda7649975a572d85646ef57d7246988d6..390d306c8af028f0c2167e836fef6274e3b932aa 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/utils/Utils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.app.Activity;
 import android.content.ComponentName;
@@ -35,7 +35,12 @@ import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.WordComposer;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -50,6 +55,7 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
 
+// TODO: Come up with a more descriptive class name
 public final class Utils {
     private static final String TAG = Utils.class.getSimpleName();
 
@@ -71,15 +77,17 @@ public final class Utils {
         }
     }
 
-    /* package */ static final class RingCharBuffer {
+    // TODO: Make this an external class
+    public /* for test */ static final class RingCharBuffer {
+        public /* for test */ static final int BUFSIZE = 20;
+        public /* for test */ int mLength = 0;
+
         private static RingCharBuffer sRingCharBuffer = new RingCharBuffer();
         private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';
         private static final int INVALID_COORDINATE = -2;
-        /* package */ static final int BUFSIZE = 20;
         private InputMethodService mContext;
         private boolean mEnabled = false;
         private int mEnd = 0;
-        /* package */ int mLength = 0;
         private char[] mCharBuf = new char[BUFSIZE];
         private int[] mXBuf = new int[BUFSIZE];
         private int[] mYBuf = new int[BUFSIZE];
@@ -184,25 +192,7 @@ public final class Utils {
         }
     }
 
-    // Get the current stack trace
-    public static String getStackTrace(final int limit) {
-        final StringBuilder sb = new StringBuilder();
-        try {
-            throw new RuntimeException();
-        } catch (final RuntimeException e) {
-            final StackTraceElement[] frames = e.getStackTrace();
-            // Start at 1 because the first frame is here and we don't care about it
-            for (int j = 1; j < frames.length && j < limit + 1; ++j) {
-                sb.append(frames[j].toString() + "\n");
-            }
-        }
-        return sb.toString();
-    }
-
-    public static String getStackTrace() {
-        return getStackTrace(Integer.MAX_VALUE - 1);
-    }
-
+    // TODO: Make this an external class
     public static final class UsabilityStudyLogUtils {
         // TODO: remove code duplication with ResearchLog class
         private static final String USABILITY_TAG = UsabilityStudyLogUtils.class.getSimpleName();
@@ -416,6 +406,7 @@ public final class Utils {
         }
     }
 
+    // TODO: Make this an external class
     public static final class Stats {
         public static void onNonSeparator(final char code, final int x, final int y) {
             RingCharBuffer.getInstance().push(code, x, y);
@@ -495,6 +486,10 @@ public final class Utils {
         return 0;
     }
 
+    /**
+     * A utility method to get the application's PackageInfo.versionName
+     * @return the application's PackageInfo.versionName
+     */
     public static String getVersionName(final Context context) {
         try {
             if (context == null) {
diff --git a/java/src/com/android/inputmethod/latin/XmlParseUtils.java b/java/src/com/android/inputmethod/latin/utils/XmlParseUtils.java
similarity index 98%
rename from java/src/com/android/inputmethod/latin/XmlParseUtils.java
rename to java/src/com/android/inputmethod/latin/utils/XmlParseUtils.java
index 48e5ed30a739ebb1f924377c7ee8dfd684429535..bdad1665256c5b585965d02889eae4e9c3a11049 100644
--- a/java/src/com/android/inputmethod/latin/XmlParseUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/XmlParseUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.content.res.TypedArray;
 
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index 6029ba963d1d45c5b5ba1180ad16bd50823aa1e9..3abeb76a014068444599c86557fccee4ad754384 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -61,7 +61,6 @@ import com.android.inputmethod.keyboard.KeyboardView;
 import com.android.inputmethod.keyboard.MainKeyboardView;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.InputTypeUtils;
 import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.RichInputConnection;
@@ -69,6 +68,7 @@ import com.android.inputmethod.latin.RichInputConnection.Range;
 import com.android.inputmethod.latin.Suggest;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.utils.InputTypeUtils;
 import com.android.inputmethod.research.MotionEventReader.ReplayData;
 
 import java.io.File;
diff --git a/tests/src/com/android/inputmethod/keyboard/SpacebarTextTests.java b/tests/src/com/android/inputmethod/keyboard/SpacebarTextTests.java
index 850af94f7b871bfee3d403a0cd791f1384d496d8..057a0c0bfe5ab49887158fabae0b41411efa39a6 100644
--- a/tests/src/com/android/inputmethod/keyboard/SpacebarTextTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/SpacebarTextTests.java
@@ -23,11 +23,11 @@ import android.test.suitebuilder.annotation.SmallTest;
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.inputmethod.latin.AdditionalSubtype;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.RichInputMethodManager;
-import com.android.inputmethod.latin.StringUtils;
 import com.android.inputmethod.latin.SubtypeLocale;
-import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Locale;
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserSplitTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserSplitTests.java
index eea1efc4945a28fa8c0b078a39f1a6b8d849f533..f04c7e9530262d61fd59ba5021f7428fcfe62fda 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserSplitTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserSplitTests.java
@@ -22,8 +22,8 @@ import android.content.res.Resources;
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 
-import com.android.inputmethod.latin.CollectionUtils;
-import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
index b55158d3e685308b52b9e5ee5e306140e99f50ea..2d9dc5e3b668edeaf77de22aa8216459fb65a308 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
@@ -26,7 +26,7 @@ import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
 
 import java.util.Arrays;
 import java.util.Locale;
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
index 8506e16f2b46c502f2222f789c3d997370c3a3f5..db39976519adce12722e22fb973c322674d79ef2 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard.internal;
 import android.text.TextUtils;
 
 import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.RecapitalizeStatus;
+import com.android.inputmethod.latin.utils.RecapitalizeStatus;
 
 public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
     public interface MockConstants {
diff --git a/tests/src/com/android/inputmethod/latin/InputPointersTests.java b/tests/src/com/android/inputmethod/latin/InputPointersTests.java
index 3015829798164160d78b7698f7e3b6e2f8e238e9..f0b6acc75b100c49ea30ea110fc972b98a6d8b17 100644
--- a/tests/src/com/android/inputmethod/latin/InputPointersTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputPointersTests.java
@@ -19,6 +19,8 @@ package com.android.inputmethod.latin;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.inputmethod.latin.utils.ResizableIntArray;
+
 import java.util.Arrays;
 
 @SmallTest
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index aec4aaca12ba9923791acd842679826cd02cddbe..c765ce5eef15b49fe601dd764d303a678b2a88e0 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -36,6 +36,7 @@ import android.widget.FrameLayout;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.utils.LocaleUtils;
 
 import java.util.Locale;
 
diff --git a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
index abfaf3062e5553ca17ca67dd43ccd2554e35f106..b64013e04f26bd87a5663716d59896b9b049fcb0 100644
--- a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
+++ b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
@@ -22,7 +22,8 @@ import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.inputmethod.InputMethodSubtype;
 
-import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
 
 import java.util.ArrayList;
 import java.util.Locale;
diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
index 9162522924fb6670b2942352dfb7af1f66539eb1..8d0fe014c5035af20b472de7c6a91043152a999b 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
@@ -21,6 +21,8 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.inputmethod.latin.utils.CollectionUtils;
+
 import java.util.ArrayList;
 import java.util.Locale;
 
diff --git a/tests/src/com/android/inputmethod/latin/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/UserHistoryDictionaryTests.java
index 594ba0e7b42eaef0e1f03794b97b252978f07c35..93befd7bf546b595c41336ff699c08fc7b8e2ac5 100644
--- a/tests/src/com/android/inputmethod/latin/UserHistoryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/UserHistoryDictionaryTests.java
@@ -22,6 +22,8 @@ import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
+import com.android.inputmethod.latin.utils.CollectionUtils;
+
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java
index 7890782bf89bfad3df654367fd78e16701ba65f6..cca81a0e0b7ee364e7364cddee31132fa82ba8b6 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java
@@ -23,12 +23,12 @@ import android.util.Log;
 import android.util.SparseArray;
 
 import com.android.inputmethod.latin.ByteArrayWrapper;
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
 import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
 import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup;
 import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
 import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.io.File;
 import java.io.FileInputStream;
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
index 08ae89b293c5fe6f0df54986e11f16dedc0c8d36..d33142ce04f332b4938a7f67caf2201628c99d17 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
@@ -21,12 +21,12 @@ import android.test.MoreAsserts;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
-import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.ByteBufferWrapper;
 import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
 import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
 import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
 import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.utils.CollectionUtils;
 
 import java.io.BufferedOutputStream;
 import java.io.File;
diff --git a/tests/src/com/android/inputmethod/latin/CapsModeUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java
similarity index 98%
rename from tests/src/com/android/inputmethod/latin/CapsModeUtilsTests.java
rename to tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java
index 339791d5779e7c320b909c6fc9d707046c1afa92..cf3bdd6801cf67e32c8575d02361309a5026d27e 100644
--- a/tests/src/com/android/inputmethod/latin/CapsModeUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
diff --git a/tests/src/com/android/inputmethod/latin/ForgettingCurveTests.java b/tests/src/com/android/inputmethod/latin/utils/ForgettingCurveTests.java
similarity index 98%
rename from tests/src/com/android/inputmethod/latin/ForgettingCurveTests.java
rename to tests/src/com/android/inputmethod/latin/utils/ForgettingCurveTests.java
index 3259312dfc2594c5c953e511ccffb79de3d69826..823bd5d7d8f98e4083644a83322239a4065bdf1e 100644
--- a/tests/src/com/android/inputmethod/latin/ForgettingCurveTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/ForgettingCurveTests.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
diff --git a/tests/src/com/android/inputmethod/latin/RecapitalizeStatusTests.java b/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java
similarity index 99%
rename from tests/src/com/android/inputmethod/latin/RecapitalizeStatusTests.java
rename to tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java
index 9d7203e5aaaa9498aeddbb3d563aa561e4497f74..a520412646d015fb6773d909405a0c50d776e682 100644
--- a/tests/src/com/android/inputmethod/latin/RecapitalizeStatusTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
diff --git a/tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java b/tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java
similarity index 99%
rename from tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java
rename to tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java
index b9fee950ef637c700cd1c01e8023130862d3b7d5..cfff61ef851c8d5c4c02057c080413b92fb6e15f 100644
--- a/tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
diff --git a/tests/src/com/android/inputmethod/latin/ResourceUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/ResourceUtilsTests.java
similarity index 98%
rename from tests/src/com/android/inputmethod/latin/ResourceUtilsTests.java
rename to tests/src/com/android/inputmethod/latin/utils/ResourceUtilsTests.java
index c915522ee46af9bfb323e04ce530624f08b8fd8e..1ae22e307ba84d108ef4d0fda20f907fa0bbc480 100644
--- a/tests/src/com/android/inputmethod/latin/ResourceUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/ResourceUtilsTests.java
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.inputmethod.latin.ResourceUtils.DeviceOverridePatternSyntaxError;
+import com.android.inputmethod.latin.utils.ResourceUtils.DeviceOverridePatternSyntaxError;
 
 import java.util.HashMap;
 
diff --git a/tests/src/com/android/inputmethod/latin/StringUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
similarity index 99%
rename from tests/src/com/android/inputmethod/latin/StringUtilsTests.java
rename to tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
index 4f260987b660b05624fd3db8c0139f30516718d6..9ee8e387b3baacf57e9b7825b1f0edf995c07b7b 100644
--- a/tests/src/com/android/inputmethod/latin/StringUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
diff --git a/tests/src/com/android/inputmethod/latin/UserHistoryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java
similarity index 95%
rename from tests/src/com/android/inputmethod/latin/UserHistoryDictIOUtilsTests.java
rename to tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java
index 6778e6650a275a6fb4f863a3e9c168a498c445fe..0d829c5e61ea1fa55404a75ebfc26ef160c02d9c 100644
--- a/tests/src/com/android/inputmethod/latin/UserHistoryDictIOUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java
@@ -14,18 +14,20 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import android.content.Context;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
-import com.android.inputmethod.latin.UserHistoryDictIOUtils.BigramDictionaryInterface;
-import com.android.inputmethod.latin.UserHistoryDictIOUtils.OnAddWordListener;
+import com.android.inputmethod.latin.ByteArrayWrapper;
+import com.android.inputmethod.latin.UserHistoryDictionaryBigramList;
 import com.android.inputmethod.latin.makedict.FormatSpec;
 import com.android.inputmethod.latin.makedict.FusionDictionary;
 import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup;
+import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.BigramDictionaryInterface;
+import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.OnAddWordListener;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -152,8 +154,7 @@ public class UserHistoryDictIOUtilsTests extends AndroidTestCase
             final byte[] buffer = new byte[(int)file.length()];
             inStream.read(buffer);
 
-            UserHistoryDictIOUtils.readDictionaryBinary(
-                    new ByteArrayWrapper(buffer), listener);
+            UserHistoryDictIOUtils.readDictionaryBinary(new ByteArrayWrapper(buffer), listener);
         } catch (FileNotFoundException e) {
             Log.e(TAG, "file not found", e);
         } catch (IOException e) {
diff --git a/tools/dicttool/Android.mk b/tools/dicttool/Android.mk
index c99ba2f990559a4741341589809067a973f3dec5..931678793b832742485f0e9a7aab9943587b2207 100644
--- a/tools/dicttool/Android.mk
+++ b/tools/dicttool/Android.mk
@@ -30,8 +30,8 @@ DICTTOOL_ONDEVICE_TESTS_DIRECTORY := \
 USED_TARGETTED_UTILS := \
         $(FRAMEWORK_TOP)/android/util/SparseArray.java \
         $(FRAMEWORK_TOP)/com/android/internal/util/ArrayUtils.java \
-        $(LATINIME_CORE_SOURCE_DIRECTORY)/CollectionUtils.java \
-        $(LATINIME_CORE_SOURCE_DIRECTORY)/ByteArrayWrapper.java
+        $(LATINIME_CORE_SOURCE_DIRECTORY)/ByteArrayWrapper.java \
+        $(LATINIME_CORE_SOURCE_DIRECTORY)/utils/CollectionUtils.java
 
 LOCAL_MAIN_SRC_FILES := $(call all-java-files-under, $(MAKEDICT_CORE_SOURCE_DIRECTORY))
 LOCAL_TOOL_SRC_FILES := $(call all-java-files-under, src)