diff --git a/java/src/com/android/inputmethod/latin/InputPointers.java b/java/src/com/android/inputmethod/latin/InputPointers.java
index febabadf7bbfa7e7f54ee225eac433d8839a245c..2bccdee4819d59f35f2aace0a63d65cdec7ab8ad 100644
--- a/java/src/com/android/inputmethod/latin/InputPointers.java
+++ b/java/src/com/android/inputmethod/latin/InputPointers.java
@@ -16,22 +16,20 @@
 
 package com.android.inputmethod.latin;
 
-import java.util.Arrays;
-
 // TODO: This class is not thread-safe.
 public class InputPointers {
     private final int mDefaultCapacity;
-    private final ScalableIntArray mXCoordinates;
-    private final ScalableIntArray mYCoordinates;
-    private final ScalableIntArray mPointerIds;
-    private final ScalableIntArray mTimes;
+    private final ResizableIntArray mXCoordinates;
+    private final ResizableIntArray mYCoordinates;
+    private final ResizableIntArray mPointerIds;
+    private final ResizableIntArray mTimes;
 
     public InputPointers(int defaultCapacity) {
         mDefaultCapacity = defaultCapacity;
-        mXCoordinates = new ScalableIntArray(defaultCapacity);
-        mYCoordinates = new ScalableIntArray(defaultCapacity);
-        mPointerIds = new ScalableIntArray(defaultCapacity);
-        mTimes = new ScalableIntArray(defaultCapacity);
+        mXCoordinates = new ResizableIntArray(defaultCapacity);
+        mYCoordinates = new ResizableIntArray(defaultCapacity);
+        mPointerIds = new ResizableIntArray(defaultCapacity);
+        mTimes = new ResizableIntArray(defaultCapacity);
     }
 
     public void addPointer(int index, int x, int y, int pointerId, int time) {
@@ -105,72 +103,4 @@ public class InputPointers {
     public int[] getTimes() {
         return mTimes.getPrimitiveArray();
     }
-
-    private static class ScalableIntArray {
-        private int[] mArray;
-        private int mLength;
-
-        public ScalableIntArray(int capacity) {
-            reset(capacity);
-        }
-
-        public void add(int index, int val) {
-            if (mLength < index + 1) {
-                mLength = index;
-                add(val);
-            } else {
-                mArray[index] = val;
-            }
-        }
-
-        public void add(int val) {
-            final int nextLength = mLength + 1;
-            ensureCapacity(nextLength);
-            mArray[mLength] = val;
-            mLength = nextLength;
-        }
-
-        private void ensureCapacity(int minimumCapacity) {
-            if (mArray.length < minimumCapacity) {
-                final int nextCapacity = mArray.length * 2;
-                // The following is the same as newLength = Math.max(minimumCapacity, nextCapacity);
-                final int newLength = minimumCapacity > nextCapacity
-                        ? minimumCapacity
-                        : nextCapacity;
-                mArray = Arrays.copyOf(mArray, newLength);
-            }
-        }
-
-        public int getLength() {
-            return mLength;
-        }
-
-        public void reset(int capacity) {
-            mArray = new int[capacity];
-            mLength = 0;
-        }
-
-        public int[] getPrimitiveArray() {
-            return mArray;
-        }
-
-        public void set(ScalableIntArray ip) {
-            mArray = ip.mArray;
-            mLength = ip.mLength;
-        }
-
-        public void copy(ScalableIntArray ip) {
-            ensureCapacity(ip.mLength);
-            System.arraycopy(ip.mArray, 0, mArray, 0, ip.mLength);
-            mLength = ip.mLength;
-        }
-
-        public void append(ScalableIntArray src, int startPos, int length) {
-            final int currentLength = mLength;
-            final int newLength = currentLength + length;
-            ensureCapacity(newLength);
-            System.arraycopy(src.mArray, startPos, mArray, currentLength, length);
-            mLength = newLength;
-        }
-    }
 }
diff --git a/java/src/com/android/inputmethod/latin/ResizableIntArray.java b/java/src/com/android/inputmethod/latin/ResizableIntArray.java
new file mode 100644
index 0000000000000000000000000000000000000000..2079c0e9980a82978ff10c73ac3d5adac78f9304
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/ResizableIntArray.java
@@ -0,0 +1,95 @@
+/*
+ * 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.latin;
+
+import java.util.Arrays;
+
+// TODO: This class is not thread-safe.
+public class ResizableIntArray {
+    private int[] mArray;
+    private int mLength;
+
+    public ResizableIntArray(int capacity) {
+        reset(capacity);
+    }
+
+    public void add(int index, int val) {
+        if (mLength < index + 1) {
+            mLength = index;
+            add(val);
+        } else {
+            mArray[index] = val;
+        }
+    }
+
+    public void add(int val) {
+        final int nextLength = mLength + 1;
+        ensureCapacity(nextLength);
+        mArray[mLength] = val;
+        mLength = nextLength;
+    }
+
+    private void ensureCapacity(int minimumCapacity) {
+        if (mArray.length < minimumCapacity) {
+            final int nextCapacity = mArray.length * 2;
+            // The following is the same as newLength =
+            // Math.max(minimumCapacity, nextCapacity);
+            final int newLength = minimumCapacity > nextCapacity
+                    ? minimumCapacity
+                    : nextCapacity;
+            // TODO: Implement primitive array pool.
+            mArray = Arrays.copyOf(mArray, newLength);
+        }
+    }
+
+    public int getLength() {
+        return mLength;
+    }
+
+    // TODO: Implement setLength(int).
+
+    public void reset(int capacity) {
+        // TODO: Implement primitive array pool.
+        mArray = new int[capacity];
+        mLength = 0;
+    }
+
+    public int[] getPrimitiveArray() {
+        return mArray;
+    }
+
+    public void set(ResizableIntArray ip) {
+        // TODO: Implement primitive array pool.
+        mArray = ip.mArray;
+        mLength = ip.mLength;
+    }
+
+    public void copy(ResizableIntArray ip) {
+        // TODO: Avoid useless coping of values.
+        ensureCapacity(ip.mLength);
+        System.arraycopy(ip.mArray, 0, mArray, 0, ip.mLength);
+        mLength = ip.mLength;
+    }
+
+    public void append(ResizableIntArray src, int startPos, int length) {
+        final int currentLength = mLength;
+        final int newLength = currentLength + length;
+        ensureCapacity(newLength);
+        System.arraycopy(src.mArray, startPos, mArray, currentLength, length);
+        mLength = newLength;
+    }
+}
diff --git a/tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java b/tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b869b6ca71e0e364365f96b778058bf56611b39
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java
@@ -0,0 +1,133 @@
+/*
+ * 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.latin;
+
+import android.test.AndroidTestCase;
+
+public class ResizableIntArrayTests extends AndroidTestCase {
+    private static final int DEFAULT_CAPACITY = 48;
+
+    public void testNewInstance() {
+        final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
+        assertEquals("new instance length", 0, src.getLength());
+        assertNotNull("new instance array", src.getPrimitiveArray());
+    }
+
+    public void testReset() {
+        final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
+        final int[] array = src.getPrimitiveArray();
+
+        src.reset(DEFAULT_CAPACITY);
+        assertEquals("length after reset", 0, src.getLength());
+        assertNotSame("array after reset", array, src.getPrimitiveArray());
+    }
+
+    public void testAdd() {
+        final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
+        final int limit = src.getPrimitiveArray().length * 2 + 10;
+        for (int i = 0; i < limit; i++) {
+            src.add(i);
+            assertEquals("length after add " + i, i + 1, src.getLength());
+        }
+        for (int i = 0; i < limit; i++) {
+            assertEquals("value at " + i, i, src.getPrimitiveArray()[i]);
+        }
+    }
+
+    public void testAddAt() {
+        final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
+        final int limit = 1000, step = 100;
+        for (int i = 0; i < limit; i += step) {
+            src.add(i, i);
+            assertEquals("length after add at " + i, i + 1, src.getLength());
+        }
+        for (int i = 0; i < limit; i += step) {
+            assertEquals("value at " + i, i, src.getPrimitiveArray()[i]);
+        }
+    }
+
+    public void testSet() {
+        final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
+        final int limit = src.getPrimitiveArray().length * 2 + 10;
+        for (int i = 0; i < limit; i++) {
+            src.add(i);
+        }
+        final ResizableIntArray dst = new ResizableIntArray(DEFAULT_CAPACITY);
+        dst.set(src);
+        assertEquals("length after set", dst.getLength(), src.getLength());
+        assertSame("array after set", dst.getPrimitiveArray(), src.getPrimitiveArray());
+    }
+
+    public void testCopy() {
+        final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
+        final int limit = 100;
+        for (int i = 0; i < limit; i++) {
+            src.add(i);
+        }
+        final ResizableIntArray dst = new ResizableIntArray(DEFAULT_CAPACITY);
+        dst.copy(src);
+        assertEquals("length after copy", dst.getLength(), src.getLength());
+        assertNotSame("array after copy", dst.getPrimitiveArray(), src.getPrimitiveArray());
+        final int length = dst.getLength();
+        assertArrayEquals("values after copy",
+                dst.getPrimitiveArray(), 0, src.getPrimitiveArray(), 0, length);
+    }
+
+    public void testAppend() {
+        final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
+        final int srcLen = 100;
+        for (int i = 0; i < srcLen; i++) {
+            src.add(i);
+        }
+        final int dstLen = 50;
+        final ResizableIntArray dst = new ResizableIntArray(DEFAULT_CAPACITY);
+        for (int i = 0; i < dstLen; i++) {
+            final int value = -i - 1;
+            dst.add(value);
+        }
+        final ResizableIntArray dstCopy = new ResizableIntArray(dst.getLength());
+        dstCopy.copy(dst);
+
+        dst.append(src, 0, 0);
+        assertEquals("length after append zero", dstLen, dst.getLength());
+        assertArrayEquals("values after append zero",
+                dstCopy.getPrimitiveArray(), 0, dst.getPrimitiveArray(), 0, dstLen);
+
+        dst.append(src, 0, srcLen);
+        assertEquals("length after append", dstLen + srcLen, dst.getLength());
+        assertTrue("primitive length after append",
+                dst.getPrimitiveArray().length >= dstLen + srcLen);
+        assertArrayEquals("original values after append",
+                dstCopy.getPrimitiveArray(), 0, dst.getPrimitiveArray(), 0, dstLen);
+        assertArrayEquals("appended values after append",
+                src.getPrimitiveArray(), 0, dst.getPrimitiveArray(), dstLen, srcLen);
+    }
+
+    private static void assertArrayEquals(String message, int[] expecteds, int expectedPos,
+            int[] actuals, int actualPos, int length) {
+        if (expecteds == null && actuals == null) {
+            return;
+        }
+        if (expecteds == null || actuals == null) {
+            fail(message + ": expecteds=" + expecteds + " actuals=" + actuals);
+        }
+        for (int i = 0; i < length; i++) {
+            assertEquals(message + ": element at " + i,
+                    expecteds[i + expectedPos], actuals[i + actualPos]);
+        }
+    }
+}