Merge "Update dictionaries"
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index c9a42a3..70f8d0d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1797,8 +1797,6 @@
                     if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
                         final String word = mWordComposer.getTypedWord();
                         ResearchLogger.latinIME_handleBackspace_batch(word, 1);
-                        ResearchLogger.getInstance().uncommitCurrentLogUnit(
-                                word, false /* dumpCurrentLogUnit */);
                     }
                     final String rejectedSuggestion = mWordComposer.getTypedWord();
                     mWordComposer.reset();
@@ -1825,6 +1823,9 @@
                 // like the smiley key or the .com key.
                 final int length = mEnteredText.length();
                 mConnection.deleteSurroundingText(length, 0);
+                if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
+                    ResearchLogger.latinIME_handleBackspace_cancelTextInput(mEnteredText);
+                }
                 mEnteredText = null;
                 // If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
                 // In addition we know that spaceState is false, and that we should not be
@@ -1858,7 +1859,8 @@
                 mLastSelectionEnd = mLastSelectionStart;
                 mConnection.deleteSurroundingText(numCharsDeleted, 0);
                 if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
-                    ResearchLogger.latinIME_handleBackspace(numCharsDeleted);
+                    ResearchLogger.latinIME_handleBackspace(numCharsDeleted,
+                            false /* shouldUncommitLogUnit */);
                 }
             } else {
                 // There is no selection, just delete one character.
@@ -1876,12 +1878,13 @@
                     mConnection.deleteSurroundingText(1, 0);
                 }
                 if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
-                    ResearchLogger.latinIME_handleBackspace(1);
+                    ResearchLogger.latinIME_handleBackspace(1, true /* shouldUncommitLogUnit */);
                 }
                 if (mDeleteCount > DELETE_ACCELERATE_AT) {
                     mConnection.deleteSurroundingText(1, 0);
                     if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
-                        ResearchLogger.latinIME_handleBackspace(1);
+                        ResearchLogger.latinIME_handleBackspace(1,
+                                true /* shouldUncommitLogUnit */);
                     }
                 }
             }
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 2f2ec35..e4c5a06 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -208,6 +208,9 @@
 
     private CharSequence getStyledSuggestedWord(final SuggestedWords suggestedWords,
             final int indexInSuggestedWords) {
+        if (indexInSuggestedWords >= suggestedWords.size()) {
+            return null;
+        }
         final String word = suggestedWords.getWord(indexInSuggestedWords);
         final boolean isAutoCorrect = indexInSuggestedWords == 1
                 && suggestedWords.willAutoCorrect();
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index 56ab90c..ec54616 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -863,7 +863,10 @@
         // Check that expected word matches.
         if (oldLogUnit != null) {
             final String oldLogUnitWords = oldLogUnit.getWordsAsString();
-            if (oldLogUnitWords != null && !oldLogUnitWords.equals(expectedWord)) {
+            // Because the word is stored in the LogUnit with digits scrubbed, the comparison must
+            // be made on a scrubbed version of the expectedWord as well.
+            if (oldLogUnitWords != null && !oldLogUnitWords.equals(
+                    scrubDigitsFromString(expectedWord))) {
                 return;
             }
         }
@@ -1274,6 +1277,16 @@
     }
 
     /**
+     * Log a revert of onTextInput() (known in the IME as "EnteredText").
+     *
+     * SystemResponse: Remove the LogUnit recording the textInput
+     */
+    public static void latinIME_handleBackspace_cancelTextInput(final String text) {
+        final ResearchLogger researchLogger = getInstance();
+        researchLogger.uncommitCurrentLogUnit(text, true /* dumpCurrentLogUnit */);
+    }
+
+    /**
      * Log a call to LatinIME.pickSuggestionManually().
      *
      * UserAction: The user has chosen a specific word from the suggestion strip.
@@ -1575,7 +1588,12 @@
     private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_REVERTDOUBLESPACEPERIOD =
             new LogStatement("RichInputConnectionRevertDoubleSpacePeriod", false, false);
     public static void richInputConnection_revertDoubleSpacePeriod() {
-        getInstance().enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_REVERTDOUBLESPACEPERIOD);
+        final ResearchLogger researchLogger = getInstance();
+        // An extra LogUnit is added for the period; this is removed here because of the revert.
+        researchLogger.uncommitCurrentLogUnit(null, true /* dumpCurrentLogUnit */);
+        // TODO: This will probably be lost as the user backspaces further.  Figure out how to put
+        // it into the right logUnit.
+        researchLogger.enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_REVERTDOUBLESPACEPERIOD);
     }
 
     /**
@@ -1806,17 +1824,26 @@
                 SystemClock.uptimeMillis());
     }
 
+    private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE =
+            new LogStatement("LatinIMEHandleBackspace", true, false, "numCharacters");
     /**
      * Log a call to LatinIME.handleBackspace() that is not a batch delete.
      *
      * UserInput: The user is deleting one or more characters by hitting the backspace key once.
      * The covers single character deletes as well as deleting selections.
+     *
+     * @param numCharacters how many characters the backspace operation deleted
+     * @param shouldUncommitLogUnit whether to uncommit the last {@code LogUnit} in the
+     * {@code LogBuffer}
      */
