diff --git a/native/jni/src/additional_proximity_chars.h b/native/jni/src/additional_proximity_chars.h
index 21eb0bf..a88fd6c 100644
--- a/native/jni/src/additional_proximity_chars.h
+++ b/native/jni/src/additional_proximity_chars.h
@@ -45,7 +45,7 @@
     }
 
  public:
-    static int getAdditionalCharsSize(const char *localeStr, const int c) {
+    static int getAdditionalCharsSize(const char *const localeStr, const int c) {
         if (!isEnLocale(localeStr)) {
             return 0;
         }
@@ -65,7 +65,7 @@
         }
     }
 
-    static const int *getAdditionalChars(const char *localeStr, const int c) {
+    static const int *getAdditionalChars(const char *const localeStr, const int c) {
         if (!isEnLocale(localeStr)) {
             return 0;
         }
diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp
index 9b99554..08646af 100644
--- a/native/jni/src/proximity_info.cpp
+++ b/native/jni/src/proximity_info.cpp
@@ -94,11 +94,6 @@
     delete[] mProximityCharsArray;
 }
 
-inline int ProximityInfo::getStartIndexFromCoordinates(const int x, const int y) const {
-    return ((y / CELL_HEIGHT) * GRID_WIDTH + (x / CELL_WIDTH))
-            * MAX_PROXIMITY_CHARS_SIZE;
-}
-
 bool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
     if (x < 0 || y < 0) {
         if (DEBUG_DICT) {
@@ -109,7 +104,8 @@
         return false;
     }
 
-    const int startIndex = getStartIndexFromCoordinates(x, y);
+    const int startIndex = ProximityInfoUtils::getStartIndexFromCoordinates(
+            MAX_PROXIMITY_CHARS_SIZE, x, y, CELL_HEIGHT, CELL_WIDTH, GRID_WIDTH);
     if (DEBUG_PROXIMITY_INFO) {
         AKLOGI("hasSpaceProximity: index %d, %d, %d", startIndex, x, y);
     }
@@ -147,100 +143,6 @@
     return getSquaredDistanceFloat(centerX, centerY, touchX, touchY) / SQUARE_FLOAT(keyWidth);
 }
 
-int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) const {
-    if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case
-    const int left = mKeyXCoordinates[keyId];
-    const int top = mKeyYCoordinates[keyId];
-    const int right = left + mKeyWidths[keyId];
-    const int bottom = top + mKeyHeights[keyId];
-    const int edgeX = x < left ? left : (x > right ? right : x);
-    const int edgeY = y < top ? top : (y > bottom ? bottom : y);
-    const int dx = x - edgeX;
-    const int dy = y - edgeY;
-    return dx * dx + dy * dy;
-}
-
-void ProximityInfo::calculateNearbyKeyCodes(
-        const int x, const int y, const int primaryKey, int *inputCodes) const {
-    int *proximityCharsArray = mProximityCharsArray;
-    int insertPos = 0;
-    inputCodes[insertPos++] = primaryKey;
-    const int startIndex = getStartIndexFromCoordinates(x, y);
-    if (startIndex >= 0) {
-        for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
-            const int c = proximityCharsArray[startIndex + i];
-            if (c < KEYCODE_SPACE || c == primaryKey) {
-                continue;
-            }
-            const int keyIndex = getKeyIndexOf(c);
-            const bool onKey = isOnKey(keyIndex, x, y);
-            const int distance = squaredDistanceToEdge(keyIndex, x, y);
-            if (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE) {
-                inputCodes[insertPos++] = c;
-                if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
-                    if (DEBUG_DICT) {
-                        ASSERT(false);
-                    }
-                    return;
-                }
-            }
-        }
-        const int additionalProximitySize =
-                AdditionalProximityChars::getAdditionalCharsSize(mLocaleStr, primaryKey);
-        if (additionalProximitySize > 0) {
-            inputCodes[insertPos++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
-            if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
-                if (DEBUG_DICT) {
-                    ASSERT(false);
-                }
-                return;
-            }
-
-            const int *additionalProximityChars =
-                    AdditionalProximityChars::getAdditionalChars(mLocaleStr, primaryKey);
-            for (int j = 0; j < additionalProximitySize; ++j) {
-                const int ac = additionalProximityChars[j];
-                int k = 0;
-                for (; k < insertPos; ++k) {
-                    if (ac == inputCodes[k]) {
-                        break;
-                    }
-                }
-                if (k < insertPos) {
-                    continue;
-                }
-                inputCodes[insertPos++] = ac;
-                if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
-                    if (DEBUG_DICT) {
-                        ASSERT(false);
-                    }
-                    return;
-                }
-            }
-        }
-    }
-    // Add a delimiter for the proximity characters
-    for (int i = insertPos; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
-        inputCodes[i] = NOT_A_CODE_POINT;
-    }
-}
-
-int ProximityInfo::getKeyIndexOf(const int c) const {
-    if (KEY_COUNT == 0) {
-        // We do not have the coordinate data
-        return NOT_AN_INDEX;
-    }
-    if (c == NOT_A_CODE_POINT) {
-        return NOT_AN_INDEX;
-    }
-    const int lowerCode = toLowerCase(c);
-    hash_map_compat<int, int>::const_iterator mapPos = mCodeToKeyMap.find(lowerCode);
-    if (mapPos != mCodeToKeyMap.end()) {
-        return mapPos->second;
-    }
-    return NOT_AN_INDEX;
-}
-
 int ProximityInfo::getCodePointOf(const int keyIndex) const {
     if (keyIndex < 0 || keyIndex >= KEY_COUNT) {
         return NOT_A_CODE_POINT;
@@ -269,11 +171,13 @@
 }
 
 int ProximityInfo::getKeyCenterXOfCodePointG(int charCode) const {
-    return getKeyCenterXOfKeyIdG(getKeyIndexOf(charCode));
+    return getKeyCenterXOfKeyIdG(
+            ProximityInfoUtils::getKeyIndexOf(KEY_COUNT, charCode, &mCodeToKeyMap));
 }
 
 int ProximityInfo::getKeyCenterYOfCodePointG(int charCode) const {
-    return getKeyCenterYOfKeyIdG(getKeyIndexOf(charCode));
+    return getKeyCenterYOfKeyIdG(
+            ProximityInfoUtils::getKeyIndexOf(KEY_COUNT, charCode, &mCodeToKeyMap));
 }
 
 int ProximityInfo::getKeyCenterXOfKeyIdG(int keyId) const {
diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h
index d002283..6be42a0 100644
--- a/native/jni/src/proximity_info.h
+++ b/native/jni/src/proximity_info.h
@@ -20,6 +20,7 @@
 #include "defines.h"
 #include "hash_map_compat.h"
 #include "jni.h"
+#include "proximity_info_utils.h"
 
 namespace latinime {
 
@@ -40,7 +41,6 @@
     float getNormalizedSquaredDistanceFromCenterFloatG(
             const int keyId, const int x, const int y) const;
     bool sameAsTyped(const unsigned short *word, int length) const;
-    int getKeyIndexOf(const int c) const;
     int getCodePointOf(const int keyIndex) const;
     bool hasSweetSpotData(const int keyIndex) const {
         // When there are no calibration data for a key,
@@ -109,23 +109,26 @@
     int getKeyCenterYOfKeyIdG(int keyId) const;
     int getKeyKeyDistanceG(int keyId0, int keyId1) const;
 
+    void initializeProximities(const int *const inputCodes, const int *const inputXCoordinates,
+            const int *const inputYCoordinates, const int inputSize, int *allInputCodes) const {
+        ProximityInfoUtils::initializeProximities(inputCodes, inputXCoordinates, inputYCoordinates,
+                inputSize, mKeyXCoordinates, mKeyYCoordinates, mKeyWidths, mKeyHeights,
+                mProximityCharsArray, MAX_PROXIMITY_CHARS_SIZE, CELL_HEIGHT, CELL_WIDTH,
+                GRID_WIDTH, MOST_COMMON_KEY_WIDTH, KEY_COUNT, mLocaleStr, &mCodeToKeyMap,
+                allInputCodes);
+    }
+
+    int getKeyIndexOf(const int c) const {
+        return ProximityInfoUtils::getKeyIndexOf(KEY_COUNT, c, &mCodeToKeyMap);
+    }
+
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfo);
     static const float NOT_A_DISTANCE_FLOAT;
 
-    int getStartIndexFromCoordinates(const int x, const int y) const;
     void initializeG();
     float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const;
     bool hasInputCoordinates() const;
-    int squaredDistanceToEdge(const int keyId, const int x, const int y) const;
-    bool isOnKey(const int keyId, const int x, const int y) const {
-        if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case
-        const int left = mKeyXCoordinates[keyId];
-        const int top = mKeyYCoordinates[keyId];
-        const int right = left + mKeyWidths[keyId] + 1;
-        const int bottom = top + mKeyHeights[keyId];
-        return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom;
-    }
 
     const int MAX_PROXIMITY_CHARS_SIZE;
     const int GRID_WIDTH;
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index aa02929..1e1413a 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -53,33 +53,11 @@
     mGridHeight = proximityInfo->getGridWidth();
     mGridWidth = proximityInfo->getGridHeight();
 
-    memset(mInputCodes, 0, sizeof(mInputCodes));
+    memset(mInputProximities, 0, sizeof(mInputProximities));
 
     if (!isGeometric && pointerId == 0) {
-        // Initialize
-        // - mInputCodes
-        // - mNormalizedSquaredDistances
-        // TODO: Merge
-        for (int i = 0; i < inputSize; ++i) {
-            const int primaryKey = inputCodes[i];
-            const int x = xCoordinates[i];
-            const int y = yCoordinates[i];
-            int *proximities = &mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL];
-            mProximityInfo->calculateNearbyKeyCodes(x, y, primaryKey, proximities);
-        }
-
-        if (DEBUG_PROXIMITY_CHARS) {
-            for (int i = 0; i < inputSize; ++i) {
-                AKLOGI("---");
-                for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL; ++j) {
-                    int icc = mInputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j];
-                    int icfjc = inputCodes[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j];
-                    icc += 0;
-                    icfjc += 0;
-                    AKLOGI("--- (%d)%c,%c", i, icc, icfjc); AKLOGI("--- A<%d>,B<%d>", icc, icfjc);
-                }
-            }
-        }
+        mProximityInfo->initializeProximities(inputCodes, xCoordinates, yCoordinates,
+                inputSize, mInputProximities);
     }
 
     ///////////////////////
diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h
index d747bae..bc2cf50 100644
--- a/native/jni/src/proximity_info_state.h
+++ b/native/jni/src/proximity_info_state.h
@@ -61,7 +61,7 @@
               mInputIndice(), mLengthCache(), mBeelineSpeedPercentiles(), mDistanceCache_G(),
               mSpeedRates(), mDirections(), mCharProbabilities(), mNearKeysVector(),
               mSearchKeysVector(), mTouchPositionCorrectionEnabled(false), mSampledInputSize(0) {
-        memset(mInputCodes, 0, sizeof(mInputCodes));
+        memset(mInputProximities, 0, sizeof(mInputProximities));
         memset(mNormalizedSquaredDistances, 0, sizeof(mNormalizedSquaredDistances));
         memset(mPrimaryInputWord, 0, sizeof(mPrimaryInputWord));
     }
@@ -117,12 +117,12 @@
         if (length != mSampledInputSize) {
             return false;
         }
-        const int *inputCodes = mInputCodes;
+        const int *inputProximities = mInputProximities;
         while (length--) {
-            if (*inputCodes != *word) {
+            if (*inputProximities != *word) {
                 return false;
             }
-            inputCodes += MAX_PROXIMITY_CHARS_SIZE_INTERNAL;
+            inputProximities += MAX_PROXIMITY_CHARS_SIZE_INTERNAL;
             word++;
         }
         return true;
@@ -229,7 +229,7 @@
     }
 
     inline const int *getProximityCodePointsAt(const int index) const {
-        return mInputCodes + (index * MAX_PROXIMITY_CHARS_SIZE_INTERNAL);
+        return mInputProximities + (index * MAX_PROXIMITY_CHARS_SIZE_INTERNAL);
     }
 
     float updateNearKeysDistances(const int x, const int y,
@@ -289,7 +289,7 @@
     // inputs including the current input point.
     std::vector<NearKeycodesSet> mSearchKeysVector;
     bool mTouchPositionCorrectionEnabled;
-    int mInputCodes[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH];
+    int mInputProximities[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH];
     int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH];
     int mSampledInputSize;
     int mPrimaryInputWord[MAX_WORD_LENGTH];
