diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 1bb0313..942068a 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -219,6 +219,8 @@
 #define DEBUG_CORRECTION false
 #define DEBUG_CORRECTION_FREQ false
 #define DEBUG_WORDS_PRIORITY_QUEUE false
+#define DEBUG_SAMPLING_POINTS true
+#define DEBUG_POINTS_PROBABILITY true
 
 #ifdef FLAG_FULL_DBG
 #define DEBUG_GEO_FULL true
@@ -239,6 +241,8 @@
 #define DEBUG_CORRECTION false
 #define DEBUG_CORRECTION_FREQ false
 #define DEBUG_WORDS_PRIORITY_QUEUE false
+#define DEBUG_SAMPLING_POINTS false
+#define DEBUG_POINTS_PROBABILITY false
 
 #define DEBUG_GEO_FULL false
 
diff --git a/native/jni/src/geometry_utils.h b/native/jni/src/geometry_utils.h
index 31359e1..734fbef 100644
--- a/native/jni/src/geometry_utils.h
+++ b/native/jni/src/geometry_utils.h
@@ -85,5 +85,24 @@
     }
     return getSquaredDistanceFloat(x, y, projectionX, projectionY);
 }
+
+// Normal distribution N(u, sigma^2).
+struct NormalDistribution {
+    NormalDistribution(const float u, const float sigma)
+            : mU(u), mSigma(sigma),
+              mPreComputedNonExpPart(1.0f / sqrtf(2.0f * M_PI_F * sigma * sigma)),
+              mPreComputedExponentPart(-1.0f / (2.0f * sigma * sigma)) {}
+
+    float getProbabilityDensity(const float x) {
+        const float shiftedX = x - mU;
+        return mPreComputedNonExpPart * expf(mPreComputedExponentPart * SQUARE_FLOAT(shiftedX));
+    }
+private:
+    DISALLOW_IMPLICIT_CONSTRUCTORS(NormalDistribution);
+    float mU; // mean value
+    float mSigma; // standard deviation
+    float mPreComputedNonExpPart; // = 1 / sqrt(2 * PI * sigma^2)
+    float mPreComputedExponentPart; // = -1 / (2 * sigma^2)
+};
 } // namespace latinime
 #endif // LATINIME_GEOMETRY_UTILS_H
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index 0151743..90e3671 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <cstring> // for memset()
+#include <sstream> // for debug prints
 #include <stdint.h>
 
 #define LOG_TAG "LatinIME: proximity_info_state.cpp"
@@ -105,6 +106,7 @@
         mDistanceCache.clear();
         mNearKeysVector.clear();
         mRelativeSpeeds.clear();