-    private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE =
-            new LogStatement("LatinIMEHandleBackspace", true, false, "numCharacters");
-    public static void latinIME_handleBackspace(final int numCharacters) {
+    public static void latinIME_handleBackspace(final int numCharacters,
+            final boolean shouldUncommitLogUnit) {
         final ResearchLogger researchLogger = getInstance();
         researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE, numCharacters);
+        if (shouldUncommitLogUnit) {
+            ResearchLogger.getInstance().uncommitCurrentLogUnit(
+                    null, true /* dumpCurrentLogUnit */);
+        }
     }
 
     /**
@@ -1834,6 +1861,8 @@
                 numCharacters);
         researchLogger.mStatistics.recordGestureDelete(deletedText.length(),
                 SystemClock.uptimeMillis());
+        researchLogger.uncommitCurrentLogUnit(deletedText.toString(),
+                false /* dumpCurrentLogUnit */);
     }
 
     /**
diff --git a/native/jni/Android.mk b/native/jni/Android.mk
index 0631b22..15bfbbe 100644
--- a/native/jni/Android.mk
+++ b/native/jni/Android.mk
@@ -46,9 +46,7 @@
     jni_common.cpp
 
 LATIN_IME_CORE_SRC_FILES := \
-    bigram_dictionary.cpp \
     correction.cpp \
-    dic_traverse_wrapper.cpp \
     unigram_dictionary.cpp \
     words_priority_queue.cpp \
     suggest/core/suggest.cpp \
@@ -57,7 +55,7 @@
         dic_node_utils.cpp \
         dic_nodes_cache.cpp) \
     $(addprefix suggest/core/dictionary/, \
-        char_utils.cpp \
+        bigram_dictionary.cpp \
         binary_dictionary_format.cpp \
         byte_array_utils.cpp \
         dictionary.cpp \
@@ -76,7 +74,8 @@
         typing_scoring.cpp \
         typing_suggest_policy.cpp \
         typing_traversal.cpp \
-        typing_weighting.cpp)
+        typing_weighting.cpp) \
+    utils/char_utils.cpp
 
 LOCAL_SRC_FILES := \
     $(LATIN_IME_JNI_SRC_FILES) \
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index e80abf6..935cb0d 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -34,10 +34,10 @@
 #include "correction.h"
 #include "jni.h"
 #include "jni_common.h"
-#include "suggest_options.h"
 #include "suggest/core/dictionary/binary_dictionary_format.h"
 #include "suggest/core/dictionary/binary_dictionary_info.h"
 #include "suggest/core/dictionary/dictionary.h"
+#include "suggest/core/suggest_options.h"
 
 namespace latinime {
 
@@ -137,7 +137,8 @@
     Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
     if (!dictionary) return 0;
     ProximityInfo *pInfo = reinterpret_cast<ProximityInfo *>(proximityInfo);
-    void *traverseSession = reinterpret_cast<void *>(dicTraverseSession);
+    DicTraverseSession *traverseSession =
+            reinterpret_cast<DicTraverseSession *>(dicTraverseSession);
 
     // Input values
     int xCoordinates[inputSize];
diff --git a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
index 08124ff..d454150 100644
--- a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
+++ b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
@@ -17,36 +17,37 @@
 #define LOG_TAG "LatinIME: jni: Session"
 
 #include "com_android_inputmethod_latin_DicTraverseSession.h"
+
 #include "defines.h"
-#include "dic_traverse_wrapper.h"
 #include "jni.h"
 #include "jni_common.h"
+#include "suggest/core/session/dic_traverse_session.h"
 
 namespace latinime {
 class Dictionary;
 static jlong latinime_setDicTraverseSession(JNIEnv *env, jclass clazz, jstring localeJStr) {
-    void *traverseSession = DicTraverseWrapper::getDicTraverseSession(env, localeJStr);
+    void *traverseSession = DicTraverseSession::getSessionInstance(env, localeJStr);
     return reinterpret_cast<jlong>(traverseSession);
 }
 
 static void latinime_initDicTraverseSession(JNIEnv *env, jclass clazz, jlong traverseSession,
         jlong dictionary, jintArray previousWord, jint previousWordLength) {
-    void *ts = reinterpret_cast<void *>(traverseSession);
+    DicTraverseSession *ts = reinterpret_cast<DicTraverseSession *>(traverseSession);
     Dictionary *dict = reinterpret_cast<Dictionary *>(dictionary);
     if (!previousWord) {
-        DicTraverseWrapper::initDicTraverseSession(
+        DicTraverseSession::initSessionInstance(
                 ts, dict, 0 /* prevWord */, 0 /* prevWordLength*/, 0 /* suggestOptions */);
         return;
     }
     int prevWord[previousWordLength];
     env->GetIntArrayRegion(previousWord, 0, previousWordLength, prevWord);