diff --git a/native/jni/src/proximity_info_utils.h b/native/jni/src/proximity_info_utils.h
new file mode 100644
index 0000000..b9348d8
--- /dev/null
+++ b/native/jni/src/proximity_info_utils.h
@@ -0,0 +1,192 @@
+/*
+ * 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_UTILS_H
+#define LATINIME_PROXIMITY_INFO_UTILS_H
+
+#include "additional_proximity_chars.h"
+#include "char_utils.h"
+#include "defines.h"
+#include "hash_map_compat.h"
+
+namespace latinime {
+class ProximityInfoUtils {
+ public:
+    static int getKeyIndexOf(const int keyCount, const int c,
+            const hash_map_compat<int, int> *const codeToKeyMap) {
+        if (keyCount == 0) {
+            // We do not have the coordinate data
+            return NOT_AN_INDEX;
+        }
+        if (c == NOT_A_CODE_POINT) {
+            return NOT_AN_INDEX;
+        }
+        const int lowerCode = toLowerCase(c);
+        hash_map_compat<int, int>::const_iterator mapPos = codeToKeyMap->find(lowerCode);
+        if (mapPos != codeToKeyMap->end()) {
+            return mapPos->second;
+        }
+        return NOT_AN_INDEX;
+    }
+
+    static void initializeProximities(const int *const inputCodes,
+            const int *const inputXCoordinates, const int *const inputYCoordinates,
+            const int inputSize, const int *const keyXCoordinates,
+            const int *const keyYCoordinates, const int *const keyWidths, const int *keyHeights,
+            const int *const proximityCharsArray, const int maxProximityCharsSize,
+            const int cellHeight, const int cellWidth, const int gridWidth,
+            const int mostCommonKeyWidth, const int keyCount, const char *const localeStr,
+            const hash_map_compat<int, int> *const codeToKeyMap, int *inputProximities) {
+        // Initialize
+        // - mInputCodes
+        // - mNormalizedSquaredDistances
+        // TODO: Merge
+        for (int i = 0; i < inputSize; ++i) {
+            const int primaryKey = inputCodes[i];
+            const int x = inputXCoordinates[i];
+            const int y = inputYCoordinates[i];
+            int *proximities = &inputProximities[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL];
+            calculateProximities(keyXCoordinates, keyYCoordinates, keyWidths, keyHeights,
+                    proximityCharsArray, maxProximityCharsSize, cellHeight, cellWidth, gridWidth,
+                    mostCommonKeyWidth, keyCount, x, y, primaryKey, localeStr, codeToKeyMap,
+                    proximities);
+        }
+
+        if (DEBUG_PROXIMITY_CHARS) {
+            for (int i = 0; i < inputSize; ++i) {
+                AKLOGI("---");
+                for (int j = 0; j < MAX_PROXIMITY_CHARS_SIZE_INTERNAL; ++j) {
+                    int proximityChar =
+                            inputProximities[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j];
+                    proximityChar += 0;
+                    AKLOGI("--- (%d)%c", i, proximityChar);
+                }
+            }
+        }
+    }
+
+    AK_FORCE_INLINE static int getStartIndexFromCoordinates(const int maxProximityCharsSize,
+            const int x, const int y, const int cellHeight, const int cellWidth,
+            const int gridWidth) {
+        return ((y / cellHeight) * gridWidth + (x / cellWidth)) * maxProximityCharsSize;
+    }
+
+ private:
+    DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoUtils);
+
+    static bool isOnKey(const int *const keyXCoordinates, const int *const keyYCoordinates,
+            const int *const keyWidths, const int *keyHeights, const int keyId, const int x,
+            const int y) {
+        if (keyId < 0) return true; // NOT_A_ID is -1, but return whenever < 0 just in case
+        const int left = keyXCoordinates[keyId];
+        const int top = keyYCoordinates[keyId];
+        const int right = left + keyWidths[keyId] + 1;
+        const int bottom = top + keyHeights[keyId];
+        return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom;
+    }
+
+    static void calculateProximities(
+            const int *const keyXCoordinates, const int *const keyYCoordinates,
+            const int *const keyWidths, const int *keyHeights,
+            const int *const proximityCharsArray,
+            const int maxProximityCharsSize, const int cellHeight, const int cellWidth,
+            const int gridWidth, const int mostCommonKeyWidth, const int keyCount,
+            const int x, const int y, const int primaryKey, const char *const localeStr,
+            const hash_map_compat<int, int> *const codeToKeyMap, int *proximities) {
+        const int mostCommonKeyWidthSquare = mostCommonKeyWidth * mostCommonKeyWidth;
+        int insertPos = 0;
+        proximities[insertPos++] = primaryKey;
+        const int startIndex = getStartIndexFromCoordinates(
+                maxProximityCharsSize, x, y, cellHeight, cellWidth, gridWidth);
+        if (startIndex >= 0) {
+            for (int i = 0; i < maxProximityCharsSize; ++i) {
+                const int c = proximityCharsArray[startIndex + i];
+                if (c < KEYCODE_SPACE || c == primaryKey) {
+                    continue;
+                }
+                const int keyIndex = getKeyIndexOf(keyCount, c, codeToKeyMap);
+                const bool onKey = isOnKey(keyXCoordinates, keyYCoordinates, keyWidths, keyHeights,
+                        keyIndex, x, y);
+                const int distance = squaredLengthToEdge(keyXCoordinates, keyYCoordinates,
+                        keyWidths, keyHeights, keyIndex, x, y);
+                if (onKey || distance < mostCommonKeyWidthSquare) {
+                    proximities[insertPos++] = c;
+                    if (insertPos >= maxProximityCharsSize) {
+                        if (DEBUG_DICT) {
+                            ASSERT(false);
+                        }
+                        return;
+                    }
+                }
+            }
+            const int additionalProximitySize =
+                    AdditionalProximityChars::getAdditionalCharsSize(localeStr, primaryKey);
+            if (additionalProximitySize > 0) {
+                proximities[insertPos++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
+                if (insertPos >= maxProximityCharsSize) {
+                    if (DEBUG_DICT) {
+                        ASSERT(false);
+                    }
+                    return;
+                }
+
+                const int *additionalProximityChars =
+                        AdditionalProximityChars::getAdditionalChars(localeStr, primaryKey);
+                for (int j = 0; j < additionalProximitySize; ++j) {
+                    const int ac = additionalProximityChars[j];
+                    int k = 0;
+                    for (; k < insertPos; ++k) {
+                        if (ac == proximities[k]) {
+                            break;
+                        }
+                    }
+                    if (k < insertPos) {
+                        continue;
+                    }
+                    proximities[insertPos++] = ac;
+                    if (insertPos >= maxProximityCharsSize) {
+                        if (DEBUG_DICT) {
+                            ASSERT(false);
+                        }
+                        return;
+                    }
+                }
+            }
+        }
+        // Add a delimiter for the proximity characters
+        for (int i = insertPos; i < maxProximityCharsSize; ++i) {
+            proximities[i] = NOT_A_CODE_POINT;
+        }
+    }
+
+    static int squaredLengthToEdge(const int *const keyXCoordinates,
+            const int *const keyYCoordinates, const int *const keyWidths, const int *keyHeights,
+            const int keyId, const int x, const int y) {
+        // NOT_A_ID is -1, but return whenever < 0 just in case
+        if (keyId < 0) return MAX_POINT_TO_KEY_LENGTH;
+        const int left = keyXCoordinates[keyId];
+        const int top = keyYCoordinates[keyId];
+        const int right = left + keyWidths[keyId];
+        const int bottom = top + keyHeights[keyId];
+        const int edgeX = x < left ? left : (x > right ? right : x);
+        const int edgeY = y < top ? top : (y > bottom ? bottom : y);
+        const int dx = x - edgeX;
+        const int dy = y - edgeY;
+        return dx * dx + dy * dy;
+    }
+};
+} // namespace latinime
+#endif // LATINIME_PROXIMITY_INFO_UTILS_H
