diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 733d3b0..437bbf0 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -22,8 +22,10 @@
 import android.view.View;
 import android.widget.TextView;
 
+import com.android.inputmethod.keyboard.internal.GestureStroke;
 import com.android.inputmethod.keyboard.internal.GestureTracker;
 import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
+import com.android.inputmethod.latin.InputPointers;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.ResearchLogger;
 import com.android.inputmethod.latin.define.ProductionFlag;
@@ -165,6 +167,8 @@
     // Gesture tracker singleton instance
     private static final GestureTracker sGestureTracker = GestureTracker.getInstance();
 
+    private final GestureStroke mGestureStroke;
+
     public static void init(boolean hasDistinctMultitouch,
             boolean needsPhantomSuddenMoveEventHack) {
         if (hasDistinctMultitouch) {
@@ -222,10 +226,43 @@
         }
     }
 
-    public PointerTracker(int id, KeyEventHandler handler) {
+    // The working and returning object of the following methods,
+    // {@link #getIncrementalBatchPoints()} and {@link #getAllBatchPoints()}.
+    private static final InputPointers mAggregatedPointers = new InputPointers();
+
+    // TODO: This method is called only from GestureTracker and should address the thread-safty
+    // issue soon.
+    public static InputPointers getIncrementalBatchPoints() {
+        final InputPointers pointers = mAggregatedPointers;
+        pointers.reset();
+        for (final PointerTracker tracker : sTrackers) {
+            tracker.getGestureStroke().appendIncrementalBatchPoints(pointers);
+        }
+        return pointers;
+    }
+
+    // TODO: This method is called only from GestureTracker and should address the thread-safety
+    // issue soon.
+    public static InputPointers getAllBatchPoints() {
+        final InputPointers pointers = mAggregatedPointers;
+        pointers.reset();
+        for (final PointerTracker tracker : sTrackers) {
+            tracker.getGestureStroke().appendAllBatchPoints(pointers);
+        }
+        return pointers;
+    }
+
+    public static void clearBatchInputPoints() {
+        for (final PointerTracker tracker : sTrackers) {
+            tracker.getGestureStroke().reset();
+        }
+    }
+
+    private PointerTracker(int id, KeyEventHandler handler) {
         if (handler == null)
             throw new NullPointerException();
         mPointerId = id;
+        mGestureStroke = new GestureStroke(id);
         setKeyDetectorInner(handler.getKeyDetector());
         mListener = handler.getKeyboardActionListener();
         mDrawingProxy = handler.getDrawingProxy();
@@ -237,6 +274,10 @@
         return mKeyPreviewText;
     }
 
+    public GestureStroke getGestureStroke() {
+        return mGestureStroke;
+    }
+
     // Returns true if keyboard has been changed by this callback.
     private boolean callListenerOnPressAndCheckKeyboardLayoutChange(Key key) {
         if (sGestureTracker.isInGesture()) {
@@ -328,6 +369,8 @@
     private void setKeyDetectorInner(KeyDetector keyDetector) {
         mKeyDetector = keyDetector;
         mKeyboard = keyDetector.getKeyboard();
+        mGestureStroke.setGestureSampleLength(
+                mKeyboard.mMostCommonKeyWidth, mKeyboard.mMostCommonKeyHeight);
         final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY);
         if (newKey != mCurrentKey) {
             if (mDrawingProxy != null) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
new file mode 100644
index 0000000..14e9948
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+package com.android.inputmethod.keyboard.internal;
+
+import android.util.FloatMath;
+
+import com.android.inputmethod.latin.InputPointers;
+
+public class GestureStroke {
+    private final int mPointerId;
+    private final InputPointers mInputPointers = new InputPointers();
+    private float mLength;
+    private float mAngle;
+    private int mIncrementalRecognitionPoint;
+    private boolean mHasSharpCorner;
+    private long mLastPointTime;
+    private int mLastPointX;
+    private int mLastPointY;
+
+    private int mMinGestureLength;
+    private int mMinGestureSampleLength;
+
+    // TODO: Tune these parameters.
+    private static final float MIN_GESTURE_DETECTION_RATIO_TO_KEY_WIDTH = 1.0f / 4.0f;
+    private static final float MIN_GESTURE_SAMPLING_RATIO_TO_KEY_HEIGHT = 1.0f / 6.0f;
+    private static final int MIN_GESTURE_DURATION = 100; // msec
+    private static final float GESTURE_RECOG_SPEED_THRESHOLD = 0.4f; // dip/msec
+    private static final float GESTURE_RECOG_CURVATURE_THRESHOLD = (float)(Math.PI / 4.0f);
+
+    private static final float DOUBLE_PI = (float)(2 * Math.PI);
+
+    public GestureStroke(int pointerId) {
+        mPointerId = pointerId;
+        reset();
+    }
+
+    public void setGestureSampleLength(final int keyWidth, final int keyHeight) {
+        mMinGestureLength = (int)(keyWidth * MIN_GESTURE_DETECTION_RATIO_TO_KEY_WIDTH);
+        mMinGestureSampleLength = (int)(keyHeight * MIN_GESTURE_SAMPLING_RATIO_TO_KEY_HEIGHT);
+    }
+
+    public boolean isStartOfAGesture(int downDuration) {
+        return downDuration > MIN_GESTURE_DURATION && mLength > mMinGestureLength;
+    }
+
+    public void reset() {
+        mLength = 0;
+        mAngle = 0;
+        mIncrementalRecognitionPoint = 0;
+        mHasSharpCorner = false;
+        mLastPointTime = 0;
+        mInputPointers.reset();
+    }
+
+    private void updateLastPoint(final int x, final int y, final int time) {
+        mLastPointTime = time;
+        mLastPointX = x;
+        mLastPointY = y;
+    }
+
+    public void addPoint(final int x, final int y, final int time, final boolean isHistorical) {
+        final int size = mInputPointers.getPointerSize();
+        if (size == 0) {
+            mInputPointers.addPointer(x, y, mPointerId, time);
+            if (!isHistorical) {
+                updateLastPoint(x, y, time);
+            }
+            return;
+        }
+
+        final int[] xCoords = mInputPointers.getXCoordinates();
+        final int[] yCoords = mInputPointers.getYCoordinates();
+        final int lastX = xCoords[size - 1];
+        final int lastY = yCoords[size - 1];
+        final float dist = getDistance(lastX, lastY, x, y);
+        if (dist > mMinGestureSampleLength) {
+            mInputPointers.addPointer(x, y, mPointerId, time);
+            mLength += dist;
+            final float angle = getAngle(lastX, lastY, x, y);
+            if (size > 1) {
+                float curvature = getAngleDiff(angle, mAngle);
+                if (curvature > GESTURE_RECOG_CURVATURE_THRESHOLD) {
+                    if (size > mIncrementalRecognitionPoint) {
+                        mIncrementalRecognitionPoint = size;
+                    }
+                    mHasSharpCorner = true;
+                }
+                if (!mHasSharpCorner) {
+                    mIncrementalRecognitionPoint = size;
+                }
+            }
+            mAngle = angle;
+        }
+
+        if (!isHistorical) {
+            final int duration = (int)(time - mLastPointTime);
+            if (mLastPointTime != 0 && duration > 0) {
+                final float speed = getDistance(mLastPointX, mLastPointY, x, y) / duration;
+                if (speed < GESTURE_RECOG_SPEED_THRESHOLD) {
+                    mIncrementalRecognitionPoint = size;
+                }
+            }
+            updateLastPoint(x, y, time);
+        }
+    }
+
+    public void appendAllBatchPoints(final InputPointers out) {
+        out.append(mInputPointers, 0, mInputPointers.getPointerSize());
+    }
+
+    public void appendIncrementalBatchPoints(final InputPointers out) {
+        out.append(mInputPointers, 0, mIncrementalRecognitionPoint);
+    }
+
+    private static float getDistance(final int p1x, final int p1y,
+            final int p2x, final int p2y) {
+        final float dx = p1x - p2x;
+        final float dy = p1y - p2y;
+        // TODO: Optimize out this {@link FloatMath#sqrt(float)} call.
+        return FloatMath.sqrt(dx * dx + dy * dy);
+    }
+
+    private static float getAngle(final int p1x, final int p1y, final int p2x, final int p2y) {
+        final int dx = p1x - p2x;
+        final int dy = p1y - p2y;
+        if (dx == 0 && dy == 0) return 0;
+        return (float)Math.atan2(dy, dx);
+    }
+
+    private static float getAngleDiff(final float a1, final float a2) {
+        final float diff = Math.abs(a1 - a2);
+        if (diff > Math.PI) {
+            return DOUBLE_PI - diff;
+        }
+        return diff;
+    }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTracker.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTracker.java
index dfd697a..0f14dce 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTracker.java
@@ -15,7 +15,6 @@
 package com.android.inputmethod.keyboard.internal;
 
 import android.util.Log;
-import android.util.SparseArray;
 
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
@@ -35,12 +34,6 @@
     private static final GestureTracker sInstance = new GestureTracker();
 
     private static final int MIN_RECOGNITION_TIME = 100;
-    private static final int MIN_GESTURE_DURATION = 200;
-
-    private static final float GESTURE_RECOG_SPEED_THRESHOLD = 0.4f;
-    private static final float SQUARED_GESTURE_RECOG_SPEED_THRESHOLD =
-            GESTURE_RECOG_SPEED_THRESHOLD * GESTURE_RECOG_SPEED_THRESHOLD;
-    private static final float GESTURE_RECOG_CURVATURE_THRESHOLD = (float) (Math.PI / 4);
 
     private boolean mIsAlphabetKeyboard;
     private boolean mIsPossibleGesture = false;
@@ -49,8 +42,6 @@
     private KeyboardActionListener mListener;
     private SuggestedWords mSuggestions;
 
-    private final SparseArray<GestureStroke> mGestureStrokes = new SparseArray<GestureStroke>();
-
     private int mLastRecognitionPointSize = 0;
     private long mLastRecognitionTime = 0;
 
@@ -67,8 +58,6 @@
 
     public void setKeyboard(Keyboard keyboard) {
         mIsAlphabetKeyboard = keyboard.mId.isAlphabetKeyboard();
-        GestureStroke.setGestureSampleLength(keyboard.mMostCommonKeyWidth / 2,
-                keyboard.mMostCommonKeyHeight / 6);
     }
 
     private void startBatchInput() {
@@ -107,7 +96,7 @@
         // A gesture should start only from the letter key.
         if (GESTURE_ON && mIsAlphabetKeyboard && key != null && Keyboard.isLetterCode(key.mCode)) {
             mIsPossibleGesture = true;
-            addPointToStroke(x, y, 0, tracker.mPointerId, false);
+            tracker.getGestureStroke().addPoint(x, y, 0, false);
         }
     }
 
@@ -115,15 +104,15 @@
             boolean isHistorical, Key key) {
         final int gestureTime = (int)(eventTime - tracker.getDownTime());
         if (GESTURE_ON && mIsPossibleGesture) {
-            final GestureStroke stroke = addPointToStroke(x, y, gestureTime, tracker.mPointerId,
-                    isHistorical);
+            final GestureStroke stroke = tracker.getGestureStroke();
+            stroke.addPoint(x, y, gestureTime, isHistorical);
             if (!isInGesture() && stroke.isStartOfAGesture(gestureTime)) {
                 startBatchInput();
             }
         }
 
         if (key != null && isInGesture()) {
-            final InputPointers batchPoints = getIncrementalBatchPoints();
+            final InputPointers batchPoints = PointerTracker.getIncrementalBatchPoints();
             if (updateBatchInputRecognitionState(eventTime, batchPoints.getPointerSize())) {
                 if (DEBUG_LISTENER) {
                     Log.d(TAG, "onUpdateBatchInput: batchPoints=" + batchPoints.getPointerSize());
@@ -135,7 +124,7 @@
 
     public void onUpEvent(PointerTracker tracker, int x, int y, long eventTime) {
         if (isInGesture()) {
-            final InputPointers batchPoints = getAllBatchPoints();
+            final InputPointers batchPoints = PointerTracker.getAllBatchPoints();
             if (DEBUG_LISTENER) {
                 Log.d(TAG, "onUpdateBatchInput: batchPoints=" + batchPoints.getPointerSize());
             }
@@ -143,49 +132,8 @@
         }
     }
 
-    private GestureStroke addPointToStroke(int x, int y, int time, int pointerId,
-            boolean isHistorical) {
-        GestureStroke stroke = mGestureStrokes.get(pointerId);
-        if (stroke == null) {
-            stroke = new GestureStroke(pointerId);
-            mGestureStrokes.put(pointerId, stroke);
-        }
-        stroke.addPoint(x, y, time, isHistorical);
-        return stroke;
-    }
-
-    // The working and return object of the following methods, {@link #getIncrementalBatchPoints()}
-    // and {@link #getAllBatchPoints()}.
-    private final InputPointers mAggregatedPointers = new InputPointers();
-
-    private InputPointers getIncrementalBatchPoints() {
-        final InputPointers pointers = mAggregatedPointers;
-        pointers.reset();
-        final int strokeSize = mGestureStrokes.size();
-        for (int index = 0; index < strokeSize; index++) {
-            final GestureStroke stroke = mGestureStrokes.valueAt(index);
-            stroke.appendIncrementalBatchPoints(pointers);
-        }
-        return pointers;
-    }
-
-    private InputPointers getAllBatchPoints() {
-        final InputPointers pointers = mAggregatedPointers;
-        pointers.reset();
-        final int strokeSize = mGestureStrokes.size();
-        for (int index = 0; index < strokeSize; index++) {
-            final GestureStroke stroke = mGestureStrokes.valueAt(index);
-            stroke.appendAllBatchPoints(pointers);
-        }
-        return pointers;
-    }
-
     private void clearBatchInputPoints() {
-        final int strokeSize = mGestureStrokes.size();
-        for (int index = 0; index < strokeSize; index++) {
-            final GestureStroke stroke = mGestureStrokes.valueAt(index);
-            stroke.reset();
-        }
+        PointerTracker.clearBatchInputPoints();
         mLastRecognitionPointSize = 0;
         mLastRecognitionTime = 0;
     }
@@ -199,128 +147,4 @@
         }
         return false;
     }
-
-    private static class GestureStroke {
-        private final int mPointerId;
-        private final InputPointers mInputPointers = new InputPointers();
-        private float mLength;
-        private float mAngle;
-        private int mIncrementalRecognitionPoint;
-        private boolean mHasSharpCorner;
-        private long mLastPointTime;
-        private int mLastPointX;
-        private int mLastPointY;
-
-        private static int sMinGestureLength;
-        private static int sSquaredGestureSampleLength;
-
-        private static final float DOUBLE_PI = (float)(2 * Math.PI);
-
-        public static void setGestureSampleLength(final int minGestureLength,
-                final int sampleLength) {
-            sMinGestureLength = minGestureLength;
-            sSquaredGestureSampleLength = sampleLength * sampleLength;
-        }
-
-        public GestureStroke(int pointerId) {
-            mPointerId = pointerId;
-            reset();
-        }
-
-        public boolean isStartOfAGesture(int downDuration) {
-            return downDuration > MIN_GESTURE_DURATION / 2  && mLength > sMinGestureLength / 2;
-        }
-
-        public void reset() {
-            mLength = 0;
-            mAngle = 0;
-            mIncrementalRecognitionPoint = 0;
-            mHasSharpCorner = false;
-            mLastPointTime = 0;
-            mInputPointers.reset();
-        }
-
-        private void updateLastPoint(final int x, final int y, final int time) {
-            mLastPointTime = time;
-            mLastPointX = x;
-            mLastPointY = y;
-        }
-
-        public void addPoint(final int x, final int y, final int time, final boolean isHistorical) {
-            final int size = mInputPointers.getPointerSize();
-            if (size == 0) {
-                mInputPointers.addPointer(x, y, mPointerId, time);
-                if (!isHistorical) {
-                    updateLastPoint(x, y, time);
-                }
-                return;
-            }
-
-            final int[] xCoords = mInputPointers.getXCoordinates();
-            final int[] yCoords = mInputPointers.getYCoordinates();
-            final int lastX = xCoords[size - 1];
-            final int lastY = yCoords[size - 1];
-            final float dist = squaredDistance(lastX, lastY, x, y);
-            if (dist > sSquaredGestureSampleLength) {
-                mInputPointers.addPointer(x, y, mPointerId, time);
-                mLength += dist;
-                final float angle = angle(lastX, lastY, x, y);
-                if (size > 1) {
-                    float curvature = getAngleDiff(angle, mAngle);
-                    if (curvature > GESTURE_RECOG_CURVATURE_THRESHOLD) {
-                        if (size > mIncrementalRecognitionPoint) {
-                            mIncrementalRecognitionPoint = size;
-                        }
-                        mHasSharpCorner = true;
-                    }
-                    if (!mHasSharpCorner) {
-                        mIncrementalRecognitionPoint = size;
-                    }
-                }
-                mAngle = angle;
-            }
-
-            if (!isHistorical) {
-                final int duration = (int)(time - mLastPointTime);
-                if (mLastPointTime != 0 && duration > 0) {
-                    final int squaredDuration = duration * duration;
-                    final float squaredSpeed =
-                            squaredDistance(mLastPointX, mLastPointY, x, y) / squaredDuration;
-                    if (squaredSpeed < SQUARED_GESTURE_RECOG_SPEED_THRESHOLD) {
-                        mIncrementalRecognitionPoint = size;
-                    }
-                }
-                updateLastPoint(x, y, time);
-            }
-        }
-
-        private float getAngleDiff(float a1, float a2) {
-            final float diff = Math.abs(a1 - a2);
-            if (diff > Math.PI) {
-                return DOUBLE_PI - diff;
-            }
-            return diff;
-        }
-
-        public void appendAllBatchPoints(InputPointers out) {
-            out.append(mInputPointers, 0, mInputPointers.getPointerSize());
-        }
-
-        public void appendIncrementalBatchPoints(InputPointers out) {
-            out.append(mInputPointers, 0, mIncrementalRecognitionPoint);
-        }
-    }
-
-    static float squaredDistance(int p1x, int p1y, int p2x, int p2y) {
-        final float dx = p1x - p2x;
-        final float dy = p1y - p2y;
-        return dx * dx + dy * dy;
-    }
-
-    static float angle(int p1x, int p1y, int p2x, int p2y) {
-        final int dx = p1x - p2x;
-        final int dy = p1y - p2y;
-        if (dx == 0 && dy == 0) return 0;
-        return (float)Math.atan2(dy, dx);
-    }
 }
