diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index e10bdb1..c412635 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -435,5 +435,7 @@
     <declare-styleable name="SeekBarDialogPreference">
         <attr name="valueFormatText" format="reference" />
         <attr name="maxValue" format="integer" />
+        <attr name="minValue" format="integer" />
+        <attr name="stepValue" format="integer" />
     </declare-styleable>
 </resources>
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 29c65f1..32cee73 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -30,8 +30,7 @@
     private static final String TAG = ProximityInfo.class.getSimpleName();
     private static final boolean DEBUG = false;
 
-    /** MAX_PROXIMITY_CHARS_SIZE must be the same as MAX_PROXIMITY_CHARS_SIZE_INTERNAL
-     * in defines.h */
+    // Must be equal to MAX_PROXIMITY_CHARS_SIZE in native/jni/src/defines.h
     public static final int MAX_PROXIMITY_CHARS_SIZE = 16;
     /** Number of key widths from current touch point to search for nearest keys. */
     private static final float SEARCH_DISTANCE = 1.2f;
@@ -88,9 +87,13 @@
             final int rowSize, final int gridWidth, final int gridHeight) {
         final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo();
         spellCheckerProximityInfo.mNativeProximityInfo =
-                spellCheckerProximityInfo.setProximityInfoNative("",
-                        rowSize, gridWidth, gridHeight, gridWidth, gridHeight,
-                        1, proximityCharsArray, 0, null, null, null, null, null, null, null, null);
+                spellCheckerProximityInfo.setProximityInfoNative("" /* locale */,
+                        gridWidth /* displayWidth */, gridHeight /* displayHeight */,
+                        gridWidth, gridHeight, 1 /* mostCommonKeyWidth */, proximityCharsArray,
+                        0 /* keyCount */, null /*keyXCoordinates */, null /* keyYCoordinates */,
+                        null /* keyWidths */, null /* keyHeights */, null /* keyCharCodes */,
+                        null /* sweetSpotCenterXs */, null /* sweetSpotCenterYs */,
+                        null /* sweetSpotRadii */);
         return spellCheckerProximityInfo;
     }
 
@@ -100,11 +103,11 @@
     }
 
     // TODO: Stop passing proximityCharsArray
-    private static native long setProximityInfoNative(String locale, int maxProximityCharsSize,
+    private static native long setProximityInfoNative(String locale,
             int displayWidth, int displayHeight, int gridWidth, int gridHeight,
             int mostCommonKeyWidth, int[] proximityCharsArray, int keyCount, int[] keyXCoordinates,
             int[] keyYCoordinates, int[] keyWidths, int[] keyHeights, int[] keyCharCodes,
-            float[] sweetSpotCenterX, float[] sweetSpotCenterY, float[] sweetSpotRadii);
+            float[] sweetSpotCenterXs, float[] sweetSpotCenterYs, float[] sweetSpotRadii);
 
     private static native void releaseProximityInfoNative(long nativeProximityInfo);
 
@@ -230,9 +233,9 @@
         }
 
         // TODO: Stop passing proximityCharsArray
-        return setProximityInfoNative(mLocaleStr, MAX_PROXIMITY_CHARS_SIZE, mKeyboardMinWidth,
-                mKeyboardHeight, mGridWidth, mGridHeight, mMostCommonKeyWidth, proximityCharsArray,
-                keyCount, keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes,
+        return setProximityInfoNative(mLocaleStr, mKeyboardMinWidth, mKeyboardHeight,
+                mGridWidth, mGridHeight, mMostCommonKeyWidth, proximityCharsArray, keyCount,
+                keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes,
                 sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
     }
 
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 59d51b0..ad31633 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -35,9 +35,9 @@
     public static final String DICTIONARY_PACK_AUTHORITY =
             "com.android.inputmethod.latin.dictionarypack";
 
-    // Must be identical to MAX_WORD_LENGTH in native/jni/src/defines.h
+    // Must be equal to MAX_WORD_LENGTH in native/jni/src/defines.h
     private static final int MAX_WORD_LENGTH = Constants.Dictionary.MAX_WORD_LENGTH;
-    // Must be identical to MAX_RESULTS in native/jni/src/defines.h
+    // Must be equal to MAX_RESULTS in native/jni/src/defines.h
     private static final int MAX_RESULTS = 18;
 
     private long mNativeDict;
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index 748900b..85cc552 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -127,7 +127,7 @@
     }
 
     public static final class Dictionary {
-        // Must be identical to MAX_WORD_LENGTH in native/jni/src/defines.h
+        // Must be equal to MAX_WORD_LENGTH in native/jni/src/defines.h
         public static final int MAX_WORD_LENGTH = 48;
 
         private Dictionary() {
diff --git a/java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java b/java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java
index 6041564..9819a02 100644
--- a/java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java
+++ b/java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java
@@ -37,6 +37,8 @@
 
     private final int mValueFormatResId;
     private final int mMaxValue;
+    private final int mMinValue;
+    private final int mStepValue;
 
     private TextView mValueView;
     private SeekBar mSeekBar;
@@ -49,6 +51,8 @@
                 attrs, R.styleable.SeekBarDialogPreference, 0, 0);
         mValueFormatResId = a.getResourceId(R.styleable.SeekBarDialogPreference_valueFormatText, 0);
         mMaxValue = a.getInt(R.styleable.SeekBarDialogPreference_maxValue, 0);
+        mMinValue = a.getInt(R.styleable.SeekBarDialogPreference_minValue, 0);
+        mStepValue = a.getInt(R.styleable.SeekBarDialogPreference_stepValue, 0);
         a.recycle();
         setDialogLayoutResource(R.layout.seek_bar_dialog);
     }
@@ -70,22 +74,42 @@
     protected View onCreateDialogView() {
         final View view = super.onCreateDialogView();
         mSeekBar = (SeekBar)view.findViewById(R.id.seek_bar_dialog_bar);
-        mSeekBar.setMax(mMaxValue);
+        mSeekBar.setMax(mMaxValue - mMinValue);
         mSeekBar.setOnSeekBarChangeListener(this);
         mValueView = (TextView)view.findViewById(R.id.seek_bar_dialog_value);
         return view;
     }
 
+    private int getProgressFromValue(final int value) {
+        return value - mMinValue;
+    }
+
+    private int getValueFromProgress(final int progress) {
+        return progress + mMinValue;
+    }
+
+    private int clipValue(final int value) {
+        final int clippedValue = Math.min(mMaxValue, Math.max(mMinValue, value));
+        if (mStepValue <= 1) {
+            return clippedValue;
+        }
+        return clippedValue - (clippedValue % mStepValue);
+    }
+
+    private int getClippedValueFromProgress(final int progress) {
+        return clipValue(getValueFromProgress(progress));
+    }
+
     private void setValue(final int value, final boolean fromUser) {
         mValueView.setText(getValueText(value));
         if (!fromUser) {
-            mSeekBar.setProgress(value);
+            mSeekBar.setProgress(getProgressFromValue(value));
         }
     }
 
     @Override
     protected void onBindDialogView(final View view) {
-        setValue(mValueProxy.readValue(getKey()), false /* fromUser */);
+        setValue(clipValue(mValueProxy.readValue(getKey())), false /* fromUser */);
     }
 
     @Override
@@ -99,18 +123,18 @@
     public void onClick(final DialogInterface dialog, final int which) {
         super.onClick(dialog, which);
         if (which == DialogInterface.BUTTON_NEUTRAL) {
-            setValue(mValueProxy.readDefaultValue(getKey()), false /* fromUser */);
+            setValue(clipValue(mValueProxy.readDefaultValue(getKey())), false /* fromUser */);
         }
         if (which != DialogInterface.BUTTON_NEGATIVE) {
             setSummary(mValueView.getText());
-            mValueProxy.writeValue(mSeekBar.getProgress(), getKey());
+            mValueProxy.writeValue(getClippedValueFromProgress(mSeekBar.getProgress()), getKey());
         }
     }
 
     @Override
     public void onProgressChanged(final SeekBar seekBar, final int progress,
             final boolean fromUser) {
-        setValue(progress, fromUser);
+        setValue(getClippedValueFromProgress(progress), fromUser);
     }
 
     @Override
@@ -118,6 +142,6 @@
 
     @Override
     public void onStopTrackingTouch(final SeekBar seekBar) {
-        mValueProxy.feedbackValue(seekBar.getProgress());
+        mValueProxy.feedbackValue(getClippedValueFromProgress(seekBar.getProgress()));
     }
 }
diff --git a/native/jni/Android.mk b/native/jni/Android.mk
index f2aebd5..3735ec0 100644
--- a/native/jni/Android.mk
+++ b/native/jni/Android.mk
@@ -54,7 +54,9 @@
     dictionary.cpp \
     dic_traverse_wrapper.cpp \
     proximity_info.cpp \
+    proximity_info_params.cpp \
     proximity_info_state.cpp \
+    proximity_info_state_utils.cpp \
     unigram_dictionary.cpp \
     words_priority_queue.cpp \
     suggest/gesture_suggest.cpp \
diff --git a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
index d718290..30ca3f1 100644
--- a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
+++ b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
@@ -25,14 +25,14 @@
 namespace latinime {
 
 static jlong latinime_Keyboard_setProximityInfo(JNIEnv *env, jclass clazz, jstring localeJStr,
-        jint maxProximityCharsSize, jint displayWidth, jint displayHeight, jint gridWidth,
-        jint gridHeight, jint mostCommonkeyWidth, jintArray proximityChars, jint keyCount,
+        jint displayWidth, jint displayHeight, jint gridWidth, jint gridHeight,
+        jint mostCommonkeyWidth, jintArray proximityChars, jint keyCount,
         jintArray keyXCoordinates, jintArray keyYCoordinates, jintArray keyWidths,
         jintArray keyHeights, jintArray keyCharCodes, jfloatArray sweetSpotCenterXs,
         jfloatArray sweetSpotCenterYs, jfloatArray sweetSpotRadii) {
-    ProximityInfo *proximityInfo = new ProximityInfo(env, localeJStr, maxProximityCharsSize,
-            displayWidth, displayHeight, gridWidth, gridHeight, mostCommonkeyWidth, proximityChars,
-            keyCount, keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes,
+    ProximityInfo *proximityInfo = new ProximityInfo(env, localeJStr, displayWidth, displayHeight,
+            gridWidth, gridHeight, mostCommonkeyWidth, proximityChars, keyCount,
+            keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes,
             sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
     return reinterpret_cast<jlong>(proximityInfo);
 }
@@ -43,7 +43,7 @@
 }
 
 static JNINativeMethod sMethods[] = {
-    {"setProximityInfoNative", "(Ljava/lang/String;IIIIII[II[I[I[I[I[I[F[F[F)J",
+    {"setProximityInfoNative", "(Ljava/lang/String;IIIII[II[I[I[I[I[I[F[F[F)J",
             reinterpret_cast<void *>(latinime_Keyboard_setProximityInfo)},
     {"releaseProximityInfoNative", "(J)V", reinterpret_cast<void *>(latinime_Keyboard_release)}
 };
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index f5f5278..922a746 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -28,10 +28,13 @@
 #define AK_FORCE_INLINE inline
 #endif // defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
 
-// Must be identical to Constants.Dictionary.MAX_WORD_LENGTH in Java
+// Must be equal to Constants.Dictionary.MAX_WORD_LENGTH in Java
 #define MAX_WORD_LENGTH 48
-// Must be identical to BinaryDictionary.MAX_RESULTS in Java
+// Must be equal to BinaryDictionary.MAX_RESULTS in Java
 #define MAX_RESULTS 18
+// Must be equal to ProximityInfo.MAX_PROXIMITY_CHARS_SIZE in Java
+#define MAX_PROXIMITY_CHARS_SIZE 16
+#define ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE 2
 
 #if defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
 #include <android/log.h>
@@ -248,6 +251,10 @@
 // GCC warns about this.
 #define S_INT_MIN (-2147483647 - 1) // -(1 << 31)
 #endif
+
+#define M_PI_F 3.14159265f
+#define MAX_PERCENTILE 100
+
 // Number of base-10 digits in the largest integer + 1 to leave room for a zero terminator.
 // As such, this is the maximum number of characters will be needed to represent an int as a
 // string, including the terminator; this is used as the size of a string buffer large enough to
@@ -322,12 +329,6 @@
 #define MAX_FREQ 255
 #define MAX_BIGRAM_FREQ 15
 
-// This must be the same as ProximityInfo#MAX_PROXIMITY_CHARS_SIZE, currently it's 16.
-#define MAX_PROXIMITY_CHARS_SIZE_INTERNAL 16
-
-// This must be equal to ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE in KeyDetector.java
-#define ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE 2
-
 // Assuming locale strings such as en_US, sr-Latn etc.
 #define MAX_LOCALE_STRING_LENGTH 10
 
@@ -392,8 +393,6 @@
 template<typename T> inline T min(T a, T b) { return a < b ? a : b; }
 template<typename T> inline T max(T a, T b) { return a > b ? a : b; }
 
-#define M_PI_F 3.14159265f
-
 #define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
 
 // The ratio of neutral area radius to sweet spot radius.
diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp
index c563b07..8157fe2 100644
--- a/native/jni/src/proximity_info.cpp
+++ b/native/jni/src/proximity_info.cpp
@@ -47,15 +47,14 @@
     }
 }
 
-ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr, const int maxProximityCharsSize,
+ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr,
         const int keyboardWidth, const int keyboardHeight, const int gridWidth,
         const int gridHeight, const int mostCommonKeyWidth, const jintArray proximityChars,
         const int keyCount, const jintArray keyXCoordinates, const jintArray keyYCoordinates,
         const jintArray keyWidths, const jintArray keyHeights, const jintArray keyCharCodes,
         const jfloatArray sweetSpotCenterXs, const jfloatArray sweetSpotCenterYs,
         const jfloatArray sweetSpotRadii)
-        : MAX_PROXIMITY_CHARS_SIZE(maxProximityCharsSize), GRID_WIDTH(gridWidth),
-          GRID_HEIGHT(gridHeight), MOST_COMMON_KEY_WIDTH(mostCommonKeyWidth),
+        : GRID_WIDTH(gridWidth), GRID_HEIGHT(gridHeight), MOST_COMMON_KEY_WIDTH(mostCommonKeyWidth),
           MOST_COMMON_KEY_WIDTH_SQUARE(mostCommonKeyWidth * mostCommonKeyWidth),
           CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth),
           CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight),