+        mCharProbabilities.clear();
     }
     if (DEBUG_GEO_FULL) {
         AKLOGI("Init ProximityInfoState: reused points =  %d, last input size = %d",
@@ -161,34 +163,42 @@
     }
 
     if (mInputSize > 0 && isGeometric) {
-        int sumDuration = mTimes.back() - mTimes.front();
-        int sumLength = mLengthCache.back() - mLengthCache.front();
-        float averageSpeed = static_cast<float>(sumLength) / static_cast<float>(sumDuration);
+        const int sumDuration = mTimes.back() - mTimes.front();
+        const int sumLength = mLengthCache.back() - mLengthCache.front();
+        const float averageSpeed = static_cast<float>(sumLength) / static_cast<float>(sumDuration);
         mRelativeSpeeds.resize(mInputSize);
         for (int i = lastSavedInputSize; i < mInputSize; ++i) {
             const int index = mInputIndice[i];
             int length = 0;
             int duration = 0;
-            if (index == 0 && index < inputSize - 1) {
-                length = getDistanceInt(xCoordinates[index], yCoordinates[index],
-                        xCoordinates[index + 1], yCoordinates[index + 1]);
-                duration = times[index + 1] - times[index];
-            } else if (index == inputSize - 1 && index > 0) {
-                length = getDistanceInt(xCoordinates[index - 1], yCoordinates[index - 1],
-                        xCoordinates[index], yCoordinates[index]);
-                duration = times[index] - times[index - 1];
-            } else if (0 < index && index < inputSize - 1) {
-                length = getDistanceInt(xCoordinates[index - 1], yCoordinates[index - 1],
-                        xCoordinates[index], yCoordinates[index])
-                        + getDistanceInt(xCoordinates[index], yCoordinates[index],
-                                xCoordinates[index + 1], yCoordinates[index + 1]);
-                duration = times[index + 1] - times[index - 1];
-            } else {
-                length = 0;
-                duration = 1;
+
+            // 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 = 1;
+            for (int j = index; j < min(inputSize - 1, index + NUM_POINTS_FOR_SPEED_CALCULATION);
+                    ++j) {
+                if (i < mInputSize - 1 && j >= mInputIndice[i + 1]) {
+                    break;
+                }
+                length += getDistanceInt(xCoordinates[j], yCoordinates[j],
+                        xCoordinates[j + 1], yCoordinates[j + 1]);
+                duration += times[j + 1] - times[j];
             }
-            const float speed = static_cast<float>(length) / static_cast<float>(duration);
-            mRelativeSpeeds[i] = speed / averageSpeed;
+            for (int j = index - 1; j >= max(0, index - NUM_POINTS_FOR_SPEED_CALCULATION); --j) {
+                if (i > 0 && j < mInputIndice[i - 1]) {
+                    break;
+                }
+                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);
+                mRelativeSpeeds[i] = 1.0f;
+            } else {
+                const float speed = static_cast<float>(length) / static_cast<float>(duration);
+                mRelativeSpeeds[i] = speed / averageSpeed;
+            }
         }
     }
 
@@ -215,7 +225,7 @@
         static const float READ_FORWORD_LENGTH_SCALE = 0.95f;
         const int readForwordLength = static_cast<int>(
                 hypotf(mProximityInfo->getKeyboardWidth(), mProximityInfo->getKeyboardHeight())
-                * READ_FORWORD_LENGTH_SCALE);
+                        * READ_FORWORD_LENGTH_SCALE);
         for (int i = 0; i < mInputSize; ++i) {
             if (DEBUG_GEO_FULL) {
                 AKLOGI("Sampled(%d): x = %d, y = %d, time = %d", i, mInputXs[i], mInputYs[i],
@@ -230,6 +240,27 @@
         }
     }
 
+    if (DEBUG_SAMPLING_POINTS) {
+        std::stringstream originalX, originalY, sampledX, sampledY;
+        for (int i = 0; i < inputSize; ++i) {
+            originalX << xCoordinates[i];
+            originalY << yCoordinates[i];
+            if (i != inputSize - 1) {
+                originalX << ";";
+                originalY << ";";
+            }
+        }
+        for (int i = 0; i < mInputSize; ++i) {
+            sampledX << mInputXs[i];
+            sampledY << mInputYs[i];
+            if (i != mInputSize - 1) {
+                sampledX << ";";
+                sampledY << ";";
+            }
+        }
+        AKLOGI("\n%s, %s,\n%s, %s,\n", originalX.str().c_str(), originalY.str().c_str(),
+                sampledX.str().c_str(), sampledY.str().c_str());
+    }
     // end
     ///////////////////////
 
@@ -276,6 +307,10 @@
     if (DEBUG_GEO_FULL) {
         AKLOGI("ProximityState init finished: %d points out of %d", mInputSize, inputSize);
     }
+    if (isGeometric && mInputSize > 0) {
+        // updates probabilities of skipping or mapping each key for all points.
+        updateAlignPointProbabilities();
+    }
 }
 
 bool ProximityInfoState::checkAndReturnIsContinuationPossible(const int inputSize,
@@ -294,7 +329,7 @@
 // the given point and the nearest key position.
 float ProximityInfoState::updateNearKeysDistances(const int x, const int y,
         NearKeysDistanceMap *const currentNearKeysDistances) {
-    static const float NEAR_KEY_THRESHOLD = 4.0f;
+    static const float NEAR_KEY_THRESHOLD = 1.7f;
 
     currentNearKeysDistances->clear();
     const int keyCount = mProximityInfo->getKeyCount();
@@ -315,7 +350,7 @@
 bool ProximityInfoState::isPrevLocalMin(const NearKeysDistanceMap *const currentNearKeysDistances,
         const NearKeysDistanceMap *const prevNearKeysDistances,
         const NearKeysDistanceMap *const prevPrevNearKeysDistances) const {
-    static const float MARGIN = 0.01f;
+    static const float MARGIN = 0.03f;
 
     for (NearKeysDistanceMap::const_iterator it = prevNearKeysDistances->begin();
         it != prevNearKeysDistances->end(); ++it) {
@@ -336,18 +371,20 @@
         const NearKeysDistanceMap *const prevNearKeysDistances,
         const NearKeysDistanceMap *const prevPrevNearKeysDistances) const {
     static const int DISTANCE_BASE_SCALE = 100;
-    static const int SAVE_DISTANCE_SCALE = 200;
-    static const int SKIP_DISTANCE_SCALE = 25;
-    static const int CHECK_LOCALMIN_DISTANCE_THRESHOLD_SCALE = 40;
-    static const int STRAIGHT_SKIP_DISTANCE_THRESHOLD_SCALE = 50;
-    static const int CORNER_CHECK_DISTANCE_THRESHOLD_SCALE = 27;
+    static const int SAVE_DISTANCE_SCALE = 500;
+    static const int SKIP_DISTANCE_SCALE = 10;
+    static const float NEAR_KEY_THRESHOLD = 1.0f;
+    static const int CHECK_LOCALMIN_DISTANCE_THRESHOLD_SCALE = 100;
+    static const int STRAIGHT_SKIP_DISTANCE_THRESHOLD_SCALE = 200;
+    static const int CORNER_CHECK_DISTANCE_THRESHOLD_SCALE = 20;
     static const float SAVE_DISTANCE_SCORE = 2.0f;
     static const float SKIP_DISTANCE_SCORE = -1.0f;
-    static const float CHECK_LOCALMIN_DISTANCE_SCORE = -1.0f;
+    static const float NOT_LOCALMIN_DISTANCE_SCORE = -1.0f;
+    static const float LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE = 2.0f;
     static const float STRAIGHT_ANGLE_THRESHOLD = M_PI_F / 36.0f;
     static const float STRAIGHT_SKIP_NEAREST_DISTANCE_THRESHOLD = 0.5f;
     static const float STRAIGHT_SKIP_SCORE = -1.0f;
-    static const float CORNER_ANGLE_THRESHOLD = M_PI_F / 2.0f;
+    static const float CORNER_ANGLE_THRESHOLD = M_PI_F / 6.0f;
     static const float CORNER_SCORE = 1.0f;
 
     const std::size_t size = mInputXs.size();
@@ -373,7 +410,10 @@
     if (distPrev < baseSampleRate * CHECK_LOCALMIN_DISTANCE_THRESHOLD_SCALE) {
         if (!isPrevLocalMin(currentNearKeysDistances, prevNearKeysDistances,
             prevPrevNearKeysDistances)) {
-            score += CHECK_LOCALMIN_DISTANCE_SCORE;
+            score += NOT_LOCALMIN_DISTANCE_SCORE;
+        } else if (nearest < NEAR_KEY_THRESHOLD) {
+            // Promote points nearby keys
+            score += LOCALMIN_DISTANCE_AND_NEAR_TO_KEY_SCORE;
         }
     }
     // Angle
@@ -402,7 +442,8 @@
         NearKeysDistanceMap *const currentNearKeysDistances,
         const NearKeysDistanceMap *const prevNearKeysDistances,
         const NearKeysDistanceMap *const prevPrevNearKeysDistances) {
-    static const float LAST_POINT_SKIP_DISTANCE_SCALE = 0.25f;
+    static const int LAST_POINT_SKIP_DISTANCE_SCALE = 4;
+    static const int LAST_AND_NOT_NEAREST_POINT_SKIP_DISTANCE_SCALE = 2;
 
     size_t size = mInputXs.size();
     bool popped = false;
@@ -419,33 +460,38 @@
             popped = false;
         }
         // Check if the last point should be skipped.
-        if (isLastPoint) {
-            if (size > 0 && getDistanceFloat(x, y, mInputXs.back(), mInputYs.back())
-                    < mProximityInfo->getMostCommonKeyWidth() * LAST_POINT_SKIP_DISTANCE_SCALE) {
+        if (isLastPoint && size > 0) {
+            const int lastPointsDistance = getDistanceInt(x, y, mInputXs.back(), mInputYs.back());
+            if (lastPointsDistance * LAST_POINT_SKIP_DISTANCE_SCALE
+                    < mProximityInfo->getMostCommonKeyWidth()) {
+                // 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 = %f, "
-                           "width = %f", size, x, y, mInputXs.back(), mInputYs.back(),
-                           getDistanceFloat(x, y, mInputXs.back(), mInputYs.back()),
+                    AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, "
+                           "width = %d", size, x, y, mInputXs.back(), mInputYs.back(),
+                           getDistanceInt(x, y, mInputXs.back(), mInputYs.back()),
                            mProximityInfo->getMostCommonKeyWidth()
-                                   * LAST_POINT_SKIP_DISTANCE_SCALE);
+                                   / LAST_POINT_SKIP_DISTANCE_SCALE);
                 }
                 return popped;
-            } else if (size > 1) {
-                int minChar = 0;
-                float minDist = mMaxPointToKeyLength;
+            } else if (lastPointsDistance * LAST_AND_NOT_NEAREST_POINT_SKIP_DISTANCE_SCALE
+                    < mProximityInfo->getMostCommonKeyWidth()) {
+                int nearestChar = 0;
+                float nearestCharDistance = mMaxPointToKeyLength;
                 for (NearKeysDistanceMap::const_iterator it = currentNearKeysDistances->begin();
                         it != currentNearKeysDistances->end(); ++it) {
-                    if (minDist > it->second) {
-                        minChar = it->first;
-                        minDist = it->second;
+                    if (nearestCharDistance > it->second) {
+                        nearestChar = it->first;
+                        nearestCharDistance = it->second;
                     }
                 }
                 NearKeysDistanceMap::const_iterator itPP =
-                        prevNearKeysDistances->find(minChar);
-                if (itPP != prevNearKeysDistances->end() && minDist > itPP->second) {
+                        prevNearKeysDistances->find(nearestChar);
+                if (itPP != prevNearKeysDistances->end() && nearestCharDistance > itPP->second) {
+                    // The nearest key of the penultimate point is same as the nearest key of the
+                    // last point. So, we don't need to use the last point.
                     if (DEBUG_GEO_FULL) {
                         AKLOGI("p1: char = %c, minDist = %f, prevNear key minDist = %f",
-                                minChar, itPP->second, minDist);
+                                nearestChar, itPP->second, nearestCharDistance);
                     }
                     return popped;
                 }
@@ -503,18 +549,21 @@
     return 0;
 }
 
-float ProximityInfoState::getPointToKeyLength(const int inputIndex, const int codePoint,
-        const float scale) const {
-    const int keyId = mProximityInfo->getKeyIndexOf(codePoint);
-    if (keyId != NOT_AN_INDEX) {
-        const int index = inputIndex * mProximityInfo->getKeyCount() + keyId;
-        return min(mDistanceCache[index] * scale, mMaxPointToKeyLength);
-    }
+float ProximityInfoState::getPointToKeyLength(const int inputIndex, const int codePoint) const {
     if (isSkippableChar(codePoint)) {
         return 0.0f;
     }
+    const int keyId = mProximityInfo->getKeyIndexOf(codePoint);
+    return getPointToKeyByIdLength(inputIndex, keyId);
+}
+
+float ProximityInfoState::getPointToKeyByIdLength(const int inputIndex, const int keyId) const {
+    if (keyId != NOT_AN_INDEX) {
+        const int index = inputIndex * mProximityInfo->getKeyCount() + keyId;
+        return min(mDistanceCache[index], mMaxPointToKeyLength);
+    }
     // If the char is not a key on the keyboard then return the max length.
-    return MAX_POINT_TO_KEY_LENGTH;
+    return static_cast<float>(MAX_POINT_TO_KEY_LENGTH);
 }
 
 int ProximityInfoState::getSpaceY() const {
@@ -565,4 +614,217 @@
     mInputIndice.pop_back();
 }
 
+float ProximityInfoState::getPointAngle(const int index) const {
+    if (index <= 0 || index >= mInputSize - 1) {
+        return 0.0f;
+    }
+    const int x = mInputXs[index];
+    const int y = mInputYs[index];
+    const int nextX = mInputXs[index + 1];
+    const int nextY = mInputYs[index + 1];
+    const int previousX = mInputXs[index - 1];
+    const int previousY = mInputYs[index - 1];
+    const float previousDirection = getAngle(previousX, previousY, x, y);
+    const float nextDirection = getAngle(x, y, nextX, nextY);
+    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 > mInputSize - 1) {
+        return 0.0f;
+    }
+    if (index1 < 0 || index1 > mInputSize - 1) {
+        return 0.0f;
+    }
+    if (index2 < 0 || index2 > mInputSize - 1) {
+        return 0.0f;
+    }
+    const int x0 = mInputXs[index0];
+    const int y0 = mInputYs[index0];
+    const int x1 = mInputXs[index1];
+    const int y1 = mInputYs[index1];
+    const int x2 = mInputXs[index2];
+    const int y2 = mInputYs[index2];
+    const float previousDirection = getAngle(x0, y0, x1, y1);
+    const float nextDirection = getAngle(x1, y1, x2, y2);
+    const float directionDiff = getAngleDiff(previousDirection, nextDirection);
+    return directionDiff;
+}
+
+// Updates probabilities of aligning to some keys and skipping.
+// Word suggestion should be based on this probabilities.
+void ProximityInfoState::updateAlignPointProbabilities() {
+    static const float MIN_PROBABILITY = 0.00001f;
+    static const float SKIP_FIRST_POINT_PROBABILITY = 0.01f;
+    static const float SKIP_LAST_POINT_PROBABILITY = 0.1f;
+    static const float ANGLE_RATE = 0.8f;
+    static const float DEEP_CORNER_ANGLE_THRESHOLD = M_PI_F * 0.5f;
+    static const float SKIP_DEEP_CORNER_PROBABILITY = 0.3f;
+    static const float CORNER_ANGLE_THRESHOLD = M_PI_F * 35.0f / 180.0f;
+    static const float STRAIGHT_ANGLE_THRESHOLD = M_PI_F * 15.0f / 180.0f;
+    static const float SKIP_CORNER_PROBABILITY = 0.5f;
+    static const float SLOW_STRAIGHT_WEIGHT = 0.8f;
+    static const float CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION = 0.0f;
+
+    mCharProbabilities.resize(mInputSize);
+    // Calculates probabilities of using a point as a correlated point with the character
+    // for each point.
+    for (int i = 0; i < mInputSize; ++i) {
+        // First, calculates skip probability. Starts form 100%.
+        // Note that all values that are multiplied to this probability should be in [0.0, 1.0];
+        float skipProbability = 1.0f;
+        const float speed = getRelativeSpeed(i);
+
+        // Adjusts skip probability by a rate depending on speed.
+        skipProbability *= min(1.0f, speed);
+        if (i == 0) {
+            skipProbability *= SKIP_FIRST_POINT_PROBABILITY;
+        } else if (i == mInputSize - 1) {
+            skipProbability *= SKIP_LAST_POINT_PROBABILITY;
+        } else {
+            const float currentAngle = getPointAngle(i);
+
+            // Adjusts skip probability by a rate depending on angle.
+            // ANGLE_RATE of skipProbability is adjusted by current angle.
+            skipProbability *= max((M_PI_F - currentAngle) / M_PI_F, 0.0f) * ANGLE_RATE +
+                    (1.0f - ANGLE_RATE);
+            if (currentAngle > DEEP_CORNER_ANGLE_THRESHOLD) {
+                skipProbability *= SKIP_DEEP_CORNER_PROBABILITY;
+            }
+            const float prevAngle = getPointsAngle(i, i - 1, i - 2);
+            if (prevAngle < STRAIGHT_ANGLE_THRESHOLD && currentAngle > CORNER_ANGLE_THRESHOLD) {
+                skipProbability *= SKIP_CORNER_PROBABILITY;
+            }
+            if (currentAngle < STRAIGHT_ANGLE_THRESHOLD) {
+                // Adjusts skip probability by speed.
+                skipProbability *= min(1.0f, speed * SLOW_STRAIGHT_WEIGHT);
+            }
+        }
+
+        // probabilities must be in [0.0, 1.0];
+        ASSERT(skipProbability >= 0.0f);
+        ASSERT(skipProbability <= 1.0f);
+
+        mCharProbabilities[i][NOT_AN_INDEX] = skipProbability;
+        // Second, calculates key probabilities by dividing the rest probability
+        // (1.0f - skipProbability).
+        const float inputCharProbability = 1.0f - skipProbability;
+        // Summing up probability densities of all near keys.
+        float sumOfProbabilityDensityOfNearKeys = 0.0f;
+        const float sigma = speed;
+        NormalDistribution distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
+        for (int j = 0; j < mProximityInfo->getKeyCount(); ++j) {
+            if (mNearKeysVector[i].test(j)) {
+                const float distance = sqrtf(getPointToKeyByIdLength(i, j));
+                sumOfProbabilityDensityOfNearKeys += distribution.getProbabilityDensity(distance);
+            }
+        }
+        for (int j = 0; j < mProximityInfo->getKeyCount(); ++j) {
+            if (mNearKeysVector[i].test(j)) {
+                const float distance = sqrtf(getPointToKeyByIdLength(i, j));
+                const float probabilityDessity = distribution.getProbabilityDensity(distance);
+                // inputCharProbability divided to the probability for each near key.
+                const float probability = inputCharProbability * probabilityDessity
+                        / sumOfProbabilityDensityOfNearKeys;
+                if (probability > MIN_PROBABILITY) {
+                    mCharProbabilities[i][j] = probability;
+                }
+            }
+        }
+    }
+
+    // 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 = 1; i < mInputSize - 1; ++i) {
+        // forward
+        for (int j = i + 1; j < mInputSize; ++j) {
+            if (suppressCharProbabilities(i, j)) {
+                break;
+            }
+        }
+        // backward
+        for (int j = i - 1; j >= 0; --j) {
+            if (suppressCharProbabilities(i, j)) {
+                break;
+            }
+        }
+    }
+
+    if (DEBUG_POINTS_PROBABILITY) {
+        for (int i = 0; i < mInputSize; ++i) {
+            std::stringstream sstream;
+            sstream << i << ", ";
+            for (hash_map_compat<int, float>::iterator it = mCharProbabilities[i].begin();
+                    it != mCharProbabilities[i].end(); ++it) {
+                sstream << it->first
+                        << "("
+                        << static_cast<char>(mProximityInfo->getCodePointOf(it->first))
+                        << "):"
+                        << it->second
+                        << ", ";
+            }
+            AKLOGI("%s", sstream.str().c_str());
+        }
+    }
+}
+
+// Decreases char probabilities of index0 by checking probabilities of a near point (index1).
+bool ProximityInfoState::suppressCharProbabilities(const int index0, const int index1) {
+    ASSERT(0 <= index0 && index0 < mInputSize);
+    ASSERT(0 <= index1 && index1 < mInputSize);
+    static const float SUPPRESSION_LENGTH_WEIGHT = 1.5f;
+    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;
+    }
+    // Summing up decreased amount of probabilities from 0%.
+    float sumOfAdjustedProbabilities = 0.0f;
+    const float suppressionRate = diff / keyWidthFloat / SUPPRESSION_LENGTH_WEIGHT;
+    for (hash_map_compat<int, float>::iterator it = mCharProbabilities[index0].begin();
+            it != mCharProbabilities[index0].end(); ++it) {
+        hash_map_compat<int, float>::const_iterator it2 =
+                mCharProbabilities[index1].find(it->first);
+        if (it2 != mCharProbabilities[index1].end() && it->second < it2->second) {
+            const float newProbability = it->second * suppressionRate;
+            sumOfAdjustedProbabilities += it->second - newProbability;
+            it->second = newProbability;
+        }
+    }
+    // All decreased amount of probabilities are added to the probability of skipping.
+    mCharProbabilities[index0][NOT_AN_INDEX] += sumOfAdjustedProbabilities;
+    return true;
+}
+
+// Get a word that is detected by tracing highest probability sequence into charBuf and returns
+// probability of generating the word.
+float ProximityInfoState::getHighestProbabilitySequence(uint16_t *const charBuf) const {
+    int buf[mInputSize];
+    // Maximum probabilities of each point are multiplied to 100%.
+    float probability = 1.0f;
+    // TODO: Current implementation is greedy algorithm. DP would be efficient for many cases.
+    for (int i = 0; i < mInputSize; ++i) {
+        float maxProbability = 0.0f;
+        for (hash_map_compat<int, float>::const_iterator it = mCharProbabilities[i].begin();
+                it != mCharProbabilities[i].end(); ++it) {
+            if (it->second > maxProbability) {
+                maxProbability = it->second;
+                buf[i] = it->first;
+            }
+        }
+        probability *= maxProbability;
+    }
+    int index = 0;
+    for (int i = 0; i < mInputSize && index < MAX_WORD_LENGTH_INTERNAL - 1; ++i) {
+        if (buf[i] != NOT_AN_INDEX) {
+            charBuf[index] = mProximityInfo->getCodePointOf(buf[i]);
+            index++;
+        }
+    }
+    charBuf[index] = '\0';
+    return probability;
+}
+
 } // namespace latinime
diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h
index c1ec76c..7286e5e 100644
--- a/native/jni/src/proximity_info_state.h
+++ b/native/jni/src/proximity_info_state.h
@@ -55,8 +55,8 @@
               mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0), mLocaleStr(),
               mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
               mIsContinuationPossible(false), mInputXs(), mInputYs(), mTimes(), mInputIndice(),