-    DicTraverseWrapper::initDicTraverseSession(
+    DicTraverseSession::initSessionInstance(
             ts, dict, prevWord, previousWordLength, 0 /* suggestOptions */);
 }
 
 static void latinime_releaseDicTraverseSession(JNIEnv *env, jclass clazz, jlong traverseSession) {
-    void *ts = reinterpret_cast<void *>(traverseSession);
-    DicTraverseWrapper::releaseDicTraverseSession(ts);
+    DicTraverseSession *ts = reinterpret_cast<DicTraverseSession *>(traverseSession);
+    DicTraverseSession::releaseSessionInstance(ts);
 }
 
 static JNINativeMethod sMethods[] = {
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp
index 3dc2f37..feed562 100644
--- a/native/jni/src/correction.cpp
+++ b/native/jni/src/correction.cpp
@@ -20,11 +20,11 @@
 
 #include "correction.h"
 #include "defines.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/layout/proximity_info_state.h"
 #include "suggest/core/layout/touch_position_correction_utils.h"
 #include "suggest/policyimpl/utils/edit_distance.h"
 #include "suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/correction.h b/native/jni/src/correction.h
index 3f60d48..84d6429 100644
--- a/native/jni/src/correction.h
+++ b/native/jni/src/correction.h
@@ -21,8 +21,8 @@
 
 #include "correction_state.h"
 #include "defines.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/layout/proximity_info_state.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/dic_traverse_wrapper.cpp b/native/jni/src/dic_traverse_wrapper.cpp
deleted file mode 100644
index ec8c62d..0000000
--- a/native/jni/src/dic_traverse_wrapper.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "LatinIME: jni: Session"
-
-#include "dic_traverse_wrapper.h"
-
-namespace latinime {
-void *(*DicTraverseWrapper::sDicTraverseSessionFactoryMethod)(JNIEnv *, jstring) = 0;
-void (*DicTraverseWrapper::sDicTraverseSessionReleaseMethod)(void *) = 0;
-void (*DicTraverseWrapper::sDicTraverseSessionInitMethod)(
-        void *, const Dictionary *const, const int *, const int, const SuggestOptions *const) = 0;
-} // namespace latinime
diff --git a/native/jni/src/dic_traverse_wrapper.h b/native/jni/src/dic_traverse_wrapper.h
deleted file mode 100644
index 43b4c9a..0000000
--- a/native/jni/src/dic_traverse_wrapper.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef LATINIME_DIC_TRAVERSE_WRAPPER_H
-#define LATINIME_DIC_TRAVERSE_WRAPPER_H
-
-#include "defines.h"
-#include "jni.h"
-
-namespace latinime {
-class Dictionary;
-class SuggestOptions;
-// TODO: Remove
-class DicTraverseWrapper {
- public:
-    static void *getDicTraverseSession(JNIEnv *env, jstring locale) {
-        if (sDicTraverseSessionFactoryMethod) {
-            return sDicTraverseSessionFactoryMethod(env, locale);
-        }
-        return 0;
-    }
-    static void initDicTraverseSession(void *traverseSession, const Dictionary *const dictionary,
-            const int *prevWord, const int prevWordLength,
-            const SuggestOptions *const suggestOptions) {
-        if (sDicTraverseSessionInitMethod) {
-            sDicTraverseSessionInitMethod(
-                    traverseSession, dictionary, prevWord, prevWordLength, suggestOptions);
-        }
-    }
-    static void releaseDicTraverseSession(void *traverseSession) {
-        if (sDicTraverseSessionReleaseMethod) {
-            sDicTraverseSessionReleaseMethod(traverseSession);
-        }
-    }
-    static void setTraverseSessionFactoryMethod(void *(*factoryMethod)(JNIEnv *, jstring)) {
-        sDicTraverseSessionFactoryMethod = factoryMethod;
-    }
-    static void setTraverseSessionInitMethod(
-            void (*initMethod)(void *, const Dictionary *const, const int *, const int,
-                    const SuggestOptions *const)) {
-        sDicTraverseSessionInitMethod = initMethod;
-    }
-    static void setTraverseSessionReleaseMethod(void (*releaseMethod)(void *)) {
-        sDicTraverseSessionReleaseMethod = releaseMethod;
-    }
-
- private:
-    DISALLOW_IMPLICIT_CONSTRUCTORS(DicTraverseWrapper);
-    static void *(*sDicTraverseSessionFactoryMethod)(JNIEnv *, jstring);
-    static void (*sDicTraverseSessionInitMethod)(
-            void *, const Dictionary *const, const int *, const int, const SuggestOptions *const);
-    static void (*sDicTraverseSessionReleaseMethod)(void *);
-};
-} // namespace latinime
-#endif // LATINIME_DIC_TRAVERSE_WRAPPER_H
diff --git a/native/jni/src/suggest/core/dicnode/dic_node.h b/native/jni/src/suggest/core/dicnode/dic_node.h
index 14bd2d5..3f64d07 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node.h
@@ -22,8 +22,8 @@
 #include "suggest/core/dicnode/dic_node_profiler.h"
 #include "suggest/core/dicnode/dic_node_properties.h"
 #include "suggest/core/dicnode/dic_node_release_listener.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/dictionary/digraph_utils.h"
+#include "utils/char_utils.h"
 
 #if DEBUG_DICT
 #define LOGI_SHOW_ADD_COST_PROP \
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
index 46dbe43..3deee1a 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
+++ b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
@@ -22,11 +22,11 @@
 #include "suggest/core/dicnode/dic_node_vector.h"
 #include "suggest/core/dictionary/binary_dictionary_info.h"
 #include "suggest/core/dictionary/binary_format.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/dictionary/multi_bigram_map.h"
 #include "suggest/core/dictionary/probability_utils.h"
 #include "suggest/core/layout/proximity_info.h"
 #include "suggest/core/layout/proximity_info_state.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/bigram_dictionary.cpp b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp
similarity index 99%
rename from native/jni/src/bigram_dictionary.cpp
rename to native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp
index b572278..59d1b19 100644
--- a/native/jni/src/bigram_dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp
@@ -24,9 +24,9 @@
 #include "suggest/core/dictionary/binary_dictionary_info.h"
 #include "suggest/core/dictionary/binary_format.h"
 #include "suggest/core/dictionary/bloom_filter.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/dictionary/dictionary.h"
 #include "suggest/core/dictionary/probability_utils.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/bigram_dictionary.h b/native/jni/src/suggest/core/dictionary/bigram_dictionary.h
similarity index 100%
rename from native/jni/src/bigram_dictionary.h
rename to native/jni/src/suggest/core/dictionary/bigram_dictionary.h
diff --git a/native/jni/src/suggest/core/dictionary/binary_format.h b/native/jni/src/suggest/core/dictionary/binary_format.h
index 3bacc09..1b57793 100644
--- a/native/jni/src/suggest/core/dictionary/binary_format.h
+++ b/native/jni/src/suggest/core/dictionary/binary_format.h
@@ -20,10 +20,10 @@
 #include <cstdlib>
 #include <stdint.h>
 
-#include "hash_map_compat.h"
 #include "suggest/core/dictionary/bloom_filter.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/dictionary/probability_utils.h"
+#include "utils/char_utils.h"
+#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp
index 53a6751..aa8356a 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp
@@ -21,12 +21,12 @@
 #include <map> // TODO: remove
 #include <stdint.h>
 
-#include "bigram_dictionary.h"
 #include "defines.h"
-#include "dic_traverse_wrapper.h"
-#include "suggest_options.h"
-#include "suggest/core/suggest.h"
+#include "suggest/core/dictionary/bigram_dictionary.h"
 #include "suggest/core/dictionary/binary_format.h"
+#include "suggest/core/session/dic_traverse_session.h"
+#include "suggest/core/suggest.h"
+#include "suggest/core/suggest_options.h"
 #include "suggest/policyimpl/gesture/gesture_suggest_policy_factory.h"
 #include "suggest/policyimpl/typing/typing_suggest_policy_factory.h"
 #include "unigram_dictionary.h"
@@ -50,14 +50,14 @@
     delete mTypingSuggest;
 }
 