@@ -65,11 +64,17 @@
                   && keyWidths && keyHeights && keyCharCodes && sweetSpotCenterXs
                   && sweetSpotCenterYs && sweetSpotRadii),
           mProximityCharsArray(new int[GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE
-                  /* proximityGridLength */]),
+                  /* proximityCharsLength */]),
           mCodeToKeyMap() {
-    const int proximityGridLength = GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE;
+    /* Let's check the input array length here to make sure */
+    const jsize proximityCharsLength = env->GetArrayLength(proximityChars);
+    if (proximityCharsLength != GRID_WIDTH * GRID_HEIGHT * MAX_PROXIMITY_CHARS_SIZE) {
+        AKLOGE("Invalid proximityCharsLength: %d", proximityCharsLength);
+        ASSERT(false);
+        return;
+    }
     if (DEBUG_PROXIMITY_INFO) {
-        AKLOGI("Create proximity info array %d", proximityGridLength);
+        AKLOGI("Create proximity info array %d", proximityCharsLength);
     }
     const jsize localeCStrUtf8Length = env->GetStringUTFLength(localeJStr);
     if (localeCStrUtf8Length >= MAX_LOCALE_STRING_LENGTH) {
@@ -78,7 +83,8 @@
     }
     memset(mLocaleStr, 0, sizeof(mLocaleStr));
     env->GetStringUTFRegion(localeJStr, 0, env->GetStringLength(localeJStr), mLocaleStr);
-    safeGetOrFillZeroIntArrayRegion(env, proximityChars, proximityGridLength, mProximityCharsArray);
+    safeGetOrFillZeroIntArrayRegion(env, proximityChars, proximityCharsLength,
+            mProximityCharsArray);
     safeGetOrFillZeroIntArrayRegion(env, keyXCoordinates, KEY_COUNT, mKeyXCoordinates);
     safeGetOrFillZeroIntArrayRegion(env, keyYCoordinates, KEY_COUNT, mKeyYCoordinates);
     safeGetOrFillZeroIntArrayRegion(env, keyWidths, KEY_COUNT, mKeyWidths);
diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h
index cd0bc32..6d571d7 100644
--- a/native/jni/src/proximity_info.h
+++ b/native/jni/src/proximity_info.h
@@ -28,7 +28,7 @@
 
 class ProximityInfo {
  public:
-    ProximityInfo(JNIEnv *env, const jstring localeJStr, const int maxProximityCharsSize,
+    ProximityInfo(JNIEnv *env, const jstring localeJStr,
             const int keyboardWidth, const int keyboardHeight, const int gridWidth,
             const int gridHeight, const int mostCommonKeyWidth, const jintArray proximityChars,
             const int keyCount, const jintArray keyXCoordinates, const jintArray keyYCoordinates,
@@ -126,7 +126,6 @@
     float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const;
     bool hasInputCoordinates() const;
 
-    const int MAX_PROXIMITY_CHARS_SIZE;
     const int GRID_WIDTH;
     const int GRID_HEIGHT;
     const int MOST_COMMON_KEY_WIDTH;
diff --git a/native/jni/src/proximity_info_params.cpp b/native/jni/src/proximity_info_params.cpp
new file mode 100644
index 0000000..45f8fb5
--- /dev/null
+++ b/native/jni/src/proximity_info_params.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include "proximity_info_params.h"
+
+namespace latinime {
+const int ProximityInfoParams::LOOKUP_RADIUS_PERCENTILE = 50;
+const int ProximityInfoParams::FIRST_POINT_TIME_OFFSET_MILLIS = 150;
+const int ProximityInfoParams::STRONG_DOUBLE_LETTER_TIME_MILLIS = 600;
+const int ProximityInfoParams::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE = 5;
+} // namespace latinime
diff --git a/native/jni/src/proximity_info_params.h b/native/jni/src/proximity_info_params.h
new file mode 100644
index 0000000..e54945e
--- /dev/null
+++ b/native/jni/src/proximity_info_params.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 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_PROXIMITY_INFO_PARAMS_H
+#define LATINIME_PROXIMITY_INFO_PARAMS_H
+
+#include "defines.h"
+
+namespace latinime {
+
+class ProximityInfoParams {
+ public:
+    static const int LOOKUP_RADIUS_PERCENTILE;
+    static const int FIRST_POINT_TIME_OFFSET_MILLIS;
+    static const int STRONG_DOUBLE_LETTER_TIME_MILLIS;
+    static const int MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE;
+ private:
+    DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoParams);
+};
+} // namespace latinime
+#endif // LATINIME_PROXIMITY_INFO_PARAMS_H
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index 31b6e4b..45b72eb 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -32,10 +32,6 @@
         1 << NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
 const float ProximityInfoState::NOT_A_DISTANCE_FLOAT = -1.0f;
 const int ProximityInfoState::NOT_A_CODE = -1;
-const int ProximityInfoState::LOOKUP_RADIUS_PERCENTILE = 50;
-const int ProximityInfoState::FIRST_POINT_TIME_OFFSET_MILLIS = 150;
-const int ProximityInfoState::STRONG_DOUBLE_LETTER_TIME_MILLIS = 600;
-const int ProximityInfoState::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE = 5;
 
 void ProximityInfoState::initInputParams(const int pointerId, const float maxPointToKeyLength,
         const ProximityInfo *proximityInfo, const int *const inputCodes, const int inputSize,
@@ -102,8 +98,14 @@
     }
 
     if (mSampledInputSize > 0 && isGeometric) {
-        refreshSpeedRates(inputSize, xCoordinates, yCoordinates, times, lastSavedInputSize);
-        refreshBeelineSpeedRates(inputSize, xCoordinates, yCoordinates, times);
+        mAverageSpeed = ProximityInfoStateUtils::refreshSpeedRates(
+                inputSize, xCoordinates, yCoordinates, times, lastSavedInputSize,
+                mSampledInputSize, &mSampledInputXs, &mSampledInputYs, &mTimes, &mLengthCache,
+                &mInputIndice, &mSpeedRates, &mDirections);
+        ProximityInfoStateUtils::refreshBeelineSpeedRates(
+                mProximityInfo->getMostCommonKeyWidth(), mAverageSpeed, inputSize,
+                xCoordinates, yCoordinates, times, mSampledInputSize, &mSampledInputXs,
+                &mSampledInputYs, &mInputIndice, &mBeelineSpeedPercentiles);
     }
 
     if (DEBUG_GEO_FULL) {
@@ -136,7 +138,11 @@
         }
         if (isGeometric) {
             // updates probabilities of skipping or mapping each key for all points.
-            updateAlignPointProbabilities(lastSavedInputSize);
+            ProximityInfoStateUtils::updateAlignPointProbabilities(
+                    mMaxPointToKeyLength, mProximityInfo->getMostCommonKeyWidth(),
+                    keyCount, lastSavedInputSize, mSampledInputSize, &mSampledInputXs,
+                    &mSampledInputYs, &mSpeedRates, &mLengthCache, &mDistanceCache_G,
+                    &mNearKeysVector, &mCharProbabilities);
 
             static const float READ_FORWORD_LENGTH_SCALE = 0.95f;
             const int readForwordLength = static_cast<int>(
@@ -206,7 +212,7 @@
                 a += 0;
                 AKLOGI("--- Primary = %c, x = %d, y = %d", primaryKey, x, y);
             }
-            for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL && proximityCodePoints[j] > 0;
+            for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE && proximityCodePoints[j] > 0;
                     ++j) {
                 const int currentCodePoint = proximityCodePoints[j];
                 const float squaredDistance =
@@ -214,10 +220,10 @@
                                 mProximityInfo->getKeyIndexOf(currentCodePoint), i) :
                                 NOT_A_DISTANCE_FLOAT;
                 if (squaredDistance >= 0.0f) {
-                    mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j] =
+                    mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
                             (int) (squaredDistance * NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
                 } else {
-                    mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j] =
+                    mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
                             (j == 0) ? EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO :
                                     PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO;
                 }
@@ -233,151 +239,6 @@
     }
 }
 
-void ProximityInfoState::refreshSpeedRates(const int inputSize, const int *const xCoordinates,
-        const int *const yCoordinates, const int *const times, const int lastSavedInputSize) {
-    // Relative speed calculation.
-    const int sumDuration = mTimes.back() - mTimes.front();
-    const int sumLength = mLengthCache.back() - mLengthCache.front();
-    mAverageSpeed = static_cast<float>(sumLength) / static_cast<float>(sumDuration);
-    mSpeedRates.resize(mSampledInputSize);
-    for (int i = lastSavedInputSize; i < mSampledInputSize; ++i) {
-        const int index = mInputIndice[i];
-        int length = 0;
-        int duration = 0;
-
-        // Calculate velocity by using distances and durations of
-        // NUM_POINTS_FOR_SPEED_CALCULATION points for both forward and backward.
-        static const int NUM_POINTS_FOR_SPEED_CALCULATION = 2;
-        for (int j = index; j < min(inputSize - 1, index + NUM_POINTS_FOR_SPEED_CALCULATION);
-                ++j) {
-            if (i < mSampledInputSize - 1 && j >= mInputIndice[i + 1]) {
-                break;
-            }
-            length += getDistanceInt(xCoordinates[j], yCoordinates[j],
-                    xCoordinates[j + 1], yCoordinates[j + 1]);
-            duration += times[j + 1] - times[j];
-        }
-        for (int j = index - 1; j >= max(0, index - NUM_POINTS_FOR_SPEED_CALCULATION); --j) {
-            if (i > 0 && j < mInputIndice[i - 1]) {
-                break;
-            }
-            // TODO: use mLengthCache instead?
-            length += getDistanceInt(xCoordinates[j], yCoordinates[j],
-                    xCoordinates[j + 1], yCoordinates[j + 1]);
-            duration += times[j + 1] - times[j];
-        }
-        if (duration == 0 || sumDuration == 0) {
-            // Cannot calculate speed; thus, it gives an average value (1.0);
-            mSpeedRates[i] = 1.0f;
-        } else {
-            const float speed = static_cast<float>(length) / static_cast<float>(duration);
-            mSpeedRates[i] = speed / mAverageSpeed;
-        }
-    }
-
-    // Direction calculation.
-    mDirections.resize(mSampledInputSize - 1);
-    for (int i = max(0, lastSavedInputSize - 1); i < mSampledInputSize - 1; ++i) {
-        mDirections[i] = getDirection(i, i + 1);
-    }
-}
-
-static const int MAX_PERCENTILE = 100;
-void ProximityInfoState::refreshBeelineSpeedRates(const int inputSize,
-        const int *const xCoordinates, const int *const yCoordinates, const int * times) {
-    if (DEBUG_SAMPLING_POINTS){
-        AKLOGI("--- refresh beeline speed rates");
-    }
-    mBeelineSpeedPercentiles.resize(mSampledInputSize);
-    for (int i = 0; i < mSampledInputSize; ++i) {
-        mBeelineSpeedPercentiles[i] = static_cast<int>(calculateBeelineSpeedRate(
-                i, inputSize, xCoordinates, yCoordinates, times) * MAX_PERCENTILE);
-    }
-}
-
-float ProximityInfoState::calculateBeelineSpeedRate(
-        const int id, const int inputSize, const int *const xCoordinates,
-        const int *const yCoordinates, const int * times) const {
-    if (mSampledInputSize <= 0 || mAverageSpeed < 0.001f) {
-        if (DEBUG_SAMPLING_POINTS){
-            AKLOGI("--- invalid state: cancel. size = %d, ave = %f",
-                    mSampledInputSize, mAverageSpeed);
-        }
-        return 1.0f;
-    }
-    const int lookupRadius =
-            mProximityInfo->getMostCommonKeyWidth() * LOOKUP_RADIUS_PERCENTILE / MAX_PERCENTILE;
-    const int x0 = mSampledInputXs[id];
-    const int y0 = mSampledInputYs[id];
-    const int actualInputIndex = mInputIndice[id];
-    int tempTime = 0;
-    int tempBeelineDistance = 0;
-    int start = actualInputIndex;
-    // lookup forward
-    while (start > 0 && tempBeelineDistance < lookupRadius) {
-        tempTime += times[start] - times[start - 1];
-        --start;
-        tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[start], yCoordinates[start]);
-    }
-    // Exclusive unless this is an edge point
-    if (start > 0 && start < actualInputIndex) {
-        ++start;
-    }
-    tempTime= 0;
-    tempBeelineDistance = 0;
-    int end = actualInputIndex;
-    // lookup backward
-    while (end < (inputSize - 1) && tempBeelineDistance < lookupRadius) {
-        tempTime += times[end + 1] - times[end];
-        ++end;
-        tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[end], yCoordinates[end]);
-    }
-    // Exclusive unless this is an edge point
-    if (end > actualInputIndex && end < (inputSize - 1)) {
-        --end;
-    }
-
-    if (start >= end) {
-        if (DEBUG_DOUBLE_LETTER) {
-            AKLOGI("--- double letter: start == end %d", start);
-        }
-        return 1.0f;
-    }
-
-    const int x2 = xCoordinates[start];
-    const int y2 = yCoordinates[start];
-    const int x3 = xCoordinates[end];
-    const int y3 = yCoordinates[end];
-    const int beelineDistance = getDistanceInt(x2, y2, x3, y3);
-    int adjustedStartTime = times[start];
-    if (start == 0 && actualInputIndex == 0 && inputSize > 1) {
-        adjustedStartTime += FIRST_POINT_TIME_OFFSET_MILLIS;
-    }
-    int adjustedEndTime = times[end];
-    if (end == (inputSize - 1) && inputSize > 1) {
-        adjustedEndTime -= FIRST_POINT_TIME_OFFSET_MILLIS;
-    }
-    const int time = adjustedEndTime - adjustedStartTime;
-    if (time <= 0) {
-        return 1.0f;
-    }
-
-    if (time >= STRONG_DOUBLE_LETTER_TIME_MILLIS){
-        return 0.0f;
-    }
-    if (DEBUG_DOUBLE_LETTER) {
-        AKLOGI("--- (%d, %d) double letter: start = %d, end = %d, dist = %d, time = %d, speed = %f,"
-                " ave = %f, val = %f, start time = %d, end time = %d",
-                id, mInputIndice[id], start, end, beelineDistance, time,
-                (static_cast<float>(beelineDistance) / static_cast<float>(time)), mAverageSpeed,
-                ((static_cast<float>(beelineDistance) / static_cast<float>(time)) / mAverageSpeed),
-                adjustedStartTime, adjustedEndTime);
-    }
-    // Offset 1%
-    // TODO: Detect double letter more smartly
-    return 0.01f + static_cast<float>(beelineDistance) / static_cast<float>(time) / mAverageSpeed;
-}
-
 bool ProximityInfoState::checkAndReturnIsContinuationPossible(const int inputSize,
         const int *const xCoordinates, const int *const yCoordinates, const int *const times,
         const bool isGeometric) const {
@@ -450,16 +311,10 @@
 }
 
 // TODO: Remove the "scale" parameter