-              mDistanceCache(), mLengthCache(), mRelativeSpeeds(), mNearKeysVector(),
-              mTouchPositionCorrectionEnabled(false), mInputSize(0) {
+              mDistanceCache(), mLengthCache(), mRelativeSpeeds(), mCharProbabilities(),
+              mNearKeysVector(), mTouchPositionCorrectionEnabled(false), mInputSize(0) {
         memset(mInputCodes, 0, sizeof(mInputCodes));
         memset(mNormalizedSquaredDistances, 0, sizeof(mNormalizedSquaredDistances));
         memset(mPrimaryInputWord, 0, sizeof(mPrimaryInputWord));
@@ -213,7 +213,9 @@
         return mIsContinuationPossible;
     }
 
-    float getPointToKeyLength(const int inputIndex, const int charCode, const float scale) const;
+    float getPointToKeyLength(const int inputIndex, const int charCode) const;
+
+    float getPointToKeyByIdLength(const int inputIndex, const int keyId) const;
 
     int getSpaceY() const;
 
@@ -223,6 +225,12 @@
     float getRelativeSpeed(const int index) const {
         return mRelativeSpeeds[index];
     }
+
+    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 getHighestProbabilitySequence(uint16_t *const charBuf) const;
  private:
     DISALLOW_COPY_AND_ASSIGN(ProximityInfoState);
     typedef hash_map_compat<int, float> NearKeysDistanceMap;
@@ -265,6 +273,8 @@
     bool checkAndReturnIsContinuationPossible(const int inputSize, const int *const xCoordinates,
             const int *const yCoordinates, const int *const times);
     void popInputData();
+    void updateAlignPointProbabilities();
+    bool suppressCharProbabilities(const int index1, const int index2);
 
     // const
     const ProximityInfo *mProximityInfo;
@@ -286,6 +296,8 @@
     std::vector<float> mDistanceCache;
     std::vector<int>  mLengthCache;
     std::vector<float> mRelativeSpeeds;
+    // probabilities of skipping or mapping to a key for each point.
+    std::vector<hash_map_compat<int, float> > mCharProbabilities;
     std::vector<NearKeycodesSet> mNearKeysVector;
     bool mTouchPositionCorrectionEnabled;
     int32_t mInputCodes[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL];