-int Dictionary::getSuggestions(ProximityInfo *proximityInfo, void *traverseSession,
+int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
         int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
         int inputSize, int *prevWordCodePoints, int prevWordLength, int commitPoint,
         const SuggestOptions *const suggestOptions, int *outWords, int *frequencies,
         int *spaceIndices, int *outputTypes) const {
     int result = 0;
     if (suggestOptions->isGesture()) {
-        DicTraverseWrapper::initDicTraverseSession(
+        DicTraverseSession::initSessionInstance(
                 traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
         result = mGestureSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
                 ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint, outWords,
@@ -68,7 +68,7 @@
         return result;
     } else {
         if (USE_SUGGEST_INTERFACE_FOR_TYPING) {
-            DicTraverseWrapper::initDicTraverseSession(
+            DicTraverseSession::initSessionInstance(
                     traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
             result = mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
                     ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint,
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h
index 771837b..40e2548 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.h
+++ b/native/jni/src/suggest/core/dictionary/dictionary.h
@@ -25,6 +25,7 @@
 namespace latinime {
 
 class BigramDictionary;
+class DicTraverseSession;
 class ProximityInfo;
 class SuggestInterface;
 class SuggestOptions;
@@ -54,9 +55,9 @@
 
     Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust);
 
-    int getSuggestions(ProximityInfo *proximityInfo, void *traverseSession, int *xcoordinates,
-            int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints, int inputSize,
-            int *prevWordCodePoints, int prevWordLength, int commitPoint,
+    int getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
+            int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
+            int inputSize, int *prevWordCodePoints, int prevWordLength, int commitPoint,
             const SuggestOptions *const suggestOptions, int *outWords, int *frequencies,
             int *spaceIndices, int *outputTypes) const;
 
diff --git a/native/jni/src/suggest/core/dictionary/digraph_utils.cpp b/native/jni/src/suggest/core/dictionary/digraph_utils.cpp
index e8cdd53..f53e56e 100644
--- a/native/jni/src/suggest/core/dictionary/digraph_utils.cpp
+++ b/native/jni/src/suggest/core/dictionary/digraph_utils.cpp
@@ -18,7 +18,7 @@
 
 #include "defines.h"
 #include "suggest/core/dictionary/binary_format.h"
-#include "suggest/core/dictionary/char_utils.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/core/dictionary/multi_bigram_map.h b/native/jni/src/suggest/core/dictionary/multi_bigram_map.h
index b17c758..ba97e58 100644
--- a/native/jni/src/suggest/core/dictionary/multi_bigram_map.h
+++ b/native/jni/src/suggest/core/dictionary/multi_bigram_map.h
@@ -18,9 +18,9 @@
 #define LATINIME_MULTI_BIGRAM_MAP_H
 
 #include "defines.h"
-#include "hash_map_compat.h"
 #include "suggest/core/dictionary/binary_dictionary_info.h"
 #include "suggest/core/dictionary/binary_format.h"
+#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/core/layout/proximity_info.cpp b/native/jni/src/suggest/core/layout/proximity_info.cpp
index 0b5d71a..80355c1 100644
--- a/native/jni/src/suggest/core/layout/proximity_info.cpp
+++ b/native/jni/src/suggest/core/layout/proximity_info.cpp
@@ -23,10 +23,10 @@
 
 #include "defines.h"
 #include "jni.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/layout/additional_proximity_chars.h"
 #include "suggest/core/layout/geometry_utils.h"
 #include "suggest/core/layout/proximity_info_params.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/core/layout/proximity_info.h b/native/jni/src/suggest/core/layout/proximity_info.h
index 6d2ddd4..6ca2fdd 100644
--- a/native/jni/src/suggest/core/layout/proximity_info.h
+++ b/native/jni/src/suggest/core/layout/proximity_info.h
@@ -18,9 +18,9 @@
 #define LATINIME_PROXIMITY_INFO_H
 
 #include "defines.h"
-#include "hash_map_compat.h"
 #include "jni.h"
 #include "suggest/core/layout/proximity_info_utils.h"
+#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state.cpp b/native/jni/src/suggest/core/layout/proximity_info_state.cpp
index 412d550..4e53992 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state.cpp
+++ b/native/jni/src/suggest/core/layout/proximity_info_state.cpp
@@ -23,10 +23,10 @@
 #include <vector>
 
 #include "defines.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/layout/geometry_utils.h"
 #include "suggest/core/layout/proximity_info.h"
 #include "suggest/core/layout/proximity_info_state_utils.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state.h b/native/jni/src/suggest/core/layout/proximity_info_state.h
index a971294..0079ab5 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state.h
+++ b/native/jni/src/suggest/core/layout/proximity_info_state.h
@@ -21,9 +21,9 @@
 #include <vector>
 
 #include "defines.h"
-#include "hash_map_compat.h"
 #include "suggest/core/layout/proximity_info_params.h"
 #include "suggest/core/layout/proximity_info_state_utils.h"
+#include "utils/hash_map_compat.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state_utils.h b/native/jni/src/suggest/core/layout/proximity_info_state_utils.h
index 1837c7a..66fe079 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state_utils.h
+++ b/native/jni/src/suggest/core/layout/proximity_info_state_utils.h
@@ -21,7 +21,7 @@
 #include <vector>
 
 #include "defines.h"
-#include "hash_map_compat.h"
+#include "utils/hash_map_compat.h"
 
 namespace latinime {
 class ProximityInfo;
diff --git a/native/jni/src/suggest/core/layout/proximity_info_utils.h b/native/jni/src/suggest/core/layout/proximity_info_utils.h
index 3588f4d..54f7539 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_utils.h
+++ b/native/jni/src/suggest/core/layout/proximity_info_utils.h
@@ -20,10 +20,10 @@
 #include <cmath>
 
 #include "defines.h"
-#include "hash_map_compat.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/layout/additional_proximity_chars.h"
 #include "suggest/core/layout/geometry_utils.h"
+#include "utils/char_utils.h"
+#include "utils/hash_map_compat.h"
 
 namespace latinime {
 class ProximityInfoUtils {
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.cpp b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
index be293df..c398cae 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.cpp
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
@@ -17,7 +17,6 @@
 #include "suggest/core/session/dic_traverse_session.h"
 
 #include "defines.h"
-#include "dic_traverse_wrapper.h"
 #include "jni.h"
 #include "suggest/core/dicnode/dic_node_utils.h"
 #include "suggest/core/dictionary/binary_dictionary_info.h"
@@ -26,43 +25,6 @@
 
 namespace latinime {
 
-const int DicTraverseSession::CACHE_START_INPUT_LENGTH_THRESHOLD = 20;
-
-// A factory method for DicTraverseSession
-static void *getSessionInstance(JNIEnv *env, jstring localeStr) {
-    return new DicTraverseSession(env, localeStr);
-}
-
-// TODO: Pass "DicTraverseSession *traverseSession" when the source code structure settles down.
-static void initSessionInstance(void *traverseSession, const Dictionary *const dictionary,
-        const int *prevWord, const int prevWordLength,
-        const SuggestOptions *const suggestOptions) {
-    if (traverseSession) {
-        DicTraverseSession *tSession = static_cast<DicTraverseSession *>(traverseSession);
-        tSession->init(dictionary, prevWord, prevWordLength, suggestOptions);
-    }
-}
-
-// TODO: Pass "DicTraverseSession *traverseSession" when the source code structure settles down.
-static void releaseSessionInstance(void *traverseSession) {
-    delete static_cast<DicTraverseSession *>(traverseSession);
-}
-
-// An ad-hoc internal class to register the factory method defined above
-class TraverseSessionFactoryRegisterer {
- public:
-    TraverseSessionFactoryRegisterer() {
-        DicTraverseWrapper::setTraverseSessionFactoryMethod(getSessionInstance);
-        DicTraverseWrapper::setTraverseSessionInitMethod(initSessionInstance);
-        DicTraverseWrapper::setTraverseSessionReleaseMethod(releaseSessionInstance);
-    }
- private:
-    DISALLOW_COPY_AND_ASSIGN(TraverseSessionFactoryRegisterer);
-};
-
-// To invoke the TraverseSessionFactoryRegisterer constructor in the global constructor.
-static TraverseSessionFactoryRegisterer traverseSessionFactoryRegisterer;
-
 void DicTraverseSession::init(const Dictionary *const dictionary, const int *prevWord,
         int prevWordLength, const SuggestOptions *const suggestOptions) {
     mDictionary = dictionary;
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.h b/native/jni/src/suggest/core/session/dic_traverse_session.h
index 3b6a3dc..630b3b5 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.h
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.h
@@ -35,6 +35,25 @@
 
 class DicTraverseSession {
  public:
+
+    // A factory method for DicTraverseSession
+    static AK_FORCE_INLINE void *getSessionInstance(JNIEnv *env, jstring localeStr) {
+        return new DicTraverseSession(env, localeStr);
+    }
+
+    static AK_FORCE_INLINE void initSessionInstance(DicTraverseSession *traverseSession,
+            const Dictionary *const dictionary, const int *prevWord, const int prevWordLength,
+            const SuggestOptions *const suggestOptions) {
+        if (traverseSession) {
+            DicTraverseSession *tSession = static_cast<DicTraverseSession *>(traverseSession);
+            tSession->init(dictionary, prevWord, prevWordLength, suggestOptions);
+        }
+    }
+
+    static AK_FORCE_INLINE void releaseSessionInstance(DicTraverseSession *traverseSession) {
+        delete traverseSession;
+    }
+
     AK_FORCE_INLINE DicTraverseSession(JNIEnv *env, jstring localeStr)
             : mPrevWordPos(NOT_VALID_WORD), mProximityInfo(0),
               mDictionary(0), mSuggestOptions(0), mDicNodesCache(), mMultiBigramMap(),
diff --git a/native/jni/src/suggest_options.h b/native/jni/src/suggest/core/suggest_options.h
similarity index 100%
rename from native/jni/src/suggest_options.h
rename to native/jni/src/suggest/core/suggest_options.h
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_traversal.h b/native/jni/src/suggest/policyimpl/typing/typing_traversal.h
index e066418..e21b318 100644
--- a/native/jni/src/suggest/policyimpl/typing/typing_traversal.h
+++ b/native/jni/src/suggest/policyimpl/typing/typing_traversal.h
@@ -22,11 +22,11 @@
 #include "defines.h"
 #include "suggest/core/dicnode/dic_node.h"
 #include "suggest/core/dicnode/dic_node_vector.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/layout/proximity_info_state.h"
 #include "suggest/core/policy/traversal.h"
 #include "suggest/core/session/dic_traverse_session.h"
 #include "suggest/policyimpl/typing/scoring_params.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 class TypingTraversal : public Traversal {
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_weighting.h b/native/jni/src/suggest/policyimpl/typing/typing_weighting.h
index 36d496a..17fa110 100644
--- a/native/jni/src/suggest/policyimpl/typing/typing_weighting.h
+++ b/native/jni/src/suggest/policyimpl/typing/typing_weighting.h
@@ -19,11 +19,11 @@
 
 #include "defines.h"
 #include "suggest/core/dicnode/dic_node_utils.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/layout/touch_position_correction_utils.h"
 #include "suggest/core/policy/weighting.h"
 #include "suggest/core/session/dic_traverse_session.h"
 #include "suggest/policyimpl/typing/scoring_params.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h b/native/jni/src/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h
index 09f986a..81614bc 100644
--- a/native/jni/src/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h
+++ b/native/jni/src/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h
@@ -17,8 +17,8 @@
 #ifndef LATINIME_DAEMARU_LEVENSHTEIN_EDIT_DISTANCE_POLICY_H
 #define LATINIME_DAEMARU_LEVENSHTEIN_EDIT_DISTANCE_POLICY_H
 
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/policyimpl/utils/edit_distance_policy.h"
+#include "utils/char_utils.h"
 
 namespace latinime {
 
diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp
index 8fd015c..5820a1d 100644
--- a/native/jni/src/unigram_dictionary.cpp
+++ b/native/jni/src/unigram_dictionary.cpp
@@ -21,12 +21,12 @@
 #include "defines.h"
 #include "suggest/core/dictionary/binary_dictionary_info.h"
 #include "suggest/core/dictionary/binary_format.h"
-#include "suggest/core/dictionary/char_utils.h"
 #include "suggest/core/dictionary/dictionary.h"
 #include "suggest/core/dictionary/digraph_utils.h"
 #include "suggest/core/dictionary/probability_utils.h"
 #include "suggest/core/dictionary/terminal_attributes.h"
 #include "suggest/core/layout/proximity_info.h"
+#include "utils/char_utils.h"
 #include "unigram_dictionary.h"
 #include "words_priority_queue.h"
 #include "words_priority_queue_pool.h"
diff --git a/native/jni/src/suggest/core/dictionary/char_utils.cpp b/native/jni/src/utils/char_utils.cpp
similarity index 99%
rename from native/jni/src/suggest/core/dictionary/char_utils.cpp
rename to native/jni/src/utils/char_utils.cpp
index 8d40e54..0e70396 100644
--- a/native/jni/src/suggest/core/dictionary/char_utils.cpp
+++ b/native/jni/src/utils/char_utils.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "suggest/core/dictionary/char_utils.h"
+#include "utils/char_utils.h"
 
 #include <cstdlib>
 
@@ -37,7 +37,7 @@
  *    $ apt-get install libicu-dev
  *
  * 3. Build the following code
- *    $ g++ -o char_utils -I../../.. -DUPDATING_CHAR_UTILS char_utils.cpp -licuuc
+ *    $ g++ -o char_utils -I.. -DUPDATING_CHAR_UTILS char_utils.cpp -licuuc
  */
 #ifdef UPDATING_CHAR_UTILS
 #include <stdio.h>
@@ -70,8 +70,7 @@
  *
  * 5. Update the SORTED_CHAR_MAP[] array below with the output above.
  *    Then, rebuild with -DCONFIRMING_CHAR_UTILS and confirm the program exits successfully.
- *    $ g++ -o char_utils -I../../.. -DUPDATING_CHAR_UTILS -DCONFIRMING_CHAR_UTILS char_utils.cpp \
- *      -licuuc
+ *    $ g++ -o char_utils -I.. -DUPDATING_CHAR_UTILS -DCONFIRMING_CHAR_UTILS char_utils.cpp -licuuc
  *    $ ./char_utils
  *    $
  */
diff --git a/native/jni/src/suggest/core/dictionary/char_utils.h b/native/jni/src/utils/char_utils.h
similarity index 100%
rename from native/jni/src/suggest/core/dictionary/char_utils.h
rename to native/jni/src/utils/char_utils.h
diff --git a/native/jni/src/hash_map_compat.h b/native/jni/src/utils/hash_map_compat.h
similarity index 100%
rename from native/jni/src/hash_map_compat.h
rename to native/jni/src/utils/hash_map_compat.h