-// This function basically converts from a length to an edit distance. Accordingly, it's obviously
-// wrong to compare with mMaxPointToKeyLength.
 float ProximityInfoState::getPointToKeyByIdLength(
         const int inputIndex, const int keyId, const float scale) const {
-    if (keyId != NOT_AN_INDEX) {
-        const int index = inputIndex * mProximityInfo->getKeyCount() + keyId;
-        return min(mDistanceCache_G[index] * scale, mMaxPointToKeyLength);
-    }
-    // If the char is not a key on the keyboard then return the max length.
-    return static_cast<float>(MAX_POINT_TO_KEY_LENGTH);
+    return ProximityInfoStateUtils::getPointToKeyByIdLength(mMaxPointToKeyLength,
+            &mDistanceCache_G, mProximityInfo->getKeyCount(), inputIndex, keyId, scale);
 }
 
 float ProximityInfoState::getPointToKeyByIdLength(const int inputIndex, const int keyId) const {
@@ -498,7 +353,7 @@
 
     // Not an exact nor an accent-alike match: search the list of close keys
     int j = 1;
-    while (j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL
+    while (j < MAX_PROXIMITY_CHARS_SIZE
             && currentCodePoints[j] > ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) {
         const bool matched = (currentCodePoints[j] == baseLowerC || currentCodePoints[j] == c);
         if (matched) {
@@ -509,10 +364,10 @@
         }
         ++j;
     }
-    if (j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL
+    if (j < MAX_PROXIMITY_CHARS_SIZE
             && currentCodePoints[j] == ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) {
         ++j;
-        while (j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL
+        while (j < MAX_PROXIMITY_CHARS_SIZE
                 && currentCodePoints[j] > ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) {
             const bool matched = (currentCodePoints[j] == baseLowerC || currentCodePoints[j] == c);
             if (matched) {
@@ -581,43 +436,8 @@
 }
 
 float ProximityInfoState::getDirection(const int index0, const int index1) const {
-    if (index0 < 0 || index0 > mSampledInputSize - 1) {
-        return 0.0f;
-    }
-    if (index1 < 0 || index1 > mSampledInputSize - 1) {
-        return 0.0f;
-    }
-    const int x1 = mSampledInputXs[index0];
-    const int y1 = mSampledInputYs[index0];
-    const int x2 = mSampledInputXs[index1];
-    const int y2 = mSampledInputYs[index1];
-    return getAngle(x1, y1, x2, y2);
-}
-
-float ProximityInfoState::getPointAngle(const int index) const {
-    if (index <= 0 || index >= mSampledInputSize - 1) {
-        return 0.0f;
-    }
-    const float previousDirection = getDirection(index - 1, index);
-    const float nextDirection = getDirection(index, index + 1);
-    const float directionDiff = getAngleDiff(previousDirection, nextDirection);
-    return directionDiff;
-}
-
-float ProximityInfoState::getPointsAngle(
-        const int index0, const int index1, const int index2) const {
-    if (index0 < 0 || index0 > mSampledInputSize - 1) {
-        return 0.0f;
-    }
-    if (index1 < 0 || index1 > mSampledInputSize - 1) {
-        return 0.0f;
-    }
-    if (index2 < 0 || index2 > mSampledInputSize - 1) {
-        return 0.0f;
-    }
-    const float previousDirection = getDirection(index0, index1);
-    const float nextDirection = getDirection(index1, index2);
-    return getAngleDiff(previousDirection, nextDirection);
+    return ProximityInfoStateUtils::getDirection(
+            &mSampledInputXs, &mSampledInputYs, index0, index1);
 }
 
 float ProximityInfoState::getLineToKeyDistance(
@@ -640,293 +460,6 @@
             keyX, keyY, x0, y0, x1, y1, extend);
 }
 
-// Updates probabilities of aligning to some keys and skipping.
-// Word suggestion should be based on this probabilities.
-void ProximityInfoState::updateAlignPointProbabilities(const int start) {
-    static const float MIN_PROBABILITY = 0.000001f;
-    static const float MAX_SKIP_PROBABILITY = 0.95f;
-    static const float SKIP_FIRST_POINT_PROBABILITY = 0.01f;
-    static const float SKIP_LAST_POINT_PROBABILITY = 0.1f;
-    static const float MIN_SPEED_RATE_FOR_SKIP_PROBABILITY = 0.15f;
-    static const float SPEED_WEIGHT_FOR_SKIP_PROBABILITY = 0.9f;
-    static const float SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY = 0.6f;
-    static const float NEAREST_DISTANCE_WEIGHT = 0.5f;
-    static const float NEAREST_DISTANCE_BIAS = 0.5f;
-    static const float NEAREST_DISTANCE_WEIGHT_FOR_LAST = 0.6f;
-    static const float NEAREST_DISTANCE_BIAS_FOR_LAST = 0.4f;
-
-    static const float ANGLE_WEIGHT = 0.90f;
-    static const float DEEP_CORNER_ANGLE_THRESHOLD = M_PI_F * 60.0f / 180.0f;
-    static const float SKIP_DEEP_CORNER_PROBABILITY = 0.1f;
-    static const float CORNER_ANGLE_THRESHOLD = M_PI_F * 30.0f / 180.0f;
-    static const float STRAIGHT_ANGLE_THRESHOLD = M_PI_F * 15.0f / 180.0f;
-    static const float SKIP_CORNER_PROBABILITY = 0.4f;
-    static const float SPEED_MARGIN = 0.1f;
-    static const float CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION = 0.0f;
-
-    const int keyCount = mProximityInfo->getKeyCount();
-    mCharProbabilities.resize(mSampledInputSize);
-    // Calculates probabilities of using a point as a correlated point with the character
-    // for each point.
-    for (int i = start; i < mSampledInputSize; ++i) {
-        mCharProbabilities[i].clear();
-        // First, calculates skip probability. Starts form MIN_SKIP_PROBABILITY.
-        // Note that all values that are multiplied to this probability should be in [0.0, 1.0];
-        float skipProbability = MAX_SKIP_PROBABILITY;
-
-        const float currentAngle = getPointAngle(i);
-        const float speedRate = getSpeedRate(i);
-
-        float nearestKeyDistance = static_cast<float>(MAX_POINT_TO_KEY_LENGTH);
-        for (int j = 0; j < keyCount; ++j) {
-            if (mNearKeysVector[i].test(j)) {
-                const float distance = getPointToKeyByIdLength(i, j);
-                if (distance < nearestKeyDistance) {
-                    nearestKeyDistance = distance;
-                }
-            }
-        }
-
-        if (i == 0) {
-            skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT
-                    + NEAREST_DISTANCE_BIAS);
-            // Promote the first point
-            skipProbability *= SKIP_FIRST_POINT_PROBABILITY;
-        } else if (i == mSampledInputSize - 1) {
-            skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT_FOR_LAST
-                    + NEAREST_DISTANCE_BIAS_FOR_LAST);
-            // Promote the last point
-            skipProbability *= SKIP_LAST_POINT_PROBABILITY;
-        } else {
-            // If the current speed is relatively slower than adjacent keys, we promote this point.
-            if (getSpeedRate(i - 1) - SPEED_MARGIN > speedRate
-                    && speedRate < getSpeedRate(i + 1) - SPEED_MARGIN) {
-                if (currentAngle < CORNER_ANGLE_THRESHOLD) {
-                    skipProbability *= min(1.0f, speedRate
-                            * SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY);
-                } else {
-                    // If the angle is small enough, we promote this point more. (e.g. pit vs put)
-                    skipProbability *= min(1.0f, speedRate * SPEED_WEIGHT_FOR_SKIP_PROBABILITY
-                            + MIN_SPEED_RATE_FOR_SKIP_PROBABILITY);
-                }
-            }
-
-            skipProbability *= min(1.0f, speedRate * nearestKeyDistance *
-                    NEAREST_DISTANCE_WEIGHT + NEAREST_DISTANCE_BIAS);
-
-            // Adjusts skip probability by a rate depending on angle.
-            // ANGLE_RATE of skipProbability is adjusted by current angle.
-            skipProbability *= (M_PI_F - currentAngle) / M_PI_F * ANGLE_WEIGHT
-                    + (1.0f - ANGLE_WEIGHT);
-            if (currentAngle > DEEP_CORNER_ANGLE_THRESHOLD) {
-                skipProbability *= SKIP_DEEP_CORNER_PROBABILITY;
-            }
-            // We assume the angle of this point is the angle for point[i], point[i - 2]
-            // and point[i - 3]. The reason why we don't use the angle for point[i], point[i - 1]
-            // and point[i - 2] is this angle can be more affected by the noise.
-            const float prevAngle = getPointsAngle(i, i - 2, i - 3);
-            if (i >= 3 && prevAngle < STRAIGHT_ANGLE_THRESHOLD
-                    && currentAngle > CORNER_ANGLE_THRESHOLD) {
-                skipProbability *= SKIP_CORNER_PROBABILITY;
-            }
-        }
-
-        // probabilities must be in [0.0, MAX_SKIP_PROBABILITY];
-        ASSERT(skipProbability >= 0.0f);
-        ASSERT(skipProbability <= MAX_SKIP_PROBABILITY);
-        mCharProbabilities[i][NOT_AN_INDEX] = skipProbability;
-
-        // Second, calculates key probabilities by dividing the rest probability
-        // (1.0f - skipProbability).
-        const float inputCharProbability = 1.0f - skipProbability;
-
-        // TODO: The variance is critical for accuracy; thus, adjusting these parameter by machine
-        // learning or something would be efficient.
-        static const float SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION = 0.3f;
-        static const float MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION = 0.25f;
-        static const float SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION = 0.5f;
-        static const float MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION = 0.15f;
-        static const float MIN_STANDERD_DIVIATION = 0.37f;
-
-        const float speedxAngleRate = min(speedRate * currentAngle / M_PI_F
-                * SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION,
-                        MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION);
-        const float speedxNearestKeyDistanceRate = min(speedRate * nearestKeyDistance
-                * SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION,
-                        MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
-        const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate + MIN_STANDERD_DIVIATION;
-
-        ProximityInfoUtils::NormalDistribution
-                distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
-        static const float PREV_DISTANCE_WEIGHT = 0.5f;
-        static const float NEXT_DISTANCE_WEIGHT = 0.6f;
-        // Summing up probability densities of all near keys.
-        float sumOfProbabilityDensities = 0.0f;
-        for (int j = 0; j < keyCount; ++j) {
-            if (mNearKeysVector[i].test(j)) {
-                float distance = sqrtf(getPointToKeyByIdLength(i, j));
-                if (i == 0 && i != mSampledInputSize - 1) {
-                    // For the first point, weighted average of distances from first point and the
-                    // next point to the key is used as a point to key distance.
-                    const float nextDistance = sqrtf(getPointToKeyByIdLength(i + 1, j));
-                    if (nextDistance < distance) {
-                        // The distance of the first point tends to bigger than continuing
-                        // points because the first touch by the user can be sloppy.
-                        // So we promote the first point if the distance of that point is larger
-                        // than the distance of the next point.
-                        distance = (distance + nextDistance * NEXT_DISTANCE_WEIGHT)
-                                / (1.0f + NEXT_DISTANCE_WEIGHT);
-                    }
-                } else if (i != 0 && i == mSampledInputSize - 1) {
-                    // For the first point, weighted average of distances from last point and
-                    // the previous point to the key is used as a point to key distance.
-                    const float previousDistance = sqrtf(getPointToKeyByIdLength(i - 1, j));
-                    if (previousDistance < distance) {
-                        // The distance of the last point tends to bigger than continuing points
-                        // because the last touch by the user can be sloppy. So we promote the
-                        // last point if the distance of that point is larger than the distance of
-                        // the previous point.
-                        distance = (distance + previousDistance * PREV_DISTANCE_WEIGHT)
-                                / (1.0f + PREV_DISTANCE_WEIGHT);
-                    }
-                }
-                // TODO: Promote the first point when the extended line from the next input is near
-                // from a key. Also, promote the last point as well.
-                sumOfProbabilityDensities += distribution.getProbabilityDensity(distance);
-            }
-        }
-
-        // Split the probability of an input point to keys that are close to the input point.
-        for (int j = 0; j < keyCount; ++j) {
-            if (mNearKeysVector[i].test(j)) {
-                float distance = sqrtf(getPointToKeyByIdLength(i, j));
-                if (i == 0 && i != mSampledInputSize - 1) {
-                    // For the first point, weighted average of distances from the first point and
-                    // the next point to the key is used as a point to key distance.
-                    const float prevDistance = sqrtf(getPointToKeyByIdLength(i + 1, j));
-                    if (prevDistance < distance) {
-                        distance = (distance + prevDistance * NEXT_DISTANCE_WEIGHT)
-                                / (1.0f + NEXT_DISTANCE_WEIGHT);
-                    }
-                } else if (i != 0 && i == mSampledInputSize - 1) {
-                    // For the first point, weighted average of distances from last point and
-                    // the previous point to the key is used as a point to key distance.
-                    const float prevDistance = sqrtf(getPointToKeyByIdLength(i - 1, j));
-                    if (prevDistance < distance) {
-                        distance = (distance + prevDistance * PREV_DISTANCE_WEIGHT)
-                                / (1.0f + PREV_DISTANCE_WEIGHT);
-                    }
-                }
-                const float probabilityDensity = distribution.getProbabilityDensity(distance);
-                const float probability = inputCharProbability * probabilityDensity
-                        / sumOfProbabilityDensities;
-                mCharProbabilities[i][j] = probability;
-            }
-        }
-    }
-
-
-    if (DEBUG_POINTS_PROBABILITY) {
-        for (int i = 0; i < mSampledInputSize; ++i) {
-            std::stringstream sstream;
-            sstream << i << ", ";
-            sstream << "(" << mSampledInputXs[i] << ", " << mSampledInputYs[i] << "), ";
-            sstream << "Speed: "<< getSpeedRate(i) << ", ";
-            sstream << "Angle: "<< getPointAngle(i) << ", \n";
-
-            for (hash_map_compat<int, float>::iterator it = mCharProbabilities[i].begin();
-                    it != mCharProbabilities[i].end(); ++it) {
-                if (it->first == NOT_AN_INDEX) {
-                    sstream << it->first
-                            << "(skip):"
-                            << it->second
-                            << "\n";
-                } else {
-                    sstream << it->first
-                            << "("
-                            << static_cast<char>(mProximityInfo->getCodePointOf(it->first))
-                            << "):"
-                            << it->second
-                            << "\n";
-                }
-            }
-            AKLOGI("%s", sstream.str().c_str());
-        }
-    }
-
-    // Decrease key probabilities of points which don't have the highest probability of that key
-    // among nearby points. Probabilities of the first point and the last point are not suppressed.
-    for (int i = max(start, 1); i < mSampledInputSize; ++i) {
-        for (int j = i + 1; j < mSampledInputSize; ++j) {
-            if (!suppressCharProbabilities(i, j)) {
-                break;
-            }
-        }
-        for (int j = i - 1; j >= max(start, 0); --j) {
-            if (!suppressCharProbabilities(i, j)) {
-                break;
-            }
-        }
-    }
-
-    // Converting from raw probabilities to log probabilities to calculate spatial distance.
-    for (int i = start; i < mSampledInputSize; ++i) {
-        for (int j = 0; j < keyCount; ++j) {
-            hash_map_compat<int, float>::iterator it = mCharProbabilities[i].find(j);
-            if (it == mCharProbabilities[i].end()){
-                mNearKeysVector[i].reset(j);
-            } else if(it->second < MIN_PROBABILITY) {
-                // Erases from near keys vector because it has very low probability.
-                mNearKeysVector[i].reset(j);
-                mCharProbabilities[i].erase(j);
-            } else {
-                it->second = -logf(it->second);
-            }
-        }
-        mCharProbabilities[i][NOT_AN_INDEX] = -logf(mCharProbabilities[i][NOT_AN_INDEX]);
-    }
-}
-
-// Decreases char probabilities of index0 by checking probabilities of a near point (index1) and
-// increases char probabilities of index1 by checking probabilities of index0.
-bool ProximityInfoState::suppressCharProbabilities(const int index0, const int index1) {
-    ASSERT(0 <= index0 && index0 < mSampledInputSize);
-    ASSERT(0 <= index1 && index1 < mSampledInputSize);
-
-    static const float SUPPRESSION_LENGTH_WEIGHT = 1.5f;
-    static const float MIN_SUPPRESSION_RATE = 0.1f;
-    static const float SUPPRESSION_WEIGHT = 0.5f;
-    static const float SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN = 0.1f;
-    static const float SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN = 0.3f;
-
-    const float keyWidthFloat = static_cast<float>(mProximityInfo->getMostCommonKeyWidth());
-    const float diff = fabsf(static_cast<float>(mLengthCache[index0] - mLengthCache[index1]));
-    if (diff > keyWidthFloat * SUPPRESSION_LENGTH_WEIGHT) {
-        return false;
-    }
-    const float suppressionRate = MIN_SUPPRESSION_RATE
-            + diff / keyWidthFloat / SUPPRESSION_LENGTH_WEIGHT * SUPPRESSION_WEIGHT;
-    for (hash_map_compat<int, float>::iterator it = mCharProbabilities[index0].begin();
-            it != mCharProbabilities[index0].end(); ++it) {
-        hash_map_compat<int, float>::iterator it2 =  mCharProbabilities[index1].find(it->first);
-        if (it2 != mCharProbabilities[index1].end() && it->second < it2->second) {
-            const float newProbability = it->second * suppressionRate;
-            const float suppression = it->second - newProbability;
-            it->second = newProbability;
-            // mCharProbabilities[index0][NOT_AN_INDEX] is the probability of skipping this point.
-            mCharProbabilities[index0][NOT_AN_INDEX] += suppression;
-
-            // Add the probability of the same key nearby index1
-            const float probabilityGain = min(suppression * SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN,
-                    mCharProbabilities[index1][NOT_AN_INDEX]
-                            * SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN);
-            it2->second += probabilityGain;
-            mCharProbabilities[index1][NOT_AN_INDEX] -= probabilityGain;
-        }
-    }
-    return true;
-}
-
 // Get a word that is detected by tracing the most probable string into codePointBuf and
 // returns probability of generating the word.
 float ProximityInfoState::getMostProbableString(int *const codePointBuf) const {
diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h
index 0f0eb7d..f2149e7 100644
--- a/native/jni/src/proximity_info_state.h
+++ b/native/jni/src/proximity_info_state.h
@@ -17,13 +17,13 @@
 #ifndef LATINIME_PROXIMITY_INFO_STATE_H
 #define LATINIME_PROXIMITY_INFO_STATE_H
 
-#include <bitset>
 #include <cstring> // for memset()
 #include <vector>
 
 #include "char_utils.h"
 #include "defines.h"
 #include "hash_map_compat.h"
+#include "proximity_info_params.h"
 #include "proximity_info_state_utils.h"
 
 namespace latinime {
@@ -32,15 +32,10 @@
 
 class ProximityInfoState {
  public:
-    typedef std::bitset<MAX_KEY_COUNT_IN_A_KEYBOARD> NearKeycodesSet;
     static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
     static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR;
     static const float NOT_A_DISTANCE_FLOAT;
     static const int NOT_A_CODE;
-    static const int LOOKUP_RADIUS_PERCENTILE;
-    static const int FIRST_POINT_TIME_OFFSET_MILLIS;
-    static const int STRONG_DOUBLE_LETTER_TIME_MILLIS;
-    static const int MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE;
 
     /////////////////////////////////////////
     // Defined in proximity_info_state.cpp //
@@ -76,7 +71,7 @@
     AK_FORCE_INLINE bool existsCodePointInProximityAt(const int index, const int c) const {
         const int *codePoints = getProximityCodePointsAt(index);
         int i = 0;
-        while (codePoints[i] > 0 && i < MAX_PROXIMITY_CHARS_SIZE_INTERNAL) {
+        while (codePoints[i] > 0 && i < MAX_PROXIMITY_CHARS_SIZE) {
             if (codePoints[i++] == c) {
                 return true;
             }
@@ -102,7 +97,7 @@
     inline int getNormalizedSquaredDistance(
             const int inputIndex, const int proximityIndex) const {
         return mNormalizedSquaredDistances[
-                inputIndex * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + proximityIndex];
+                inputIndex * MAX_PROXIMITY_CHARS_SIZE + proximityIndex];
     }
 
     inline const int *getPrimaryInputWord() const {
@@ -122,7 +117,7 @@
             if (*inputProximities != *word) {
                 return false;
             }
-            inputProximities += MAX_PROXIMITY_CHARS_SIZE_INTERNAL;
+            inputProximities += MAX_PROXIMITY_CHARS_SIZE;
             word++;
         }
         return true;
@@ -180,7 +175,8 @@
         const int beelineSpeedRate = getBeelineSpeedPercentile(id);
         if (beelineSpeedRate == 0) {
             return A_STRONG_DOUBLE_LETTER;
-        } else if (beelineSpeedRate < MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE) {
+        } else if (beelineSpeedRate
+                < ProximityInfoParams::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE) {
             return A_DOUBLE_LETTER;
         } else {
             return NOT_A_DOUBLE_LETTER;
@@ -193,10 +189,6 @@
     // get xy direction
     float getDirection(const int x, const int y) const;
 
-    float getPointAngle(const int index) const;
-    // Returns angle of three points. x, y, and z are indices.
-    float getPointsAngle(const int index0, const int index1, const int index2) const;
-
     float getMostProbableString(int *const codePointBuf) const;
 
     float getProbability(const int index, const int charCode) const;
@@ -207,7 +199,6 @@
     bool isKeyInSerchKeysAfterIndex(const int index, const int keyId) const;
  private:
     DISALLOW_COPY_AND_ASSIGN(ProximityInfoState);
-    typedef hash_map_compat<int, float> NearKeysDistanceMap;
     /////////////////////////////////////////
     // Defined in proximity_info_state.cpp //
     /////////////////////////////////////////
@@ -216,11 +207,6 @@
     float calculateSquaredDistanceFromSweetSpotCenter(
             const int keyIndex, const int inputIndex) const;
 
-    bool pushTouchPoint(const int inputIndex, const int nodeCodePoint, int x, int y, const int time,
-            const bool sample, const bool isLastPoint, const float sumAngle,
-            NearKeysDistanceMap *const currentNearKeysDistances,
-            const NearKeysDistanceMap *const prevNearKeysDistances,
-            const NearKeysDistanceMap *const prevPrevNearKeysDistances);
     /////////////////////////////////////////
     // Defined here                        //
     /////////////////////////////////////////
@@ -233,28 +219,9 @@
     inline const int *getProximityCodePointsAt(const int index) const {
         return ProximityInfoStateUtils::getProximityCodePointsAt(mInputProximities, index);
     }
-
-    float updateNearKeysDistances(const int x, const int y,
-            NearKeysDistanceMap *const currentNearKeysDistances);
-    bool isPrevLocalMin(const NearKeysDistanceMap *const currentNearKeysDistances,
-            const NearKeysDistanceMap *const prevNearKeysDistances,
-            const NearKeysDistanceMap *const prevPrevNearKeysDistances) const;
-    float getPointScore(
-            const int x, const int y, const int time, const bool last, const float nearest,
-            const float sumAngle, const NearKeysDistanceMap *const currentNearKeysDistances,
-            const NearKeysDistanceMap *const prevNearKeysDistances,
-            const NearKeysDistanceMap *const prevPrevNearKeysDistances) const;
     bool checkAndReturnIsContinuationPossible(const int inputSize, const int *const xCoordinates,
             const int *const yCoordinates, const int *const times, const bool isGeometric) const;
     void popInputData();
-    void updateAlignPointProbabilities(const int start);
-    bool suppressCharProbabilities(const int index1, const int index2);
-    void refreshSpeedRates(const int inputSize, const int *const xCoordinates,
-            const int *const yCoordinates, const int *const times, const int lastSavedInputSize);
-    void refreshBeelineSpeedRates(const int inputSize,
-            const int *const xCoordinates, const int *const yCoordinates, const int * times);
-    float calculateBeelineSpeedRate(const int id, const int inputSize,
-            const int *const xCoordinates, const int *const yCoordinates, const int * times) const;
 
     // const
     const ProximityInfo *mProximityInfo;
@@ -283,15 +250,15 @@
     // The vector for the key code set which holds nearby keys for each sampled input point
     // 1. Used to calculate the probability of the key
     // 2. Used to calculate mSearchKeysVector
-    std::vector<NearKeycodesSet> mNearKeysVector;
+    std::vector<ProximityInfoStateUtils::NearKeycodesSet> mNearKeysVector;
     // The vector for the key code set which holds nearby keys of some trailing sampled input points
     // for each sampled input point. These nearby keys contain the next characters which can be in
     // the dictionary. Specifically, currently we are looking for keys nearby trailing sampled
     // inputs including the current input point.
-    std::vector<NearKeycodesSet> mSearchKeysVector;
+    std::vector<ProximityInfoStateUtils::NearKeycodesSet> mSearchKeysVector;
     bool mTouchPositionCorrectionEnabled;
-    int mInputProximities[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH];
-    int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH];
+    int mInputProximities[MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH];
+    int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH];
     int mSampledInputSize;
     int mPrimaryInputWord[MAX_WORD_LENGTH];
 };
diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp
new file mode 100644
index 0000000..e5567f7
--- /dev/null
+++ b/native/jni/src/proximity_info_state_utils.cpp
@@ -0,0 +1,852 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include <sstream> // for debug prints
+#include <vector>
+
+#include "defines.h"
+#include "geometry_utils.h"
+#include "proximity_info.h"
+#include "proximity_info_params.h"
+#include "proximity_info_state_utils.h"
+
+namespace latinime {
+/* static */ int ProximityInfoStateUtils::updateTouchPoints(const int mostCommonKeyWidth,
+        const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
+        const int *const inputProximities, const int *const inputXCoordinates,
+        const int *const inputYCoordinates, const int *const times, const int *const pointerIds,
+        const int inputSize, const bool isGeometric, const int pointerId,
+        const int pushTouchPointStartIndex, std::vector<int> *sampledInputXs,
+        std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes,
+        std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice) {
+    if (DEBUG_SAMPLING_POINTS) {
+        if (times) {
+            for (int i = 0; i < inputSize; ++i) {
+                AKLOGI("(%d) x %d, y %d, time %d",
+                        i, xCoordinates[i], yCoordinates[i], times[i]);
+            }
+        }
+    }
+#ifdef DO_ASSERT_TEST
+    if (times) {
+        for (int i = 0; i < inputSize; ++i) {
+            if (i > 0) {
+                ASSERT(times[i] >= times[i - 1]);
+            }
+        }
+    }
+#endif
+    const bool proximityOnly = !isGeometric
+            && (inputXCoordinates[0] < 0 || inputYCoordinates[0] < 0);
+    int lastInputIndex = pushTouchPointStartIndex;
+    for (int i = lastInputIndex; i < inputSize; ++i) {
+        const int pid = pointerIds ? pointerIds[i] : 0;
+        if (pointerId == pid) {
+            lastInputIndex = i;
+        }
+    }
+    if (DEBUG_GEO_FULL) {
+        AKLOGI("Init ProximityInfoState: last input index = %d", lastInputIndex);
+    }
+    // Working space to save near keys distances for current, prev and prevprev input point.
+    NearKeysDistanceMap nearKeysDistances[3];
+    // These pointers are swapped for each inputs points.
+    NearKeysDistanceMap *currentNearKeysDistances = &nearKeysDistances[0];
+    NearKeysDistanceMap *prevNearKeysDistances = &nearKeysDistances[1];
+    NearKeysDistanceMap *prevPrevNearKeysDistances = &nearKeysDistances[2];
+    // "sumAngle" is accumulated by each angle of input points. And when "sumAngle" exceeds
+    // the threshold we save that point, reset sumAngle. This aims to keep the figure of
+    // the curve.
+    float sumAngle = 0.0f;
+
+    for (int i = pushTouchPointStartIndex; i <= lastInputIndex; ++i) {
+        // Assuming pointerId == 0 if pointerIds is null.
+        const int pid = pointerIds ? pointerIds[i] : 0;
+        if (DEBUG_GEO_FULL) {
+            AKLOGI("Init ProximityInfoState: (%d)PID = %d", i, pid);
+        }
+        if (pointerId == pid) {
+            const int c = isGeometric ?
+                    NOT_A_COORDINATE : getPrimaryCodePointAt(inputProximities, i);
+            const int x = proximityOnly ? NOT_A_COORDINATE : inputXCoordinates[i];
+            const int y = proximityOnly ? NOT_A_COORDINATE : inputYCoordinates[i];
+            const int time = times ? times[i] : -1;
+
+            if (i > 1) {
+                const float prevAngle = getAngle(
+                        inputXCoordinates[i - 2], inputYCoordinates[i - 2],
+                        inputXCoordinates[i - 1], inputYCoordinates[i - 1]);
+                const float currentAngle =
+                        getAngle(inputXCoordinates[i - 1], inputYCoordinates[i - 1], x, y);
+                sumAngle += getAngleDiff(prevAngle, currentAngle);
+            }
+
+            if (pushTouchPoint(mostCommonKeyWidth, proximityInfo, maxPointToKeyLength,
+                    i, c, x, y, time, isGeometric /* doSampling */,
+                    i == lastInputIndex, sumAngle, currentNearKeysDistances,
+                    prevNearKeysDistances, prevPrevNearKeysDistances,
+                    sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
+                    sampledInputIndice)) {
+                // Previous point information was popped.
+                NearKeysDistanceMap *tmp = prevNearKeysDistances;
+                prevNearKeysDistances = currentNearKeysDistances;
+                currentNearKeysDistances = tmp;
+            } else {
+                NearKeysDistanceMap *tmp = prevPrevNearKeysDistances;
+                prevPrevNearKeysDistances = prevNearKeysDistances;
+                prevNearKeysDistances = currentNearKeysDistances;
+                currentNearKeysDistances = tmp;
+                sumAngle = 0.0f;
+            }
+        }
+    }
+    return sampledInputXs->size();
+}
+
+/* static */ const int *ProximityInfoStateUtils::getProximityCodePointsAt(
+        const int *const inputProximities, const int index) {
+    return inputProximities + (index * MAX_PROXIMITY_CHARS_SIZE);
+}
+
+/* static */ int ProximityInfoStateUtils::getPrimaryCodePointAt(
+        const int *const inputProximities, const int index) {
+    return getProximityCodePointsAt(inputProximities, index)[0];
+}
+
+/* static */ void ProximityInfoStateUtils::popInputData(std::vector<int> *sampledInputXs,
+        std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes,
+        std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice) {
+    sampledInputXs->pop_back();
+    sampledInputYs->pop_back();
+    sampledInputTimes->pop_back();
+    sampledLengthCache->pop_back();
+    sampledInputIndice->pop_back();
+}
+
+/* static */ float ProximityInfoStateUtils::refreshSpeedRates(const int inputSize,
+        const int *const xCoordinates, const int *const yCoordinates, const int *const times,
+        const int lastSavedInputSize, const int sampledInputSize,
+        const std::vector<int> *const sampledInputXs,
+        const std::vector<int> *const sampledInputYs,
+        const std::vector<int> *const sampledInputTimes,
+        const std::vector<int> *const sampledLengthCache,
+        const std::vector<int> *const sampledInputIndice, std::vector<float> *sampledSpeedRates,
+        std::vector<float> *sampledDirections) {
+    // Relative speed calculation.
+    const int sumDuration = sampledInputTimes->back() - sampledInputTimes->front();
+    const int sumLength = sampledLengthCache->back() - sampledLengthCache->front();
+    const float averageSpeed = static_cast<float>(sumLength) / static_cast<float>(sumDuration);
+    sampledSpeedRates->resize(sampledInputSize);
+    for (int i = lastSavedInputSize; i < sampledInputSize; ++i) {
+        const int index = (*sampledInputIndice)[i];
+        int length = 0;
+        int duration = 0;
+
+        // Calculate velocity by using distances and durations of
+        // NUM_POINTS_FOR_SPEED_CALCULATION points for both forward and backward.
+        static const int NUM_POINTS_FOR_SPEED_CALCULATION = 2;
+        for (int j = index; j < min(inputSize - 1, index + NUM_POINTS_FOR_SPEED_CALCULATION);
+                ++j) {
+            if (i < sampledInputSize - 1 && j >= (*sampledInputIndice)[i + 1]) {
+                break;
+            }
+            length += getDistanceInt(xCoordinates[j], yCoordinates[j],
+                    xCoordinates[j + 1], yCoordinates[j + 1]);
+            duration += times[j + 1] - times[j];
+        }
+        for (int j = index - 1; j >= max(0, index - NUM_POINTS_FOR_SPEED_CALCULATION); --j) {
+            if (i > 0 && j < (*sampledInputIndice)[i - 1]) {
+                break;
+            }
+            // TODO: use mLengthCache instead?
+            length += getDistanceInt(xCoordinates[j], yCoordinates[j],
+                    xCoordinates[j + 1], yCoordinates[j + 1]);
+            duration += times[j + 1] - times[j];
+        }
+        if (duration == 0 || sumDuration == 0) {
+            // Cannot calculate speed; thus, it gives an average value (1.0);
+            (*sampledSpeedRates)[i] = 1.0f;
+        } else {
+            const float speed = static_cast<float>(length) / static_cast<float>(duration);
+            (*sampledSpeedRates)[i] = speed / averageSpeed;
+        }
+    }
+
+    // Direction calculation.
+    sampledDirections->resize(sampledInputSize - 1);
+    for (int i = max(0, lastSavedInputSize - 1); i < sampledInputSize - 1; ++i) {
+        (*sampledDirections)[i] = getDirection(sampledInputXs, sampledInputYs, i, i + 1);
+    }
+    return averageSpeed;
+}
+
+/* static */ void ProximityInfoStateUtils::refreshBeelineSpeedRates(const int mostCommonKeyWidth,
+        const float averageSpeed, const int inputSize, const int *const xCoordinates,
+        const int *const yCoordinates, const int *times, const int sampledInputSize,
+        const std::vector<int> *const sampledInputXs,
+        const std::vector<int> *const sampledInputYs, const std::vector<int> *const inputIndice,
+        std::vector<int> *beelineSpeedPercentiles) {
+    if (DEBUG_SAMPLING_POINTS) {
+        AKLOGI("--- refresh beeline speed rates");
+    }
+    beelineSpeedPercentiles->resize(sampledInputSize);
+    for (int i = 0; i < sampledInputSize; ++i) {
+        (*beelineSpeedPercentiles)[i] = static_cast<int>(calculateBeelineSpeedRate(
+                mostCommonKeyWidth, averageSpeed, i, inputSize, xCoordinates, yCoordinates, times,
+                sampledInputSize, sampledInputXs, sampledInputYs, inputIndice) * MAX_PERCENTILE);
+    }
+}
+
+/* static */float ProximityInfoStateUtils::getDirection(
+        const std::vector<int> *const sampledInputXs,
+        const std::vector<int> *const sampledInputYs, const int index0, const int index1) {
+    ASSERT(sampledInputXs && sampledInputYs);
+    const int sampledInputSize =sampledInputXs->size();
+    if (index0 < 0 || index0 > sampledInputSize - 1) {
+        return 0.0f;
+    }
+    if (index1 < 0 || index1 > sampledInputSize - 1) {
+        return 0.0f;
+    }
+    const int x1 = (*sampledInputXs)[index0];
+    const int y1 = (*sampledInputYs)[index0];
+    const int x2 = (*sampledInputXs)[index1];
+    const int y2 = (*sampledInputYs)[index1];
+    return getAngle(x1, y1, x2, y2);
+}
+
+// Calculating point to key distance for all near keys and returning the distance between
+// the given point and the nearest key position.
+/* static */ float ProximityInfoStateUtils::updateNearKeysDistances(
+        const ProximityInfo *const proximityInfo, const float maxPointToKeyLength, const int x,
+        const int y, NearKeysDistanceMap *const currentNearKeysDistances) {
+    static const float NEAR_KEY_THRESHOLD = 2.0f;
+
+    currentNearKeysDistances->clear();
+    const int keyCount = proximityInfo->getKeyCount();
+    float nearestKeyDistance = maxPointToKeyLength;
+    for (int k = 0; k < keyCount; ++k) {
+        const float dist = proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y);
+        if (dist < NEAR_KEY_THRESHOLD) {
+            currentNearKeysDistances->insert(std::pair<int, float>(k, dist));
+        }
+        if (nearestKeyDistance > dist) {
+            nearestKeyDistance = dist;
+        }
+    }
+    return nearestKeyDistance;
+}
+
+// Check if previous point is at local minimum position to near keys.
+/* static */ bool ProximityInfoStateUtils::isPrevLocalMin(
+        const NearKeysDistanceMap *const currentNearKeysDistances,
+        const NearKeysDistanceMap *const prevNearKeysDistances,
+        const NearKeysDistanceMap *const prevPrevNearKeysDistances) {
+    static const float MARGIN = 0.01f;
+
+    for (NearKeysDistanceMap::const_iterator it = prevNearKeysDistances->begin();
+            it != prevNearKeysDistances->end(); ++it) {
+        NearKeysDistanceMap::const_iterator itPP = prevPrevNearKeysDistances->find(it->first);
+        NearKeysDistanceMap::const_iterator itC = currentNearKeysDistances->find(it->first);
+        if ((itPP == prevPrevNearKeysDistances->end() || itPP->second > it->second + MARGIN)
+                && (itC == currentNearKeysDistances->end() || itC->second > it->second + MARGIN)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+// Calculating a point score that indicates usefulness of the point.
+/* static */ float ProximityInfoStateUtils::getPointScore(const int mostCommonKeyWidth,
+        const int x, const int y, const int time, const bool lastPoint, const float nearest,
+        const float sumAngle, const NearKeysDistanceMap *const currentNearKeysDistances,
+        const NearKeysDistanceMap *const prevNearKeysDistances,
+        const NearKeysDistanceMap *const prevPrevNearKeysDistances,
+        std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs) {
+    static const int DISTANCE_BASE_SCALE = 100;
+    static const float NEAR_KEY_THRESHOLD = 0.6f;
+    static const int CORNER_CHECK_DISTANCE_THRESHOLD_SCALE = 25;
+    static const float NOT_LOCALMIN_DISTANCE_SCORE = -1.0f;
+    static const float LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE = 1.0f;
+    static const float CORNER_ANGLE_THRESHOLD = M_PI_F * 2.0f / 3.0f;
+    static const float CORNER_SUM_ANGLE_THRESHOLD = M_PI_F / 4.0f;
+    static const float CORNER_SCORE = 1.0f;
+
+    const size_t size = sampledInputXs->size();
+    // If there is only one point, add this point. Besides, if the previous point's distance map
+    // is empty, we re-compute nearby keys distances from the current point.
+    // Note that the current point is the first point in the incremental input that needs to
+    // be re-computed.
+    if (size <= 1 || prevNearKeysDistances->empty()) {
+        return 0.0f;
+    }
+
+    const int baseSampleRate = mostCommonKeyWidth;
+    const int distPrev = getDistanceInt(sampledInputXs->back(), sampledInputYs->back(),
+            (*sampledInputXs)[size - 2], (*sampledInputYs)[size - 2]) * DISTANCE_BASE_SCALE;
+    float score = 0.0f;
+
+    // Location
+    if (!isPrevLocalMin(currentNearKeysDistances, prevNearKeysDistances,
+        prevPrevNearKeysDistances)) {
+        score += NOT_LOCALMIN_DISTANCE_SCORE;
+    } else if (nearest < NEAR_KEY_THRESHOLD) {
+        // Promote points nearby keys
+        score += LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE;
+    }
+    // Angle
+    const float angle1 = getAngle(x, y, sampledInputXs->back(), sampledInputYs->back());
+    const float angle2 = getAngle(sampledInputXs->back(), sampledInputYs->back(),
+            (*sampledInputXs)[size - 2], (*sampledInputYs)[size - 2]);
+    const float angleDiff = getAngleDiff(angle1, angle2);
+
+    // Save corner
+    if (distPrev > baseSampleRate * CORNER_CHECK_DISTANCE_THRESHOLD_SCALE
+            && (sumAngle > CORNER_SUM_ANGLE_THRESHOLD || angleDiff > CORNER_ANGLE_THRESHOLD)) {
+        score += CORNER_SCORE;
+    }
+    return score;
+}
+
+// Sampling touch point and pushing information to vectors.
+// Returning if previous point is popped or not.
+/* static */ bool ProximityInfoStateUtils::pushTouchPoint(const int mostCommonKeyWidth,
+        const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
+        const int inputIndex, const int nodeCodePoint, int x, int y,
+        const int time, const bool doSampling, const bool isLastPoint, const float sumAngle,
+        NearKeysDistanceMap *const currentNearKeysDistances,
+        const NearKeysDistanceMap *const prevNearKeysDistances,
+        const NearKeysDistanceMap *const prevPrevNearKeysDistances,
+        std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
+        std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache,
+        std::vector<int> *sampledInputIndice) {
+    static const int LAST_POINT_SKIP_DISTANCE_SCALE = 4;
+
+    size_t size = sampledInputXs->size();
+    bool popped = false;
+    if (nodeCodePoint < 0 && doSampling) {
+        const float nearest = updateNearKeysDistances(
+                proximityInfo, maxPointToKeyLength, x, y, currentNearKeysDistances);
+        const float score = getPointScore(mostCommonKeyWidth, x, y, time, isLastPoint, nearest,
+                sumAngle, currentNearKeysDistances, prevNearKeysDistances,
+                prevPrevNearKeysDistances, sampledInputXs, sampledInputYs);
+        if (score < 0) {
+            // Pop previous point because it would be useless.
+            popInputData(sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
+                    sampledInputIndice);
+            size = sampledInputXs->size();
+            popped = true;
+        } else {
+            popped = false;
+        }
+        // Check if the last point should be skipped.
+        if (isLastPoint && size > 0) {
+            if (getDistanceInt(x, y, sampledInputXs->back(),
+                    sampledInputYs->back()) * LAST_POINT_SKIP_DISTANCE_SCALE
+                            < mostCommonKeyWidth) {
+                // This point is not used because it's too close to the previous point.
+                if (DEBUG_GEO_FULL) {
+                    AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, "
+                           "width = %d", size, x, y, mSampledInputXs.back(),
+                           mSampledInputYs.back(), ProximityInfoUtils::getDistanceInt(
+                                   x, y, mSampledInputXs.back(), mSampledInputYs.back()),
+                           mProximityInfo->getMostCommonKeyWidth()
+                                   / LAST_POINT_SKIP_DISTANCE_SCALE);
+                }
+                return popped;
+            }
+        }
+    }
+
+    if (nodeCodePoint >= 0 && (x < 0 || y < 0)) {
+        const int keyId = proximityInfo->getKeyIndexOf(nodeCodePoint);
+        if (keyId >= 0) {
+            x = proximityInfo->getKeyCenterXOfKeyIdG(keyId);
+            y = proximityInfo->getKeyCenterYOfKeyIdG(keyId);
+        }
+    }
+
+    // Pushing point information.
+    if (size > 0) {
+        sampledLengthCache->push_back(
+                sampledLengthCache->back() + getDistanceInt(
+                        x, y, sampledInputXs->back(), sampledInputYs->back()));
+    } else {
+        sampledLengthCache->push_back(0);
+    }
+    sampledInputXs->push_back(x);
+    sampledInputYs->push_back(y);
+    sampledInputTimes->push_back(time);
+    sampledInputIndice->push_back(inputIndex);
+    if (DEBUG_GEO_FULL) {
+        AKLOGI("pushTouchPoint: x = %03d, y = %03d, time = %d, index = %d, popped ? %01d",
+                x, y, time, inputIndex, popped);
+    }
+    return popped;
+}
+
+/* static */ float ProximityInfoStateUtils::calculateBeelineSpeedRate(const int mostCommonKeyWidth,
+        const float averageSpeed, const int id, const int inputSize, const int *const xCoordinates,
+        const int *const yCoordinates, const int *times, const int sampledInputSize,
+        const std::vector<int> *const sampledInputXs,
+        const std::vector<int> *const sampledInputYs, const std::vector<int> *const inputIndice) {
+    if (sampledInputSize <= 0 || averageSpeed < 0.001f) {
+        if (DEBUG_SAMPLING_POINTS) {
+            AKLOGI("--- invalid state: cancel. size = %d, ave = %f",
+                    mSampledInputSize, mAverageSpeed);
+        }
+        return 1.0f;
+    }
+    const int lookupRadius = mostCommonKeyWidth
+            * ProximityInfoParams::LOOKUP_RADIUS_PERCENTILE / MAX_PERCENTILE;
+    const int x0 = (*sampledInputXs)[id];
+    const int y0 = (*sampledInputYs)[id];
+    const int actualInputIndex = (*inputIndice)[id];
+    int tempTime = 0;
+    int tempBeelineDistance = 0;
+    int start = actualInputIndex;
+    // lookup forward
+    while (start > 0 && tempBeelineDistance < lookupRadius) {
+        tempTime += times[start] - times[start - 1];
+        --start;
+        tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[start], yCoordinates[start]);
+    }
+    // Exclusive unless this is an edge point
+    if (start > 0 && start < actualInputIndex) {
+        ++start;
+    }
+    tempTime= 0;
+    tempBeelineDistance = 0;
+    int end = actualInputIndex;
+    // lookup backward
+    while (end < (inputSize - 1) && tempBeelineDistance < lookupRadius) {
+        tempTime += times[end + 1] - times[end];
+        ++end;
+        tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[end], yCoordinates[end]);
+    }
+    // Exclusive unless this is an edge point
+    if (end > actualInputIndex && end < (inputSize - 1)) {
+        --end;
+    }
+
+    if (start >= end) {
+        if (DEBUG_DOUBLE_LETTER) {
+            AKLOGI("--- double letter: start == end %d", start);
+        }
+        return 1.0f;
+    }
+
+    const int x2 = xCoordinates[start];
+    const int y2 = yCoordinates[start];
+    const int x3 = xCoordinates[end];
+    const int y3 = yCoordinates[end];
+    const int beelineDistance = getDistanceInt(x2, y2, x3, y3);
+    int adjustedStartTime = times[start];
+    if (start == 0 && actualInputIndex == 0 && inputSize > 1) {
+        adjustedStartTime += ProximityInfoParams::FIRST_POINT_TIME_OFFSET_MILLIS;
+    }
+    int adjustedEndTime = times[end];
+    if (end == (inputSize - 1) && inputSize > 1) {
+        adjustedEndTime -= ProximityInfoParams::FIRST_POINT_TIME_OFFSET_MILLIS;
+    }
+    const int time = adjustedEndTime - adjustedStartTime;
+    if (time <= 0) {
+        return 1.0f;
+    }
+
+    if (time >= ProximityInfoParams::STRONG_DOUBLE_LETTER_TIME_MILLIS){
+        return 0.0f;
+    }
+    if (DEBUG_DOUBLE_LETTER) {
+        AKLOGI("--- (%d, %d) double letter: start = %d, end = %d, dist = %d, time = %d,"
+                " speed = %f, ave = %f, val = %f, start time = %d, end time = %d",
+                id, mInputIndice[id], start, end, beelineDistance, time,
+                (static_cast<float>(beelineDistance) / static_cast<float>(time)), mAverageSpeed,
+                ((static_cast<float>(beelineDistance) / static_cast<float>(time))
+                        / mAverageSpeed), adjustedStartTime, adjustedEndTime);
+    }
+    // Offset 1%
+    // TODO: Detect double letter more smartly
+    return 0.01f + static_cast<float>(beelineDistance) / static_cast<float>(time) / averageSpeed;
+}
+
+/* static */ float ProximityInfoStateUtils::getPointAngle(
+        const std::vector<int> *const sampledInputXs,
+        const std::vector<int> *const sampledInputYs, const int index) {
+    if (!sampledInputXs || !sampledInputYs) {
+        return 0.0f;
+    }
+    const int sampledInputSize = sampledInputXs->size();
+    if (index <= 0 || index >= sampledInputSize - 1) {
+        return 0.0f;
+    }
+    const float previousDirection = getDirection(sampledInputXs, sampledInputYs, index - 1, index);
+    const float nextDirection = getDirection(sampledInputXs, sampledInputYs, index, index + 1);
+    const float directionDiff = getAngleDiff(previousDirection, nextDirection);
+    return directionDiff;
+}
+
+/* static */ float ProximityInfoStateUtils::getPointsAngle(
+        const std::vector<int> *const sampledInputXs,
+        const std::vector<int> *const sampledInputYs,
+        const int index0, const int index1, const int index2) {
+    if (!sampledInputXs || !sampledInputYs) {
+        return 0.0f;
+    }
+    const int sampledInputSize = sampledInputXs->size();
+    if (index0 < 0 || index0 > sampledInputSize - 1) {
+        return 0.0f;
+    }
+    if (index1 < 0 || index1 > sampledInputSize - 1) {
+        return 0.0f;
+    }
+    if (index2 < 0 || index2 > sampledInputSize - 1) {
+        return 0.0f;
+    }
+    const float previousDirection = getDirection(sampledInputXs, sampledInputYs, index0, index1);
+    const float nextDirection = getDirection(sampledInputXs, sampledInputYs, index1, index2);
+    return getAngleDiff(previousDirection, nextDirection);
+}
+
+// TODO: Remove the "scale" parameter
+// This function basically converts from a length to an edit distance. Accordingly, it's obviously
+// wrong to compare with mMaxPointToKeyLength.
+/* static */ float ProximityInfoStateUtils::getPointToKeyByIdLength(const float maxPointToKeyLength,
+        const std::vector<float> *const distanceCache_G, const int keyCount,
+        const int inputIndex, const int keyId, const float scale) {
+    if (keyId != NOT_AN_INDEX) {
+        const int index = inputIndex * keyCount + keyId;
+        return min((*distanceCache_G)[index] * scale, maxPointToKeyLength);
+    }
+    // If the char is not a key on the keyboard then return the max length.
+    return static_cast<float>(MAX_POINT_TO_KEY_LENGTH);
+}
+
+/* static */ float ProximityInfoStateUtils::getPointToKeyByIdLength(const float maxPointToKeyLength,
+        const std::vector<float> *const distanceCache_G, const int keyCount,
+        const int inputIndex, const int keyId) {
+    return getPointToKeyByIdLength(maxPointToKeyLength, distanceCache_G, keyCount, inputIndex,
+            keyId, 1.0f);
+}
+
+// Updates probabilities of aligning to some keys and skipping.
+// Word suggestion should be based on this probabilities.
+/* static */ void ProximityInfoStateUtils::updateAlignPointProbabilities(
+        const float maxPointToKeyLength, const int mostCommonKeyWidth, const int keyCount,
+        const int start, const int sampledInputSize, const std::vector<int> *const sampledInputXs,
+        const std::vector<int> *const sampledInputYs,
+        const std::vector<float> *const sampledSpeedRates,
+        const std::vector<int> *const sampledLengthCache,
+        const std::vector<float> *const distanceCache_G,
+        std::vector<NearKeycodesSet> *nearKeysVector,
+        std::vector<hash_map_compat<int, float> > *charProbabilities) {
+    static const float MIN_PROBABILITY = 0.000001f;
+    static const float MAX_SKIP_PROBABILITY = 0.95f;
+    static const float SKIP_FIRST_POINT_PROBABILITY = 0.01f;
+    static const float SKIP_LAST_POINT_PROBABILITY = 0.1f;
+    static const float MIN_SPEED_RATE_FOR_SKIP_PROBABILITY = 0.15f;
+    static const float SPEED_WEIGHT_FOR_SKIP_PROBABILITY = 0.9f;
+    static const float SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY = 0.6f;
+    static const float NEAREST_DISTANCE_WEIGHT = 0.5f;
+    static const float NEAREST_DISTANCE_BIAS = 0.5f;
+    static const float NEAREST_DISTANCE_WEIGHT_FOR_LAST = 0.6f;
+    static const float NEAREST_DISTANCE_BIAS_FOR_LAST = 0.4f;
+
+    static const float ANGLE_WEIGHT = 0.90f;
+    static const float DEEP_CORNER_ANGLE_THRESHOLD = M_PI_F * 60.0f / 180.0f;
+    static const float SKIP_DEEP_CORNER_PROBABILITY = 0.1f;
+    static const float CORNER_ANGLE_THRESHOLD = M_PI_F * 30.0f / 180.0f;
+    static const float STRAIGHT_ANGLE_THRESHOLD = M_PI_F * 15.0f / 180.0f;
+    static const float SKIP_CORNER_PROBABILITY = 0.4f;
+    static const float SPEED_MARGIN = 0.1f;
+    static const float CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION = 0.0f;
+
+    charProbabilities->resize(sampledInputSize);
+    // Calculates probabilities of using a point as a correlated point with the character
+    // for each point.
+    for (int i = start; i < sampledInputSize; ++i) {
+        (*charProbabilities)[i].clear();
+        // First, calculates skip probability. Starts form MIN_SKIP_PROBABILITY.
+        // Note that all values that are multiplied to this probability should be in [0.0, 1.0];
+        float skipProbability = MAX_SKIP_PROBABILITY;
+
+        const float currentAngle = getPointAngle(sampledInputXs, sampledInputYs, i);
+        const float speedRate = (*sampledSpeedRates)[i];
+
+        float nearestKeyDistance = static_cast<float>(MAX_POINT_TO_KEY_LENGTH);
+        for (int j = 0; j < keyCount; ++j) {
+            if ((*nearKeysVector)[i].test(j)) {
+                const float distance = getPointToKeyByIdLength(
+                        maxPointToKeyLength, distanceCache_G, keyCount, i, j);
+                if (distance < nearestKeyDistance) {
+                    nearestKeyDistance = distance;
+                }
+            }
+        }
+
+        if (i == 0) {
+            skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT
+                    + NEAREST_DISTANCE_BIAS);
+            // Promote the first point
+            skipProbability *= SKIP_FIRST_POINT_PROBABILITY;
+        } else if (i == sampledInputSize - 1) {
+            skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT_FOR_LAST
+                    + NEAREST_DISTANCE_BIAS_FOR_LAST);
+            // Promote the last point
+            skipProbability *= SKIP_LAST_POINT_PROBABILITY;
+        } else {
+            // If the current speed is relatively slower than adjacent keys, we promote this point.
+            if ((*sampledSpeedRates)[i - 1] - SPEED_MARGIN > speedRate
+                    && speedRate < (*sampledSpeedRates)[i + 1] - SPEED_MARGIN) {
+                if (currentAngle < CORNER_ANGLE_THRESHOLD) {
+                    skipProbability *= min(1.0f, speedRate
+                            * SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY);
+                } else {
+                    // If the angle is small enough, we promote this point more. (e.g. pit vs put)
+                    skipProbability *= min(1.0f, speedRate * SPEED_WEIGHT_FOR_SKIP_PROBABILITY
+                            + MIN_SPEED_RATE_FOR_SKIP_PROBABILITY);
+                }
+            }
+
+            skipProbability *= min(1.0f, speedRate * nearestKeyDistance *
+                    NEAREST_DISTANCE_WEIGHT + NEAREST_DISTANCE_BIAS);
+
+            // Adjusts skip probability by a rate depending on angle.
+            // ANGLE_RATE of skipProbability is adjusted by current angle.
+            skipProbability *= (M_PI_F - currentAngle) / M_PI_F * ANGLE_WEIGHT
+                    + (1.0f - ANGLE_WEIGHT);
+            if (currentAngle > DEEP_CORNER_ANGLE_THRESHOLD) {
+                skipProbability *= SKIP_DEEP_CORNER_PROBABILITY;
+            }
+            // We assume the angle of this point is the angle for point[i], point[i - 2]
+            // and point[i - 3]. The reason why we don't use the angle for point[i], point[i - 1]
+            // and point[i - 2] is this angle can be more affected by the noise.
+            const float prevAngle = getPointsAngle(sampledInputXs, sampledInputYs, i, i - 2, i - 3);
+            if (i >= 3 && prevAngle < STRAIGHT_ANGLE_THRESHOLD
+                    && currentAngle > CORNER_ANGLE_THRESHOLD) {
+                skipProbability *= SKIP_CORNER_PROBABILITY;
+            }
+        }
+
+        // probabilities must be in [0.0, MAX_SKIP_PROBABILITY];
+        ASSERT(skipProbability >= 0.0f);
+        ASSERT(skipProbability <= MAX_SKIP_PROBABILITY);
+        (*charProbabilities)[i][NOT_AN_INDEX] = skipProbability;
+
+        // Second, calculates key probabilities by dividing the rest probability
+        // (1.0f - skipProbability).
+        const float inputCharProbability = 1.0f - skipProbability;
+
+        // TODO: The variance is critical for accuracy; thus, adjusting these parameter by machine
+        // learning or something would be efficient.
+        static const float SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION = 0.3f;
+        static const float MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION = 0.25f;
+        static const float SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION = 0.5f;
+        static const float MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION = 0.15f;
+        static const float MIN_STANDERD_DIVIATION = 0.37f;
+
+        const float speedxAngleRate = min(speedRate * currentAngle / M_PI_F
+                * SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION,
+                        MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION);
+        const float speedxNearestKeyDistanceRate = min(speedRate * nearestKeyDistance
+                * SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION,
+                        MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
+        const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate + MIN_STANDERD_DIVIATION;
+
+        ProximityInfoUtils::NormalDistribution
+                distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
+        static const float PREV_DISTANCE_WEIGHT = 0.5f;
+        static const float NEXT_DISTANCE_WEIGHT = 0.6f;
+        // Summing up probability densities of all near keys.
+        float sumOfProbabilityDensities = 0.0f;
+        for (int j = 0; j < keyCount; ++j) {
+            if ((*nearKeysVector)[i].test(j)) {
+                float distance = sqrtf(getPointToKeyByIdLength(
+                        maxPointToKeyLength, distanceCache_G, keyCount, i, j));
+                if (i == 0 && i != sampledInputSize - 1) {
+                    // For the first point, weighted average of distances from first point and the
+                    // next point to the key is used as a point to key distance.
+                    const float nextDistance = sqrtf(getPointToKeyByIdLength(
+                            maxPointToKeyLength, distanceCache_G, keyCount, i + 1, j));
+                    if (nextDistance < distance) {
+                        // The distance of the first point tends to bigger than continuing
+                        // points because the first touch by the user can be sloppy.
+                        // So we promote the first point if the distance of that point is larger
+                        // than the distance of the next point.
+                        distance = (distance + nextDistance * NEXT_DISTANCE_WEIGHT)
+                                / (1.0f + NEXT_DISTANCE_WEIGHT);
+                    }
+                } else if (i != 0 && i == sampledInputSize - 1) {
+                    // For the first point, weighted average of distances from last point and
+                    // the previous point to the key is used as a point to key distance.
+                    const float previousDistance = sqrtf(getPointToKeyByIdLength(
+                            maxPointToKeyLength, distanceCache_G, keyCount, i - 1, j));
+                    if (previousDistance < distance) {
+                        // The distance of the last point tends to bigger than continuing points
+                        // because the last touch by the user can be sloppy. So we promote the
+                        // last point if the distance of that point is larger than the distance of
+                        // the previous point.
+                        distance = (distance + previousDistance * PREV_DISTANCE_WEIGHT)
+                                / (1.0f + PREV_DISTANCE_WEIGHT);
+                    }
+                }
+                // TODO: Promote the first point when the extended line from the next input is near
+                // from a key. Also, promote the last point as well.
+                sumOfProbabilityDensities += distribution.getProbabilityDensity(distance);
+            }
+        }
+
+        // Split the probability of an input point to keys that are close to the input point.
+        for (int j = 0; j < keyCount; ++j) {
+            if ((*nearKeysVector)[i].test(j)) {
+                float distance = sqrtf(getPointToKeyByIdLength(
+                        maxPointToKeyLength, distanceCache_G, keyCount, i, j));
+                if (i == 0 && i != sampledInputSize - 1) {
+                    // For the first point, weighted average of distances from the first point and
+                    // the next point to the key is used as a point to key distance.
+                    const float prevDistance = sqrtf(getPointToKeyByIdLength(
+                            maxPointToKeyLength, distanceCache_G, keyCount, i + 1, j));
+                    if (prevDistance < distance) {
+                        distance = (distance + prevDistance * NEXT_DISTANCE_WEIGHT)
+                                / (1.0f + NEXT_DISTANCE_WEIGHT);
+                    }
+                } else if (i != 0 && i == sampledInputSize - 1) {
+                    // For the first point, weighted average of distances from last point and
+                    // the previous point to the key is used as a point to key distance.
+                    const float prevDistance = sqrtf(getPointToKeyByIdLength(
+                            maxPointToKeyLength, distanceCache_G, keyCount, i - 1, j));
+                    if (prevDistance < distance) {
+                        distance = (distance + prevDistance * PREV_DISTANCE_WEIGHT)
+                                / (1.0f + PREV_DISTANCE_WEIGHT);
+                    }
+                }
+                const float probabilityDensity = distribution.getProbabilityDensity(distance);
+                const float probability = inputCharProbability * probabilityDensity
+                        / sumOfProbabilityDensities;
+                (*charProbabilities)[i][j] = probability;
+            }
+        }
+    }
+
+
+    if (DEBUG_POINTS_PROBABILITY) {
+        for (int i = 0; i < sampledInputSize; ++i) {
+            std::stringstream sstream;
+            sstream << i << ", ";
+            sstream << "(" << (*sampledInputXs)[i] << ", " << (*sampledInputYs)[i] << "), ";
+            sstream << "Speed: "<< (*sampledSpeedRates)[i] << ", ";
+            sstream << "Angle: "<< getPointAngle(sampledInputXs, sampledInputYs, i) << ", \n";
+
+            for (hash_map_compat<int, float>::iterator it = (*charProbabilities)[i].begin();
+                    it != (*charProbabilities)[i].end(); ++it) {
+                if (it->first == NOT_AN_INDEX) {
+                    sstream << it->first
+                            << "(skip):"
+                            << it->second
+                            << "\n";
+                } else {
+                    sstream << it->first
+                            << "("
+                            //<< static_cast<char>(mProximityInfo->getCodePointOf(it->first))
+                            << "):"
+                            << it->second
+                            << "\n";
+                }
+            }
+            AKLOGI("%s", sstream.str().c_str());
+        }
+    }
+
+    // Decrease key probabilities of points which don't have the highest probability of that key
+    // among nearby points. Probabilities of the first point and the last point are not suppressed.
+    for (int i = max(start, 1); i < sampledInputSize; ++i) {
+        for (int j = i + 1; j < sampledInputSize; ++j) {
+            if (!suppressCharProbabilities(
+                    mostCommonKeyWidth, sampledInputSize, sampledLengthCache, i, j,
+                    charProbabilities)) {
+                break;
+            }
+        }
+        for (int j = i - 1; j >= max(start, 0); --j) {
+            if (!suppressCharProbabilities(
+                    mostCommonKeyWidth, sampledInputSize, sampledLengthCache, i, j,
+                    charProbabilities)) {
+                break;
+            }
+        }
+    }
+
+    // Converting from raw probabilities to log probabilities to calculate spatial distance.
+    for (int i = start; i < sampledInputSize; ++i) {
+        for (int j = 0; j < keyCount; ++j) {
+            hash_map_compat<int, float>::iterator it = (*charProbabilities)[i].find(j);
+            if (it == (*charProbabilities)[i].end()){
+                (*nearKeysVector)[i].reset(j);
+            } else if(it->second < MIN_PROBABILITY) {
+                // Erases from near keys vector because it has very low probability.
+                (*nearKeysVector)[i].reset(j);
+                (*charProbabilities)[i].erase(j);
+            } else {
+                it->second = -logf(it->second);
+            }
+        }
+        (*charProbabilities)[i][NOT_AN_INDEX] = -logf((*charProbabilities)[i][NOT_AN_INDEX]);
+    }
+}
+
+// Decreases char probabilities of index0 by checking probabilities of a near point (index1) and
+// increases char probabilities of index1 by checking probabilities of index0.
+/* static */ bool ProximityInfoStateUtils::suppressCharProbabilities(const int mostCommonKeyWidth,
+        const int sampledInputSize, const std::vector<int> *const lengthCache,
+        const int index0, const int index1,
+        std::vector<hash_map_compat<int, float> > *charProbabilities) {
+    ASSERT(0 <= index0 && index0 < sampledInputSize);
+    ASSERT(0 <= index1 && index1 < sampledInputSize);
+
+    static const float SUPPRESSION_LENGTH_WEIGHT = 1.5f;
+    static const float MIN_SUPPRESSION_RATE = 0.1f;
+    static const float SUPPRESSION_WEIGHT = 0.5f;
+    static const float SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN = 0.1f;
+    static const float SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN = 0.3f;
+
+    const float keyWidthFloat = static_cast<float>(mostCommonKeyWidth);
+    const float diff = fabsf(static_cast<float>((*lengthCache)[index0] - (*lengthCache)[index1]));
+    if (diff > keyWidthFloat * SUPPRESSION_LENGTH_WEIGHT) {
+        return false;
+    }
+    const float suppressionRate = MIN_SUPPRESSION_RATE
+            + diff / keyWidthFloat / SUPPRESSION_LENGTH_WEIGHT * SUPPRESSION_WEIGHT;
+    for (hash_map_compat<int, float>::iterator it = (*charProbabilities)[index0].begin();
+            it != (*charProbabilities)[index0].end(); ++it) {
+        hash_map_compat<int, float>::iterator it2 =  (*charProbabilities)[index1].find(it->first);
+        if (it2 != (*charProbabilities)[index1].end() && it->second < it2->second) {
+            const float newProbability = it->second * suppressionRate;
+            const float suppression = it->second - newProbability;
+            it->second = newProbability;
+            // mCharProbabilities[index0][NOT_AN_INDEX] is the probability of skipping this point.
+            (*charProbabilities)[index0][NOT_AN_INDEX] += suppression;
+
+            // Add the probability of the same key nearby index1
+            const float probabilityGain = min(suppression * SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN,
+                    (*charProbabilities)[index1][NOT_AN_INDEX]
+                            * SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN);
+            it2->second += probabilityGain;
+            (*charProbabilities)[index1][NOT_AN_INDEX] -= probabilityGain;
+        }
+    }
+    return true;
+}
+} // namespace latinime
diff --git a/native/jni/src/proximity_info_state_utils.h b/native/jni/src/proximity_info_state_utils.h
index 53b992a..8241eaf 100644
--- a/native/jni/src/proximity_info_state_utils.h
+++ b/native/jni/src/proximity_info_state_utils.h
@@ -17,16 +17,21 @@
 #ifndef LATINIME_PROXIMITY_INFO_STATE_UTILS_H
 #define LATINIME_PROXIMITY_INFO_STATE_UTILS_H
 
+#include <bitset>
 #include <vector>
 
 #include "defines.h"
-#include "geometry_utils.h"
 #include "hash_map_compat.h"
-#include "proximity_info.h"
 
 namespace latinime {
+class ProximityInfo;
+class ProximityInfoParams;
+
 class ProximityInfoStateUtils {
  public:
+    typedef hash_map_compat<int, float> NearKeysDistanceMap;
+    typedef std::bitset<MAX_KEY_COUNT_IN_A_KEYBOARD> NearKeycodesSet;
+
     static int updateTouchPoints(const int mostCommonKeyWidth,
             const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
             const int *const inputProximities,
@@ -35,285 +40,87 @@
             const bool isGeometric, const int pointerId, const int pushTouchPointStartIndex,
             std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
             std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache,
-            std::vector<int> *sampledInputIndice) {
-        if (DEBUG_SAMPLING_POINTS) {
-            if (times) {
-                for (int i = 0; i < inputSize; ++i) {
-                    AKLOGI("(%d) x %d, y %d, time %d",
-                            i, xCoordinates[i], yCoordinates[i], times[i]);
-                }
-            }
-        }
-#ifdef DO_ASSERT_TEST
-        if (times) {
-            for (int i = 0; i < inputSize; ++i) {
-                if (i > 0) {
-                    ASSERT(times[i] >= times[i - 1]);
-                }
-            }
-        }
-#endif
-        const bool proximityOnly = !isGeometric
-                && (inputXCoordinates[0] < 0 || inputYCoordinates[0] < 0);
-        int lastInputIndex = pushTouchPointStartIndex;
-        for (int i = lastInputIndex; i < inputSize; ++i) {
-            const int pid = pointerIds ? pointerIds[i] : 0;
-            if (pointerId == pid) {
-                lastInputIndex = i;
-            }
-        }
-        if (DEBUG_GEO_FULL) {
-            AKLOGI("Init ProximityInfoState: last input index = %d", lastInputIndex);
-        }
-        // Working space to save near keys distances for current, prev and prevprev input point.
-        NearKeysDistanceMap nearKeysDistances[3];
-        // These pointers are swapped for each inputs points.
-        NearKeysDistanceMap *currentNearKeysDistances = &nearKeysDistances[0];
-        NearKeysDistanceMap *prevNearKeysDistances = &nearKeysDistances[1];
-        NearKeysDistanceMap *prevPrevNearKeysDistances = &nearKeysDistances[2];
-        // "sumAngle" is accumulated by each angle of input points. And when "sumAngle" exceeds
-        // the threshold we save that point, reset sumAngle. This aims to keep the figure of
-        // the curve.
-        float sumAngle = 0.0f;
-
-        for (int i = pushTouchPointStartIndex; i <= lastInputIndex; ++i) {
-            // Assuming pointerId == 0 if pointerIds is null.
-            const int pid = pointerIds ? pointerIds[i] : 0;
-            if (DEBUG_GEO_FULL) {
-                AKLOGI("Init ProximityInfoState: (%d)PID = %d", i, pid);
-            }
-            if (pointerId == pid) {
-                const int c = isGeometric ?
-                        NOT_A_COORDINATE : getPrimaryCodePointAt(inputProximities, i);
-                const int x = proximityOnly ? NOT_A_COORDINATE : inputXCoordinates[i];
-                const int y = proximityOnly ? NOT_A_COORDINATE : inputYCoordinates[i];
-                const int time = times ? times[i] : -1;
-
-                if (i > 1) {
-                    const float prevAngle = getAngle(
-                            inputXCoordinates[i - 2], inputYCoordinates[i - 2],
-                            inputXCoordinates[i - 1], inputYCoordinates[i - 1]);
-                    const float currentAngle =
-                            getAngle(inputXCoordinates[i - 1], inputYCoordinates[i - 1], x, y);
-                    sumAngle += getAngleDiff(prevAngle, currentAngle);
-                }
-
-                if (pushTouchPoint(mostCommonKeyWidth, proximityInfo, maxPointToKeyLength,
-                        i, c, x, y, time, isGeometric /* do sampling */,
-                        i == lastInputIndex, sumAngle, currentNearKeysDistances,
-                        prevNearKeysDistances, prevPrevNearKeysDistances,
-                        sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
-                        sampledInputIndice)) {
-                    // Previous point information was popped.
-                    NearKeysDistanceMap *tmp = prevNearKeysDistances;
-                    prevNearKeysDistances = currentNearKeysDistances;
-                    currentNearKeysDistances = tmp;
-                } else {
-                    NearKeysDistanceMap *tmp = prevPrevNearKeysDistances;
-                    prevPrevNearKeysDistances = prevNearKeysDistances;
-                    prevNearKeysDistances = currentNearKeysDistances;
-                    currentNearKeysDistances = tmp;
-                    sumAngle = 0.0f;
-                }
-            }
-        }
-        return sampledInputXs->size();
-    }
-
-    static const int *getProximityCodePointsAt(
-            const int *const inputProximities, const int index) {
-        return inputProximities + (index * MAX_PROXIMITY_CHARS_SIZE_INTERNAL);
-    }
-
-    static int getPrimaryCodePointAt(const int *const inputProximities, const int index) {
-        return getProximityCodePointsAt(inputProximities, index)[0];
-    }
-
+            std::vector<int> *sampledInputIndice);
+    static const int *getProximityCodePointsAt(const int *const inputProximities, const int index);
+    static int getPrimaryCodePointAt(const int *const inputProximities, const int index);
     static void popInputData(std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
             std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache,
-            std::vector<int> *sampledInputIndice) {
-        sampledInputXs->pop_back();
-        sampledInputYs->pop_back();
-        sampledInputTimes->pop_back();
-        sampledLengthCache->pop_back();
-        sampledInputIndice->pop_back();
-    }
+            std::vector<int> *sampledInputIndice);
+    static float refreshSpeedRates(const int inputSize, const int *const xCoordinates,
+            const int *const yCoordinates, const int *const times, const int lastSavedInputSize,
+            const int sampledInputSize, const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs,
+            const std::vector<int> *const sampledInputTimes,
+            const std::vector<int> *const sampledLengthCache,
+            const std::vector<int> *const sampledInputIndice,
+            std::vector<float> *sampledSpeedRates, std::vector<float> *sampledDirections);
+    static void refreshBeelineSpeedRates(const int mostCommonKeyWidth,  const float averageSpeed,
+            const int inputSize, const int *const xCoordinates, const int *const yCoordinates,
+            const int *times, const int sampledInputSize,
+            const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs, const std::vector<int> *const inputIndice,
+            std::vector<int> *beelineSpeedPercentiles);
+    static float getDirection(const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs, const int index0, const int index1);
+    static void updateAlignPointProbabilities(
+            const float maxPointToKeyLength, const int mostCommonKeyWidth, const int keyCount,
+            const int start, const int sampledInputSize,
+            const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs,
+            const std::vector<float> *const sampledSpeedRates,
+            const std::vector<int> *const sampledLengthCache,
+            const std::vector<float> *const distanceCache_G,
+            std::vector<NearKeycodesSet> *nearKeysVector,
+            std::vector<hash_map_compat<int, float> > *charProbabilities);
+    static float getPointToKeyByIdLength(const float maxPointToKeyLength,
+            const std::vector<float> *const distanceCache_G, const int keyCount,
+            const int inputIndex, const int keyId, const float scale);
+    static float getPointToKeyByIdLength(const float maxPointToKeyLength,
+            const std::vector<float> *const distanceCache_G, const int keyCount,
+            const int inputIndex, const int keyId);
 
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoStateUtils);
 
-    typedef hash_map_compat<int, float> NearKeysDistanceMap;
-
-    // Calculating point to key distance for all near keys and returning the distance between
-    // the given point and the nearest key position.
     static float updateNearKeysDistances(const ProximityInfo *const proximityInfo,
             const float maxPointToKeyLength, const int x, const int y,
-            NearKeysDistanceMap *const currentNearKeysDistances) {
-        static const float NEAR_KEY_THRESHOLD = 2.0f;
-
-        currentNearKeysDistances->clear();
-        const int keyCount = proximityInfo->getKeyCount();
-        float nearestKeyDistance = maxPointToKeyLength;
-        for (int k = 0; k < keyCount; ++k) {
-            const float dist = proximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y);
-            if (dist < NEAR_KEY_THRESHOLD) {
-                currentNearKeysDistances->insert(std::pair<int, float>(k, dist));
-            }
-            if (nearestKeyDistance > dist) {
-                nearestKeyDistance = dist;
-            }
-        }
-        return nearestKeyDistance;
-    }
-
-    // Check if previous point is at local minimum position to near keys.
+            NearKeysDistanceMap *const currentNearKeysDistances);
     static bool isPrevLocalMin(const NearKeysDistanceMap *const currentNearKeysDistances,
             const NearKeysDistanceMap *const prevNearKeysDistances,
-            const NearKeysDistanceMap *const prevPrevNearKeysDistances) {
-        static const float MARGIN = 0.01f;
-
-        for (NearKeysDistanceMap::const_iterator it = prevNearKeysDistances->begin();
-            it != prevNearKeysDistances->end(); ++it) {
-            NearKeysDistanceMap::const_iterator itPP = prevPrevNearKeysDistances->find(it->first);
-            NearKeysDistanceMap::const_iterator itC = currentNearKeysDistances->find(it->first);
-            if ((itPP == prevPrevNearKeysDistances->end() || itPP->second > it->second + MARGIN)
-                    && (itC == currentNearKeysDistances->end()
-                            || itC->second > it->second + MARGIN)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // Calculating a point score that indicates usefulness of the point.
-    static float getPointScore(const int mostCommonKeyWidth,
-            const int x, const int y, const int time, const bool lastPoint, const float nearest,
-            const float sumAngle, const NearKeysDistanceMap *const currentNearKeysDistances,
+            const NearKeysDistanceMap *const prevPrevNearKeysDistances);
+    static float getPointScore(const int mostCommonKeyWidth, const int x, const int y,
+            const int time, const bool lastPoint, const float nearest, const float sumAngle,
+            const NearKeysDistanceMap *const currentNearKeysDistances,
             const NearKeysDistanceMap *const prevNearKeysDistances,
             const NearKeysDistanceMap *const prevPrevNearKeysDistances,
-            std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs) {
-        static const int DISTANCE_BASE_SCALE = 100;
-        static const float NEAR_KEY_THRESHOLD = 0.6f;
-        static const int CORNER_CHECK_DISTANCE_THRESHOLD_SCALE = 25;
-        static const float NOT_LOCALMIN_DISTANCE_SCORE = -1.0f;
-        static const float LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE = 1.0f;
-        static const float CORNER_ANGLE_THRESHOLD = M_PI_F * 2.0f / 3.0f;
-        static const float CORNER_SUM_ANGLE_THRESHOLD = M_PI_F / 4.0f;
-        static const float CORNER_SCORE = 1.0f;
-
-        const size_t size = sampledInputXs->size();
-        // If there is only one point, add this point. Besides, if the previous point's distance map
-        // is empty, we re-compute nearby keys distances from the current point.
-        // Note that the current point is the first point in the incremental input that needs to
-        // be re-computed.
-        if (size <= 1 || prevNearKeysDistances->empty()) {
-            return 0.0f;
-        }
-
-        const int baseSampleRate = mostCommonKeyWidth;
-        const int distPrev = getDistanceInt(
-                sampledInputXs->back(), sampledInputYs->back(),
-                (*sampledInputXs)[size - 2], (*sampledInputYs)[size - 2]) * DISTANCE_BASE_SCALE;
-        float score = 0.0f;
-
-        // Location
-        if (!isPrevLocalMin(currentNearKeysDistances, prevNearKeysDistances,
-            prevPrevNearKeysDistances)) {
-            score += NOT_LOCALMIN_DISTANCE_SCORE;
-        } else if (nearest < NEAR_KEY_THRESHOLD) {
-            // Promote points nearby keys
-            score += LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE;
-        }
-        // Angle
-        const float angle1 = getAngle(x, y, sampledInputXs->back(), sampledInputYs->back());
-        const float angle2 = getAngle(sampledInputXs->back(), sampledInputYs->back(),
-                (*sampledInputXs)[size - 2], (*sampledInputYs)[size - 2]);
-        const float angleDiff = getAngleDiff(angle1, angle2);
-
-        // Save corner
-        if (distPrev > baseSampleRate * CORNER_CHECK_DISTANCE_THRESHOLD_SCALE
-                && (sumAngle > CORNER_SUM_ANGLE_THRESHOLD || angleDiff > CORNER_ANGLE_THRESHOLD)) {
-            score += CORNER_SCORE;
-        }
-        return score;
-    }
-
-    // Sampling touch point and pushing information to vectors.
-    // Returning if previous point is popped or not.
+            std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs);
     static bool pushTouchPoint(const int mostCommonKeyWidth,
             const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
-            const int inputIndex, const int nodeCodePoint, int x, int y,
-            const int time, const bool sample, const bool isLastPoint, const float sumAngle,
+            const int inputIndex, const int nodeCodePoint, int x, int y, const int time,
+            const bool doSampling, const bool isLastPoint, const float sumAngle,
             NearKeysDistanceMap *const currentNearKeysDistances,
             const NearKeysDistanceMap *const prevNearKeysDistances,
             const NearKeysDistanceMap *const prevPrevNearKeysDistances,
             std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
             std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache,
-            std::vector<int> *sampledInputIndice) {
-        static const int LAST_POINT_SKIP_DISTANCE_SCALE = 4;
-
-        size_t size = sampledInputXs->size();
-        bool popped = false;
-        if (nodeCodePoint < 0 && sample) {
-            const float nearest = updateNearKeysDistances(
-                    proximityInfo, maxPointToKeyLength, x, y, currentNearKeysDistances);
-            const float score = getPointScore(mostCommonKeyWidth, x, y, time, isLastPoint, nearest,
-                    sumAngle, currentNearKeysDistances, prevNearKeysDistances,
-                    prevPrevNearKeysDistances, sampledInputXs, sampledInputYs);
-            if (score < 0) {
-                // Pop previous point because it would be useless.
-                popInputData(sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
-                        sampledInputIndice);
-                size = sampledInputXs->size();
-                popped = true;
-            } else {
-                popped = false;
-            }
-            // Check if the last point should be skipped.
-            if (isLastPoint && size > 0) {
-                if (getDistanceInt(x, y, sampledInputXs->back(),
-                        sampledInputYs->back()) * LAST_POINT_SKIP_DISTANCE_SCALE
-                                < mostCommonKeyWidth) {
-                    // This point is not used because it's too close to the previous point.
-                    if (DEBUG_GEO_FULL) {
-                        AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, "
-                               "width = %d", size, x, y, mSampledInputXs.back(),
-                               mSampledInputYs.back(), ProximityInfoUtils::getDistanceInt(
-                                       x, y, mSampledInputXs.back(), mSampledInputYs.back()),
-                               mProximityInfo->getMostCommonKeyWidth()
-                                       / LAST_POINT_SKIP_DISTANCE_SCALE);
-                    }
-                    return popped;
-                }
-            }
-        }
-
-        if (nodeCodePoint >= 0 && (x < 0 || y < 0)) {
-            const int keyId = proximityInfo->getKeyIndexOf(nodeCodePoint);
-            if (keyId >= 0) {
-                x = proximityInfo->getKeyCenterXOfKeyIdG(keyId);
-                y = proximityInfo->getKeyCenterYOfKeyIdG(keyId);
-            }
-        }
-
-        // Pushing point information.
-        if (size > 0) {
-            sampledLengthCache->push_back(
-                    sampledLengthCache->back() + getDistanceInt(
-                            x, y, sampledInputXs->back(), sampledInputYs->back()));
-        } else {
-            sampledLengthCache->push_back(0);
-        }
-        sampledInputXs->push_back(x);
-        sampledInputYs->push_back(y);
-        sampledInputTimes->push_back(time);
-        sampledInputIndice->push_back(inputIndex);
-        if (DEBUG_GEO_FULL) {
-            AKLOGI("pushTouchPoint: x = %03d, y = %03d, time = %d, index = %d, popped ? %01d",
-                    x, y, time, inputIndex, popped);
-        }
-        return popped;
-    }
+            std::vector<int> *sampledInputIndice);
+    static float calculateBeelineSpeedRate(const int mostCommonKeyWidth, const float averageSpeed,
+            const int id, const int inputSize, const int *const xCoordinates,
+            const int *const yCoordinates, const int *times, const int sampledInputSize,
+            const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs,
+            const std::vector<int> *const inputIndice);
+    static float getPointAngle(
+            const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs, const int index);
+    static float getPointsAngle(
+            const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs,
+            const int index0, const int index1, const int index2);
+    static bool suppressCharProbabilities(const int mostCommonKeyWidth,
+            const int sampledInputSize, const std::vector<int> *const lengthCache,
+            const int index0, const int index1,
+            std::vector<hash_map_compat<int, float> > *charProbabilities);
 };
 } // namespace latinime
 #endif // LATINIME_PROXIMITY_INFO_STATE_UTILS_H
