diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/latin/PointerTracker.java
index 504c85784e05b0a01a789e2616c6b5c72564df31..c8976a37246ae3f8f8b58071a477abdfb8670b03 100644
--- a/java/src/com/android/inputmethod/latin/PointerTracker.java
+++ b/java/src/com/android/inputmethod/latin/PointerTracker.java
@@ -100,21 +100,25 @@ public class PointerTracker {
         mKeyDebounceThresholdSquared = (int)(hysteresisPixel * hysteresisPixel);
     }
 
+    private boolean isValidKeyIndex(int keyIndex) {
+        return keyIndex >= 0 && keyIndex < mKeys.length;
+    }
+
     public Key getKey(int keyIndex) {
-        return (keyIndex >= 0 && keyIndex < mKeys.length) ? mKeys[keyIndex] : null;
+        return isValidKeyIndex(keyIndex) ? mKeys[keyIndex] : null;
     }
 
     public void updateKey(int keyIndex) {
         int oldKeyIndex = mPreviousKey;
         mPreviousKey = keyIndex;
         if (keyIndex != oldKeyIndex) {
-            if (oldKeyIndex != NOT_A_KEY && oldKeyIndex < mKeys.length) {
+            if (isValidKeyIndex(oldKeyIndex)) {
                 // if new key index is not a key, old key was just released inside of the key.
                 final boolean inside = (keyIndex == NOT_A_KEY);
                 mKeys[oldKeyIndex].onReleased(inside);
                 mProxy.invalidateKey(mKeys[oldKeyIndex]);
             }
-            if (keyIndex != NOT_A_KEY && keyIndex < mKeys.length) {
+            if (isValidKeyIndex(keyIndex)) {
                 mKeys[keyIndex].onPressed();
                 mProxy.invalidateKey(mKeys[keyIndex]);
             }
@@ -130,14 +134,14 @@ public class PointerTracker {
         startTimeDebouncing(eventTime);
         checkMultiTap(eventTime, keyIndex);
         if (mListener != null) {
-            int primaryCode = (keyIndex != NOT_A_KEY) ? mKeys[keyIndex].codes[0] : 0;
+            int primaryCode = isValidKeyIndex(keyIndex) ? mKeys[keyIndex].codes[0] : 0;
             mListener.onPress(primaryCode);
         }
-        if (keyIndex >= 0 && mKeys[keyIndex].repeatable) {
-            repeatKey(keyIndex);
-            mHandler.startKeyRepeatTimer(REPEAT_START_DELAY, keyIndex, this);
-        }
-        if (keyIndex != NOT_A_KEY) {
+        if (isValidKeyIndex(keyIndex)) {
+            if (mKeys[keyIndex].repeatable) {
+                repeatKey(keyIndex);
+                mHandler.startKeyRepeatTimer(REPEAT_START_DELAY, keyIndex, this);
+            }
             mHandler.startLongPressTimer(keyIndex, LONGPRESS_TIMEOUT);
         }
         showKeyPreviewAndUpdateKey(keyIndex);
@@ -146,7 +150,7 @@ public class PointerTracker {
 
     public void onMoveEvent(int touchX, int touchY, long eventTime) {
         int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(touchX, touchY, null);
-        if (keyIndex != NOT_A_KEY) {
+        if (isValidKeyIndex(keyIndex)) {
             if (mCurrentKey == NOT_A_KEY) {
                 updateTimeDebouncing(eventTime);
                 mCurrentKey = keyIndex;
@@ -195,7 +199,7 @@ public class PointerTracker {
         if (!wasInKeyRepeat && !mProxy.isMiniKeyboardOnScreen()) {
             detectAndSendKey(mCurrentKey, touchX, touchY, eventTime);
         }
-        if (keyIndex != NOT_A_KEY && keyIndex < mKeys.length)
+        if (isValidKeyIndex(keyIndex))
             mProxy.invalidateKey(mKeys[keyIndex]);
     }
 
@@ -205,15 +209,17 @@ public class PointerTracker {
         mProxy.dismissPopupKeyboard();
         showKeyPreviewAndUpdateKey(NOT_A_KEY);
         int keyIndex = mCurrentKey;
-        if (keyIndex != NOT_A_KEY && keyIndex < mKeys.length)
+        if (isValidKeyIndex(keyIndex))
            mProxy.invalidateKey(mKeys[keyIndex]);
     }
 
     public void repeatKey(int keyIndex) {
-        Key key = mKeys[keyIndex];
-        // While key is repeating, because there is no need to handle multi-tap key, we can pass
-        // -1 as eventTime argument.
-        detectAndSendKey(keyIndex, key.x, key.y, -1);
+        Key key = getKey(keyIndex);
+        if (key != null) {
+            // While key is repeating, because there is no need to handle multi-tap key, we can
+            // pass -1 as eventTime argument.
+            detectAndSendKey(keyIndex, key.x, key.y, -1);
+        }
     }
 
     // These package scope methods are only for debugging purpose.
@@ -253,7 +259,7 @@ public class PointerTracker {
             throw new IllegalStateException("keyboard and/or hysteresis not set");
         if (newKey == curKey) {
             return true;
-        } else if (curKey >= 0 && curKey < mKeys.length) {
+        } else if (isValidKeyIndex(curKey)) {
             return getSquareDistanceToKeyEdge(x, y, mKeys[curKey])
                     < mKeyDebounceThresholdSquared;
         } else {
@@ -303,7 +309,7 @@ public class PointerTracker {
     }
 
     private void detectAndSendKey(int index, int x, int y, long eventTime) {
-        if (index != NOT_A_KEY && index < mKeys.length) {
+        if (isValidKeyIndex(index)) {
             final Key key = mKeys[index];
             OnKeyboardActionListener listener = mListener;
             if (key.text != null) {
@@ -366,11 +372,15 @@ public class PointerTracker {
     }
 
     private void checkMultiTap(long eventTime, int keyIndex) {
-        if (keyIndex == NOT_A_KEY) return;
-        Key key = mKeys[keyIndex];
+        Key key = getKey(keyIndex);
+        if (key == null)
+            return;
+
+        final boolean isMultiTap =
+                (eventTime < mLastTapTime + MULTITAP_INTERVAL && keyIndex == mLastSentIndex);
         if (key.codes.length > 1) {
             mInMultiTap = true;
-            if (eventTime < mLastTapTime + MULTITAP_INTERVAL && keyIndex == mLastSentIndex) {
+            if (isMultiTap) {
                 mTapCount = (mTapCount + 1) % key.codes.length;
                 return;
             } else {
@@ -378,7 +388,7 @@ public class PointerTracker {
                 return;
             }
         }
-        if (eventTime > mLastTapTime + MULTITAP_INTERVAL || keyIndex != mLastSentIndex) {
+        if (!isMultiTap) {
             resetMultiTap();
         }
     }