diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 7e6c53e2f3a383203f7ba0f285b519bfa0c1d799..e0adc9a7121084700f0f42ab773e67a425ebcee8 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -90,9 +90,9 @@ public class BinaryDictionary extends Dictionary {
     private native void closeNative(long dict);
     private native int getFrequencyNative(long dict, int[] word, int wordLength);
     private native boolean isValidBigramNative(long dict, int[] word1, int[] word2);
-    private native int getSuggestionsNative(long dict, long proximityInfo, int[] xCoordinates,
-            int[] yCoordinates, int[] times, int[] pointerIds, int[] inputCodes, int codesSize,
-            int commitPoint, boolean isGesture,
+    private native int getSuggestionsNative(long dict, long proximityInfo, long traverseSession,
+            int[] xCoordinates, int[] yCoordinates, int[] times, int[] pointerIds,
+            int[] inputCodes, int codesSize, int commitPoint, boolean isGesture,
             int[] prevWordCodePointArray, boolean useFullEditDistance, char[] outputChars,
             int[] outputScores, int[] outputIndices, int[] outputTypes);
     private static native float calcNormalizedScoreNative(
@@ -129,7 +129,8 @@ public class BinaryDictionary extends Dictionary {
         final int codesSize = isGesture ? ips.getPointerSize() : composerSize;
         // proximityInfo and/or prevWordForBigrams may not be null.
         final int tmpCount = getSuggestionsNative(mNativeDict,
-                proximityInfo.getNativeProximityInfo(), ips.getXCoordinates(),
+                proximityInfo.getNativeProximityInfo(),
+                mDicTraverseSession.getSession(), ips.getXCoordinates(),
                 ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(),
                 mInputCodes, codesSize, 0 /* commitPoint */, isGesture, prevWordCodePointArray,
                 mUseFullEditDistance, mOutputChars, mOutputScores, mSpaceIndices, mOutputTypes);
diff --git a/java/src/com/android/inputmethod/latin/DicTraverseSession.java b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
index d0c70f3ad062138c0728eb90b41d9fdff79b1997..ae68e69ddb8c693a3502d73230f10ec4198dd23a 100644
--- a/java/src/com/android/inputmethod/latin/DicTraverseSession.java
+++ b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
@@ -30,6 +30,10 @@ public class DicTraverseSession {
                 locale != null ? locale.toString() : "");
     }
 
+    public long getSession() {
+        return mNativeDicTraverseSession;
+    }
+
     private native long setDicTraverseSessionNative(String locale);
     private native void releaseDicTraverseSessionNative(long nativeDicTraverseSession);
 
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 776f5f78fa2c156aa596bc07da6e0750e7b3e3e0..9de087a185ac0e5e054cf13718a46e26c7c5cf1c 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -122,14 +122,15 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
 }
 
 static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object, jlong dict,
-        jlong proximityInfo, jintArray xCoordinatesArray, jintArray yCoordinatesArray,
-        jintArray timesArray, jintArray pointerIdArray, jintArray inputArray, jint arraySize,
-        jint commitPoint, jboolean isGesture,
+        jlong proximityInfo, jlong dicTraverseSession, jintArray xCoordinatesArray,
+        jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdArray,
+        jintArray inputArray, jint arraySize, jint commitPoint, jboolean isGesture,
         jintArray prevWordForBigrams, jboolean useFullEditDistance, jcharArray outputArray,
         jintArray frequencyArray, jintArray spaceIndexArray, jintArray outputTypesArray) {
-    Dictionary *dictionary = (Dictionary*) dict;
+    Dictionary *dictionary = reinterpret_cast<Dictionary*>(dict);
     if (!dictionary) return 0;
-    ProximityInfo *pInfo = (ProximityInfo*)proximityInfo;
+    ProximityInfo *pInfo = reinterpret_cast<ProximityInfo*>(proximityInfo);
+    void *traverseSession = reinterpret_cast<void*>(dicTraverseSession);
     int *xCoordinates = env->GetIntArrayElements(xCoordinatesArray, 0);
     int *yCoordinates = env->GetIntArrayElements(yCoordinatesArray, 0);
     int *times = env->GetIntArrayElements(timesArray, 0);
@@ -145,10 +146,10 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object,
 
     int count;
     if (isGesture || arraySize > 1) {
-        count = dictionary->getSuggestions(pInfo, xCoordinates, yCoordinates, times, pointerIds,
-                inputCodes, arraySize, prevWordChars, prevWordLength, commitPoint, isGesture,
-                useFullEditDistance, (unsigned short*) outputChars, frequencies, spaceIndices,
-                outputTypes);
+        count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
+                times, pointerIds, inputCodes, arraySize, prevWordChars, prevWordLength,
+                commitPoint, isGesture, useFullEditDistance, (unsigned short*) outputChars,
+                frequencies, spaceIndices, outputTypes);
     } else {
         count = dictionary->getBigrams(prevWordChars, prevWordLength, inputCodes,
                 arraySize, (unsigned short*) outputChars, frequencies, outputTypes);
@@ -247,7 +248,7 @@ void releaseDictBuf(void *dictBuf, const size_t length, int fd) {
 static JNINativeMethod sMethods[] = {
     {"openNative", "(Ljava/lang/String;JJIIIII)J", (void*)latinime_BinaryDictionary_open},
     {"closeNative", "(J)V", (void*)latinime_BinaryDictionary_close},
-    {"getSuggestionsNative", "(JJ[I[I[I[I[IIIZ[IZ[C[I[I[I)I",
+    {"getSuggestionsNative", "(JJJ[I[I[I[I[IIIZ[IZ[C[I[I[I)I",
             (void*) latinime_BinaryDictionary_getSuggestions},
     {"getFrequencyNative", "(J[II)I", (void*)latinime_BinaryDictionary_getFrequency},
     {"isValidBigramNative", "(J[I[I)Z", (void*)latinime_BinaryDictionary_isValidBigram},
diff --git a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
index 8ee0450e48a35175be76ef88dcad19f216222a74..e7965377c8ed52940814f5c79937386ffaa8559d 100644
--- a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
+++ b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
@@ -26,12 +26,13 @@ void (*DicTraverseWrapper::sDicTraverseSessionReleaseMethod)(void *) = 0;
 
 static jlong latinime_setDicTraverseSession(JNIEnv *env, jobject object,
         jstring localejStr) {
-    void *session = DicTraverseWrapper::getDicTraverseSession();
-    return reinterpret_cast<jlong>(session);
+    void *traverseSession = DicTraverseWrapper::getDicTraverseSession();
+    return reinterpret_cast<jlong>(traverseSession);
 }
 
-static void latinime_DicTraverseSession_release(JNIEnv *env, jobject object, jlong session) {
-    void *pi = reinterpret_cast<void*>(session);
+static void latinime_DicTraverseSession_release(
+        JNIEnv *env, jobject object, jlong traverseSession) {
+    void *pi = reinterpret_cast<void*>(traverseSession);
     if (!pi) return;
     DicTraverseWrapper::releaseDicTraverseSession(pi);
 }
diff --git a/native/jni/com_android_inputmethod_latin_DicTraverseSession.h b/native/jni/com_android_inputmethod_latin_DicTraverseSession.h
index 5238fd0afe5df066dc18e734151963fdc57e9bc8..a84fe78cc3702d61c3a9a8340f10f9a9933560a2 100644
--- a/native/jni/com_android_inputmethod_latin_DicTraverseSession.h
+++ b/native/jni/com_android_inputmethod_latin_DicTraverseSession.h
@@ -31,9 +31,9 @@ class DicTraverseWrapper {
         }
         return 0;
     }
-    static void releaseDicTraverseSession(void *session) {
+    static void releaseDicTraverseSession(void *traverseSession) {
         if (sDicTraverseSessionReleaseMethod) {
-            sDicTraverseSessionReleaseMethod(session);
+            sDicTraverseSessionReleaseMethod(traverseSession);
         }
     }
  private:
diff --git a/native/jni/src/dictionary.cpp b/native/jni/src/dictionary.cpp
index ee55cfa60e33825e13124e035540755a4e216142..8c785a26323a2f6d61e37cd8dd403f4998a15523 100644
--- a/native/jni/src/dictionary.cpp
+++ b/native/jni/src/dictionary.cpp
@@ -56,16 +56,17 @@ Dictionary::~Dictionary() {
     delete mGestureDecoder;
 }
 
-int Dictionary::getSuggestions(ProximityInfo *proximityInfo, int *xcoordinates, int *ycoordinates,
-        int *times, int *pointerIds, int *codes, int codesSize, int *prevWordChars,
+int Dictionary::getSuggestions(ProximityInfo *proximityInfo, void *traverseSession,
+        int *xcoordinates, int *ycoordinates, int *times, int *pointerIds,
+        int *codes, int codesSize, int *prevWordChars,
         int prevWordLength, int commitPoint, bool isGesture,
         bool useFullEditDistance, unsigned short *outWords,
         int *frequencies, int *spaceIndices, int *outputTypes) {
     int result = 0;
     if (isGesture) {
         mGestureDecoder->setPrevWord(prevWordChars, prevWordLength);
-        result = mGestureDecoder->getSuggestions(proximityInfo, xcoordinates, ycoordinates,
-                times, pointerIds, codes, codesSize, commitPoint,
+        result = mGestureDecoder->getSuggestions(proximityInfo, traverseSession,
+                xcoordinates, ycoordinates, times, pointerIds, codes, codesSize, commitPoint,
                 outWords, frequencies, spaceIndices, outputTypes);
         if (DEBUG_DICT) {
             DUMP_RESULT(outWords, frequencies, 18 /* MAX_WORDS */, MAX_WORD_LENGTH_INTERNAL);
diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h
index ab238c8245d087ddfc6a212a404eaf2af9980e43..2c79527be1bd1aaf1605e822ff0fee5e7efd1783 100644
--- a/native/jni/src/dictionary.h
+++ b/native/jni/src/dictionary.h
@@ -44,9 +44,9 @@ class Dictionary {
     Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int typedLetterMultipler,
             int fullWordMultiplier, int maxWordLength, int maxWords, int maxPredictions);
 
-    int getSuggestions(ProximityInfo *proximityInfo, int *xcoordinates, int *ycoordinates,
-            int *times, int *pointerIds, int *codes, int codesSize, int *prevWordChars,
-            int prevWordLength, int commitPoint, bool isGesture,
+    int getSuggestions(ProximityInfo *proximityInfo, void *traverseSession, int *xcoordinates,
+            int *ycoordinates, int *times, int *pointerIds, int *codes, int codesSize,
+            int *prevWordChars, int prevWordLength, int commitPoint, bool isGesture,
             bool useFullEditDistance, unsigned short *outWords,
             int *frequencies, int *spaceIndices, int *outputTypes);
 
diff --git a/native/jni/src/gesture/gesture_decoder_wrapper.h b/native/jni/src/gesture/gesture_decoder_wrapper.h
index 03c84b5fd7851bc5888821b4231b186ba65a59c3..b70c8e0a3f0d64a7fe537da1375e1f3628d595a0 100644
--- a/native/jni/src/gesture/gesture_decoder_wrapper.h
+++ b/native/jni/src/gesture/gesture_decoder_wrapper.h
@@ -37,15 +37,15 @@ class GestureDecoderWrapper : public IncrementalDecoderInterface {
         delete mIncrementalDecoderInterface;
     }
 
-    int getSuggestions(ProximityInfo *pInfo, int *inputXs, int *inputYs, int *times,
-            int *pointerIds, int *codes, int inputSize, int commitPoint,
+    int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
+            int *times, int *pointerIds, int *codes, int inputSize, int commitPoint,
             unsigned short *outWords, int *frequencies, int *outputIndices, int *outputTypes) {
         if (!mIncrementalDecoderInterface) {
             return 0;
         }
         return mIncrementalDecoderInterface->getSuggestions(
-                pInfo, inputXs, inputYs, times, pointerIds, codes, inputSize, commitPoint,
-                outWords, frequencies, outputIndices, outputTypes);
+                pInfo, traverseSession, inputXs, inputYs, times, pointerIds, codes,
+                inputSize, commitPoint, outWords, frequencies, outputIndices, outputTypes);
     }
 
     void reset() {
diff --git a/native/jni/src/gesture/incremental_decoder_interface.h b/native/jni/src/gesture/incremental_decoder_interface.h
index 6d2e273da59ec2f38cd62301dbfa0bcb57ef47c8..e8d3a5333070e134c3e6f5b136ca524d8570bdc6 100644
--- a/native/jni/src/gesture/incremental_decoder_interface.h
+++ b/native/jni/src/gesture/incremental_decoder_interface.h
@@ -28,9 +28,10 @@ class ProximityInfo;
 
 class IncrementalDecoderInterface {
  public:
-    virtual int getSuggestions(ProximityInfo *pInfo, int *inputXs, int *inputYs, int *times,
-            int *pointerIds, int *codes, int inputSize, int commitPoint,
-            unsigned short *outWords, int *frequencies, int *outputIndices, int *outputTypes) = 0;
+    virtual int getSuggestions(ProximityInfo *pInfo, void *traverseSession,
+            int *inputXs, int *inputYs, int *times, int *pointerIds, int *codes,
+            int inputSize, int commitPoint, unsigned short *outWords, int *frequencies,
+            int *outputIndices, int *outputTypes) = 0;
     virtual void reset() = 0;
     virtual void setDict(const UnigramDictionary *dict, const BigramDictionary *bigram,
             const uint8_t *dictRoot, int rootPos) = 0;
diff --git a/native/jni/src/gesture/incremental_decoder_wrapper.h b/native/jni/src/gesture/incremental_decoder_wrapper.h
index 698061548f03d235460c90002447720c655e4c59..8d66b4ec126258f2fab87fad87134da85d54b607 100644
--- a/native/jni/src/gesture/incremental_decoder_wrapper.h
+++ b/native/jni/src/gesture/incremental_decoder_wrapper.h
@@ -37,15 +37,15 @@ class IncrementalDecoderWrapper : public IncrementalDecoderInterface {
         delete mIncrementalDecoderInterface;
     }
 
-    int getSuggestions(ProximityInfo *pInfo, int *inputXs, int *inputYs, int *times,
-            int *pointerIds, int *codes, int inputSize, int commitPoint,
+    int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
+            int *times, int *pointerIds, int *codes, int inputSize, int commitPoint,
             unsigned short *outWords, int *frequencies, int *outputIndices, int *outputTypes) {
         if (!mIncrementalDecoderInterface) {
             return 0;
         }
         return mIncrementalDecoderInterface->getSuggestions(
-                pInfo, inputXs, inputYs, times, pointerIds, codes, inputSize, commitPoint,
-                outWords, frequencies, outputIndices, outputTypes);
+                pInfo, traverseSession, inputXs, inputYs, times, pointerIds, codes,
+                inputSize, commitPoint, outWords, frequencies, outputIndices, outputTypes);
     }
 
     void reset() {