diff --git a/native/jni/src/proximity_info_utils.h b/native/jni/src/proximity_info_utils.h
index 0930207..24917d8 100644
--- a/native/jni/src/proximity_info_utils.h
+++ b/native/jni/src/proximity_info_utils.h
@@ -61,7 +61,7 @@
             const int primaryKey = inputCodes[i];
             const int x = inputXCoordinates[i];
             const int y = inputYCoordinates[i];
-            int *proximities = &inputProximities[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL];
+            int *proximities = &inputProximities[i * MAX_PROXIMITY_CHARS_SIZE];
             calculateProximities(keyXCoordinates, keyYCoordinates, keyWidths, keyHeights,
                     proximityCharsArray, maxProximityCharsSize, cellHeight, cellWidth, gridWidth,
                     mostCommonKeyWidth, keyCount, x, y, primaryKey, localeStr, codeToKeyMap,
@@ -71,9 +71,9 @@
         if (DEBUG_PROXIMITY_CHARS) {
             for (int i = 0; i < inputSize; ++i) {
                 AKLOGI("---");
-                for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL; ++j) {
+                for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE; ++j) {
                     int proximityChar =
-                            inputProximities[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j];
+                            inputProximities[i * MAX_PROXIMITY_CHARS_SIZE + j];
                     proximityChar += 0;
                     AKLOGI("--- (%d)%c", i, proximityChar);
                 }
