First pass at cleaning up the gestures code.
diff --git a/tests/sketch/src/com/android/gesture/Gesture.java b/tests/sketch/src/com/android/gesture/Gesture.java
index a5e7a25..44711ca 100755
--- a/tests/sketch/src/com/android/gesture/Gesture.java
+++ b/tests/sketch/src/com/android/gesture/Gesture.java
@@ -34,13 +34,11 @@
  */
 
 public class Gesture implements Parcelable {
-
     private static final long GESTURE_ID_BASE = System.currentTimeMillis();
 
     private static final int BITMAP_RENDERING_WIDTH = 2;
 
     private static final boolean BITMAP_RENDERING_ANTIALIAS = true;
-
     private static final boolean BITMAP_RENDERING_DITHER = true;
 
     private static int sGestureCount = 0;
@@ -50,7 +48,7 @@
     // the same as its instance ID
     private long mGestureID;
 
-    private ArrayList<GestureStroke> mStrokes = new ArrayList<GestureStroke>();
+    private final ArrayList<GestureStroke> mStrokes = new ArrayList<GestureStroke>();
 
     public Gesture() {
         mGestureID = GESTURE_ID_BASE + sGestureCount++;
@@ -93,12 +91,13 @@
      */
     public float getLength() {
         int len = 0;
-        ArrayList<GestureStroke> strokes = mStrokes;
-        int count = strokes.size();
+        final ArrayList<GestureStroke> strokes = mStrokes;
+        final int count = strokes.size();
+
         for (int i = 0; i < count; i++) {
-            GestureStroke stroke = strokes.get(i);
-            len += stroke.length;
+            len += strokes.get(i).length;
         }
+
         return len;
     }
 
@@ -131,11 +130,11 @@
      * @param canvas
      */
     void draw(Canvas canvas, Paint paint) {
-        ArrayList<GestureStroke> strokes = mStrokes;
-        int count = strokes.size();
+        final ArrayList<GestureStroke> strokes = mStrokes;
+        final int count = strokes.size();
+
         for (int i = 0; i < count; i++) {
-            GestureStroke stroke = strokes.get(i);
-            stroke.draw(canvas, paint);
+            strokes.get(i).draw(canvas, paint);
         }
     }
 
@@ -150,7 +149,6 @@
      * @return the bitmap
      */
     public Bitmap toBitmap(int width, int height, int edge, int numSample, int color) {
-        RectF bbx = getBoundingBox();
         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
         Canvas canvas = new Canvas(bitmap);
         canvas.translate(edge, edge);
@@ -162,11 +160,12 @@
         paint.setStrokeJoin(Paint.Join.ROUND);
         paint.setStrokeCap(Paint.Cap.ROUND);
         paint.setStrokeWidth(BITMAP_RENDERING_WIDTH);
-        ArrayList<GestureStroke> strokes = mStrokes;
-        int count = strokes.size();
+
+        final ArrayList<GestureStroke> strokes = mStrokes;
+        final int count = strokes.size();
+
         for (int i = 0; i < count; i++) {
-            GestureStroke stroke = strokes.get(i);
-            Path path = stroke.toPath(width - 2 * edge, height - 2 * edge, numSample);
+            Path path = strokes.get(i).toPath(width - 2 * edge, height - 2 * edge, numSample);
             canvas.drawPath(path, paint);
         }
 
@@ -183,7 +182,6 @@
      * @return the bitmap
      */
     public Bitmap toBitmap(int width, int height, int edge, int color) {
-        RectF bbx = getBoundingBox();
         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
         Canvas canvas = new Canvas(bitmap);
         canvas.translate(edge, edge);
@@ -232,7 +230,8 @@
     public void createFromString(String str) {
         int startIndex = 0;
         int endIndex;
-        while ((endIndex = str.indexOf(GestureConstants.STRING_GESTURE_DELIIMITER, startIndex + 1)) != -1) {
+        while ((endIndex =
+                str.indexOf(GestureConstants.STRING_GESTURE_DELIIMITER, startIndex + 1)) != -1) {
             String token = str.substring(startIndex, endIndex);
             if (startIndex > 0) { // stroke tokens
                 addStroke(GestureStroke.createFromString(token));
diff --git a/tests/sketch/src/com/android/gesture/GestureActionListener.java b/tests/sketch/src/com/android/gesture/GestureActionListener.java
index 130ac19..c9c5232 100644
--- a/tests/sketch/src/com/android/gesture/GestureActionListener.java
+++ b/tests/sketch/src/com/android/gesture/GestureActionListener.java
@@ -16,7 +16,6 @@
 
 package com.android.gesture;
 
-
 public interface GestureActionListener {
     public void onGesturePerformed(GestureOverlay overlay, Gesture gesture);
 }
diff --git a/tests/sketch/src/com/android/gesture/GestureConstants.java b/tests/sketch/src/com/android/gesture/GestureConstants.java
index 0e17c8a..cb64791 100644
--- a/tests/sketch/src/com/android/gesture/GestureConstants.java
+++ b/tests/sketch/src/com/android/gesture/GestureConstants.java
@@ -28,4 +28,5 @@
     static final int STROKE_STRING_BUFFER_SIZE = 1024;
     static final int STROKE_POINT_BUFFER_SIZE = 100; // number of points
     static final int IO_BUFFER_SIZE = 8 * 1024; // 8K
+    String LOG_TAG = "GestureLibrary";
 }
diff --git a/tests/sketch/src/com/android/gesture/GestureLibrary.java b/tests/sketch/src/com/android/gesture/GestureLibrary.java
index c89aa16..3e753e7 100644
--- a/tests/sketch/src/com/android/gesture/GestureLibrary.java
+++ b/tests/sketch/src/com/android/gesture/GestureLibrary.java
@@ -36,36 +36,33 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Set;
 
+import static com.android.gesture.GestureConstants.LOG_TAG;
+
 /**
  * GestureLibrary maintains gesture examples and makes predictions on a new
  * gesture
  */
 public class GestureLibrary {
 
-    public static final int SEQUENCE_INVARIANT = 1;
+    private static final String NAMESPACE = "";
 
+    public static final int SEQUENCE_INVARIANT = 1;
     // when SEQUENCE_SENSITIVE is used, only single stroke gestures are allowed
     public static final int SEQUENCE_SENSITIVE = 2;
 
-    private int mSequenceType = SEQUENCE_SENSITIVE;
-
     public static final int ORIENTATION_INVARIANT = 1;
-
     // ORIENTATION_SENSITIVE is only available for single stroke gestures
     public static final int ORIENTATION_SENSITIVE = 2;
 
+    private int mSequenceType = SEQUENCE_SENSITIVE;
     private int mOrientationStyle = ORIENTATION_SENSITIVE;
 
-    private static final String LOGTAG = "GestureLibrary";
-
-    private static final String NAMESPACE = "";
-
     private final String mGestureFileName;
 
-    private HashMap<String, ArrayList<Gesture>> mEntryName2gestures = new HashMap<String, ArrayList<Gesture>>();
+    private final HashMap<String, ArrayList<Gesture>> mEntryName2gestures =
+            new HashMap<String, ArrayList<Gesture>>();
 
     private Learner mClassifier;
 
@@ -128,9 +125,6 @@
      * @param gesture
      */
     public void addGesture(String entryName, Gesture gesture) {
-        if (Config.DEBUG) {
-            Log.v(LOGTAG, "Add an example for gesture: " + entryName);
-        }
         if (entryName == null || entryName.length() == 0) {
             return;
         }
@@ -186,11 +180,10 @@
      * @param entryName
      * @return the list of gestures that is under this name
      */
-    @SuppressWarnings("unchecked")
     public ArrayList<Gesture> getGestures(String entryName) {
         ArrayList<Gesture> gestures = mEntryName2gestures.get(entryName);
         if (gestures != null) {
-            return (ArrayList<Gesture>)gestures.clone();
+            return new ArrayList<Gesture>(gestures);
         } else {
             return null;
         }
@@ -199,30 +192,33 @@
     /**
      * Save the gesture library
      */
-    public void save() {
-        if (!mChanged)
-            return;
+    public boolean save() {
+        if (!mChanged) {
+            return true;
+        }
+
+        boolean result= false;
+        PrintWriter writer = null;
 
         try {
             File file = new File(mGestureFileName);
             if (!file.getParentFile().exists()) {
-                file.getParentFile().mkdirs();
+                if (!file.getParentFile().mkdirs()) {
+                    return false;
+                }
             }
-            if (Config.DEBUG) {
-                Log.v(LOGTAG, "Save to " + mGestureFileName);
-            }
-            BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(
-                    mGestureFileName), GestureConstants.IO_BUFFER_SIZE);
 
-            PrintWriter writer = new PrintWriter(outputStream);
-            XmlSerializer serializer = Xml.newSerializer();
+            writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(
+                    mGestureFileName), GestureConstants.IO_BUFFER_SIZE));
+
+            final XmlSerializer serializer = Xml.newSerializer();
             serializer.setOutput(writer);
             serializer.startDocument(Encoding.ISO_8859_1.name(), null);
             serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY);
-            HashMap<String, ArrayList<Gesture>> maps = mEntryName2gestures;
-            Iterator<String> it = maps.keySet().iterator();
-            while (it.hasNext()) {
-                String key = it.next();
+
+            final HashMap<String, ArrayList<Gesture>> maps = mEntryName2gestures;
+
+            for (String key : maps.keySet()) {
                 ArrayList<Gesture> examples = maps.get(key);
                 // save an entry
                 serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY);
@@ -235,53 +231,64 @@
                 }
                 serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY);
             }
+
             serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY);
             serializer.endDocument();
             serializer.flush();
-            writer.close();
-            outputStream.close();
+
             mChanged = false;
+            result = true;
         } catch (IOException ex) {
-            Log.d(LOGTAG, "Failed to save gestures:", ex);
+            Log.d(LOG_TAG, "Failed to save gestures:", ex);
+        } finally {
+            GestureUtilities.closeStream(writer);
         }
+
+        return result;
     }
 
     /**
      * Load the gesture library
      */
-    public void load() {
-        File file = new File(mGestureFileName);
+    public boolean load() {
+        boolean result = false;
+
+        final File file = new File(mGestureFileName);
         if (file.exists()) {
+            BufferedInputStream in = null;
             try {
                 if (Config.DEBUG) {
-                    Log.v(LOGTAG, "Load from " + mGestureFileName);
+                    Log.v(LOG_TAG, "Load from " + mGestureFileName);
                 }
-                BufferedInputStream in = new BufferedInputStream(new FileInputStream(
+                in = new BufferedInputStream(new FileInputStream(
                         mGestureFileName), GestureConstants.IO_BUFFER_SIZE);
                 Xml.parse(in, Encoding.ISO_8859_1, new CompactInkHandler());
-                in.close();
+                result = true;
             } catch (SAXException ex) {
-                Log.d(LOGTAG, "Failed to load gestures:", ex);
+                Log.d(LOG_TAG, "Failed to load gestures:", ex);
             } catch (IOException ex) {
-                Log.d(LOGTAG, "Failed to load gestures:", ex);
+                Log.d(LOG_TAG, "Failed to load gestures:", ex);
+            } finally {
+                GestureUtilities.closeStream(in);
             }
         }
+
+        return result;
     }
 
     private class CompactInkHandler implements ContentHandler {
-        Gesture currentGesture = null;
+        final StringBuilder mBuffer = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
 
-        StringBuilder buffer = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
+        String mEntryName;
 
-        String entryName;
-
-        ArrayList<Gesture> gestures;
+        Gesture mCurrentGesture = null;
+        ArrayList<Gesture> mGestures;
 
         CompactInkHandler() {
         }
 
         public void characters(char[] ch, int start, int length) {
-            buffer.append(ch, start, length);
+            mBuffer.append(ch, start, length);
         }
 
         public void endDocument() {
@@ -289,16 +296,16 @@
 
         public void endElement(String uri, String localName, String qName) {
             if (localName.equals(GestureConstants.XML_TAG_ENTRY)) {
-                mEntryName2gestures.put(entryName, gestures);
-                gestures = null;
+                mEntryName2gestures.put(mEntryName, mGestures);
+                mGestures = null;
             } else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) {
-                gestures.add(currentGesture);
+                mGestures.add(mCurrentGesture);
                 mClassifier.addInstance(Instance.createInstance(GestureLibrary.this,
-                        currentGesture, entryName));
-                currentGesture = null;
+                        mCurrentGesture, mEntryName));
+                mCurrentGesture = null;
             } else if (localName.equals(GestureConstants.XML_TAG_STROKE)) {
-                currentGesture.addStroke(GestureStroke.createFromString(buffer.toString()));
-                buffer.setLength(0);
+                mCurrentGesture.addStroke(GestureStroke.createFromString(mBuffer.toString()));
+                mBuffer.setLength(0);
             }
         }
 
@@ -322,11 +329,11 @@
 
         public void startElement(String uri, String localName, String qName, Attributes attributes) {
             if (localName.equals(GestureConstants.XML_TAG_ENTRY)) {
-                gestures = new ArrayList<Gesture>();
-                entryName = attributes.getValue(NAMESPACE, GestureConstants.XML_TAG_NAME);
+                mGestures = new ArrayList<Gesture>();
+                mEntryName = attributes.getValue(NAMESPACE, GestureConstants.XML_TAG_NAME);
             } else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) {
-                currentGesture = new Gesture();
-                currentGesture.setID(Long.parseLong(attributes.getValue(NAMESPACE,
+                mCurrentGesture = new Gesture();
+                mCurrentGesture.setID(Long.parseLong(attributes.getValue(NAMESPACE,
                         GestureConstants.XML_TAG_ID)));
             }
         }
diff --git a/tests/sketch/src/com/android/gesture/GestureOverlay.java b/tests/sketch/src/com/android/gesture/GestureOverlay.java
index 9907831..72ab787 100755
--- a/tests/sketch/src/com/android/gesture/GestureOverlay.java
+++ b/tests/sketch/src/com/android/gesture/GestureOverlay.java
@@ -20,7 +20,6 @@
 import android.graphics.Bitmap;
 import android.graphics.BlurMaskFilter;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Rect;
@@ -37,32 +36,32 @@
  */
 
 public class GestureOverlay extends View {
-
     static final float TOUCH_TOLERANCE = 3;
 
-    private static final int TRANSPARENT_BACKGROUND = Color.argb(0, 0, 0, 0);
+    // TODO: Move all these values into XML attributes
+    private static final int TRANSPARENT_BACKGROUND = 0x00000000;
 
     private static final float FADING_ALPHA_CHANGE = 0.03f;
-
     private static final long FADING_REFRESHING_RATE = 100;
 
     private static final int GESTURE_STROKE_WIDTH = 12;
-
     private static final boolean GESTURE_RENDERING_ANTIALIAS = true;
 
-    private static final BlurMaskFilter BLUR_MASK_FILTER = new BlurMaskFilter(1, BlurMaskFilter.Blur.NORMAL);
-    
     private static final boolean DITHER_FLAG = true;
 
+    public static final int DEFAULT_GESTURE_COLOR = 0xFFFFFF00;
+
     private static final int REFRESH_RANGE = 10;
 
-    public static final int DEFAULT_GESTURE_COLOR = Color.argb(255, 255, 255, 0);
+    private static final BlurMaskFilter BLUR_MASK_FILTER =
+            new BlurMaskFilter(1, BlurMaskFilter.Blur.NORMAL);
+    
 
     // double buffering
     private Paint mGesturePaint;
 
+    private final Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
     private Bitmap mBitmap; // with transparent background
-
     private Canvas mBitmapCanvas;
 
     // for rendering immediate ink feedback
@@ -71,31 +70,25 @@
     private Path mPath;
 
     private float mX;
-
     private float mY;
     
     private float mCurveEndX;
-    
     private float mCurveEndY;
 
     // current gesture
     private Gesture mCurrentGesture = null;
 
-    // gesture event handlers
-    ArrayList<GestureListener> mGestureListeners = new ArrayList<GestureListener>();
-
+    // TODO: Make this a list of WeakReferences
+    private final ArrayList<GestureListener> mGestureListeners = new ArrayList<GestureListener>();
     private ArrayList<GesturePoint> mPointBuffer = null;
 
     // fading out effect
     private boolean mIsFadingOut = false;
-
     private float mFadingAlpha = 1;
 
     private Handler mHandler = new Handler();
 
-    private Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
-
-    private Runnable mFadingOut = new Runnable() {
+    private final Runnable mFadingOut = new Runnable() {
         public void run() {
             if (mIsFadingOut) {
                 mFadingAlpha -= FADING_ALPHA_CHANGE;
@@ -165,13 +158,15 @@
 
     private void init() {
         mGesturePaint = new Paint();
-        mGesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
-        mGesturePaint.setColor(DEFAULT_GESTURE_COLOR);
-        mGesturePaint.setStyle(Paint.Style.STROKE);
-        mGesturePaint.setStrokeJoin(Paint.Join.ROUND);
-        mGesturePaint.setStrokeCap(Paint.Cap.ROUND);
-        mGesturePaint.setStrokeWidth(GESTURE_STROKE_WIDTH);
-        mGesturePaint.setDither(DITHER_FLAG);
+
+        final Paint gesturePaint = mGesturePaint;
+        gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
+        gesturePaint.setColor(DEFAULT_GESTURE_COLOR);
+        gesturePaint.setStyle(Paint.Style.STROKE);
+        gesturePaint.setStrokeJoin(Paint.Join.ROUND);
+        gesturePaint.setStrokeCap(Paint.Cap.ROUND);
+        gesturePaint.setStrokeWidth(GESTURE_STROKE_WIDTH);
+        gesturePaint.setDither(DITHER_FLAG);
 
         mPath = null;
     }
@@ -179,14 +174,24 @@
     @Override
     protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
         super.onSizeChanged(width, height, oldWidth, oldHeight);
+
         if (width <= 0 || height <= 0) {
             return;
         }
+
         int targetWidth = width > oldWidth ? width : oldWidth;
         int targetHeight = height > oldHeight ? height : oldHeight;
+
+        if (mBitmap != null) mBitmap.recycle();
+
         mBitmap = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888);
-        mBitmapCanvas = new Canvas(mBitmap);
+        if (mBitmapCanvas != null) {
+            mBitmapCanvas.setBitmap(mBitmap);
+        } else {
+            mBitmapCanvas = new Canvas(mBitmap);
+        }
         mBitmapCanvas.drawColor(TRANSPARENT_BACKGROUND);
+
         if (mCurrentGesture != null) {
             mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
         }
@@ -248,7 +253,6 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-
         if (!isEnabled()) {
             return true;
         }
@@ -275,8 +279,8 @@
 
     private Rect touchStart(MotionEvent event) {
         // pass the event to handlers
-        ArrayList<GestureListener> listeners = mGestureListeners;
-        int count = listeners.size();
+        final ArrayList<GestureListener> listeners = mGestureListeners;
+        final int count = listeners.size();
         for (int i = 0; i < count; i++) {
             GestureListener listener = listeners.get(i);
             listener.onStartGesture(this, event);
@@ -306,8 +310,8 @@
         mPath = new Path();
         mPath.moveTo(x, y);
 
-        mInvalidRect.set((int) x - REFRESH_RANGE, (int) y - REFRESH_RANGE, (int) x + REFRESH_RANGE,
-                (int) y + REFRESH_RANGE);
+        mInvalidRect.set((int) x - REFRESH_RANGE, (int) y - REFRESH_RANGE,
+                (int) x + REFRESH_RANGE, (int) y + REFRESH_RANGE);
         
         mCurveEndX = x;
         mCurveEndY = y;
@@ -352,11 +356,10 @@
         mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));
 
         // pass the event to handlers
-        ArrayList<GestureListener> listeners = mGestureListeners;
-        int count = listeners.size();
+        final ArrayList<GestureListener> listeners = mGestureListeners;
+        final int count = listeners.size();
         for (int i = 0; i < count; i++) {
-            GestureListener listener = listeners.get(i);
-            listener.onGesture(this, event);
+            listeners.get(i).onGesture(this, event);
         }
         
         return areaToRefresh;
@@ -372,11 +375,10 @@
         mGesturePaint.setMaskFilter(null);
         
         // pass the event to handlers
-        ArrayList<GestureListener> listeners = mGestureListeners;
-        int count = listeners.size();
+        final ArrayList<GestureListener> listeners = mGestureListeners;
+        final int count = listeners.size();
         for (int i = 0; i < count; i++) {
-            GestureListener listener = listeners.get(i);
-            listener.onFinishGesture(this, event);
+            listeners.get(i).onFinishGesture(this, event);
         }
         
         mPath = null;        
diff --git a/tests/sketch/src/com/android/gesture/GesturePoint.java b/tests/sketch/src/com/android/gesture/GesturePoint.java
index d06eff47..81e59a4 100644
--- a/tests/sketch/src/com/android/gesture/GesturePoint.java
+++ b/tests/sketch/src/com/android/gesture/GesturePoint.java
@@ -21,15 +21,14 @@
  */
 
 public class GesturePoint {
-    public final float xpos;
-
-    public final float ypos;
+    public final float x;
+    public final float y;
 
     public final long timestamp;
 
     public GesturePoint(float x, float y, long t) {
-        xpos = x;
-        ypos = y;
+        this.x = x;
+        this.y = y;
         timestamp = t;
     }
 }
diff --git a/tests/sketch/src/com/android/gesture/GestureStroke.java b/tests/sketch/src/com/android/gesture/GestureStroke.java
index b5e38b7..3555010 100644
--- a/tests/sketch/src/com/android/gesture/GestureStroke.java
+++ b/tests/sketch/src/com/android/gesture/GestureStroke.java
@@ -34,50 +34,48 @@
     public final RectF boundingBox;
 
     public final float length;
-
     public final float[] points;
 
     private final long[] timestamps;
-
     private Path mCachedPath;
 
     /**
      * Construct a gesture stroke from a list of gesture points
      * 
-     * @param pts
+     * @param points
      */
-    public GestureStroke(ArrayList<GesturePoint> pts) {
-        float[] tmpPoints = new float[pts.size() * 2];
-        long[] times = new long[pts.size()];
+    public GestureStroke(ArrayList<GesturePoint> points) {
+        final int count = points.size();
+        final float[] tmpPoints = new float[count * 2];
+        final long[] times = new long[count];
 
         RectF bx = null;
         float len = 0;
         int index = 0;
-        int count = pts.size();
 
         for (int i = 0; i < count; i++) {
-            GesturePoint p = pts.get(i);
-            tmpPoints[i * 2] = p.xpos;
-            tmpPoints[i * 2 + 1] = p.ypos;
+            final GesturePoint p = points.get(i);
+            tmpPoints[i * 2] = p.x;
+            tmpPoints[i * 2 + 1] = p.y;
             times[index] = p.timestamp;
 
             if (bx == null) {
                 bx = new RectF();
-                bx.top = p.ypos;
-                bx.left = p.xpos;
-                bx.right = p.xpos;
-                bx.bottom = p.ypos;
+                bx.top = p.y;
+                bx.left = p.x;
+                bx.right = p.x;
+                bx.bottom = p.y;
                 len = 0;
             } else {
-                len += Math.sqrt(Math.pow(p.xpos - tmpPoints[(i - 1) * 2], 2)
-                        + Math.pow(p.ypos - tmpPoints[(i -1 ) * 2 + 1], 2));
-                bx.union(p.xpos, p.ypos);
+                len += Math.sqrt(Math.pow(p.x - tmpPoints[(i - 1) * 2], 2)
+                        + Math.pow(p.y - tmpPoints[(i -1 ) * 2 + 1], 2));
+                bx.union(p.x, p.y);
             }
             index++;
         }
         
         timestamps = times;
-        points = tmpPoints;
+        this.points = tmpPoints;
         boundingBox = bx;
         length = len;
     }
@@ -89,13 +87,17 @@
      */
     void draw(Canvas canvas, Paint paint) {
         if (mCachedPath == null) {
-            float[] pts = points;
-            int count = pts.length;
+            final float[] localPoints = points;
+            final int count = localPoints.length;
+
             Path path = null;
-            float mX = 0, mY = 0;
+
+            float mX = 0;
+            float mY = 0;
+
             for (int i = 0; i < count; i += 2) {
-                float x = pts[i];
-                float y = pts[i + 1];
+                float x = localPoints[i];
+                float y = localPoints[i + 1];
                 if (path == null) {
                     path = new Path();
                     path.moveTo(x, y);
@@ -127,22 +129,22 @@
      * @return the path
      */
     public Path toPath(float width, float height, int numSample) {
-        float[] pts = GestureUtils.temporalSampling(this, numSample);
-        RectF rect = boundingBox;
-        float scale = height / rect.height();
-        Matrix matrix = new Matrix();
+        final float[] pts = GestureUtilities.temporalSampling(this, numSample);
+        final RectF rect = boundingBox;
+        final float scale = height / rect.height();
+
+        final Matrix matrix = new Matrix();
         matrix.setTranslate(-rect.left, -rect.top);
-        Matrix scaleMatrix = new Matrix();
-        scaleMatrix.setScale(scale, scale);
-        matrix.postConcat(scaleMatrix);
-        Matrix translate = new Matrix();
-        matrix.postConcat(translate);
+        matrix.postScale(scale, scale);
         matrix.mapPoints(pts);
 
-        Path path = null;
         float mX = 0;
         float mY = 0;
-        int count = pts.length;
+
+        Path path = null;
+
+        final int count = pts.length;
+
         for (int i = 0; i < count; i += 2) {
             float x = pts[i];
             float y = pts[i + 1];
@@ -161,6 +163,7 @@
                 }
             }
         }
+
         return path;
     }
 
@@ -184,11 +187,14 @@
      * @return the gesture stroke
      */
     public static GestureStroke createFromString(String str) {
-        ArrayList<GesturePoint> points = new ArrayList<GesturePoint>(
+        final ArrayList<GesturePoint> points = new ArrayList<GesturePoint>(
                 GestureConstants.STROKE_POINT_BUFFER_SIZE);
+
         int endIndex;
         int startIndex = 0;
-        while ((endIndex = str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1)) != -1) {
+
+        while ((endIndex =
+                str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1)) != -1) {
 
             // parse x
             String token = str.substring(startIndex, endIndex);
@@ -209,6 +215,7 @@
 
             points.add(new GesturePoint(x, y, time));
         }
+
         return new GestureStroke(points);
     }
 
@@ -217,15 +224,17 @@
      */
     @Override
     public String toString() {
-        StringBuilder str = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
-        float[] pts = points;
-        long[] times = timestamps;
-        int count = points.length;
+        final StringBuilder str = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
+        final float[] pts = points;
+        final long[] times = timestamps;
+        final int count = points.length;
+
         for (int i = 0; i < count; i += 2) {
-            str.append(points[i] + GestureConstants.STRING_STROKE_DELIIMITER + points[i + 1]
-                    + GestureConstants.STRING_STROKE_DELIIMITER + times[i / 2]
-                    + GestureConstants.STRING_STROKE_DELIIMITER);
+            str.append(pts[i]).append(GestureConstants.STRING_STROKE_DELIIMITER);
+            str.append(pts[i + 1]).append(GestureConstants.STRING_STROKE_DELIIMITER);
+            str.append(times[i / 2]).append(GestureConstants.STRING_STROKE_DELIIMITER);
         }
+
         return str.toString();
     }
 
diff --git a/tests/sketch/src/com/android/gesture/GestureUtils.java b/tests/sketch/src/com/android/gesture/GestureUtilities.java
similarity index 89%
rename from tests/sketch/src/com/android/gesture/GestureUtils.java
rename to tests/sketch/src/com/android/gesture/GestureUtilities.java
index 09d2625..2798616 100755
--- a/tests/sketch/src/com/android/gesture/GestureUtils.java
+++ b/tests/sketch/src/com/android/gesture/GestureUtilities.java
@@ -17,15 +17,37 @@
 package com.android.gesture;
 
 import android.graphics.RectF;
+import android.graphics.Matrix;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.io.Closeable;
+import java.io.IOException;
 
-public class GestureUtils {
+import static com.android.gesture.GestureConstants.*;
 
+public final class GestureUtilities {
     private static final int TEMPORAL_SAMPLING_RATE = 16;
-   
-    protected static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension) {
+
+    private GestureUtilities() {
+    }
+
+    /**
+     * Closes the specified stream.
+     *
+     * @param stream The stream to close.
+     */
+    static void closeStream(Closeable stream) {
+        if (stream != null) {
+            try {
+                stream.close();
+            } catch (IOException e) {
+                android.util.Log.e(LOG_TAG, "Could not close stream", e);
+            }
+        }
+    }
+
+    static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension) {
         final float targetPatchSize = sampleMatrixDimension - 1; // edge inclusive
         float[] sample = new float[sampleMatrixDimension * sampleMatrixDimension];
         Arrays.fill(sample, 0);
@@ -120,7 +142,6 @@
         return sample;
     }
 
-    
     private static void plot(float x, float y, float[] sample, int sampleSize) {
         x = x < 0 ? 0 : x;
         y = y < 0 ? 0 : y;
@@ -175,7 +196,7 @@
      * @param sampleSize
      * @return a float array
      */
-    protected static float[] temporalSampling(GestureStroke stroke, int sampleSize) {
+    static float[] temporalSampling(GestureStroke stroke, int sampleSize) {
         final float increment = stroke.length / (sampleSize - 1);
         int vectorLength = sampleSize * 2;
         float[] vector = new float[vectorLength];
@@ -237,7 +258,7 @@
      * @param points
      * @return the centroid
      */
-    public static float[] computeCentroid(float[] points) {
+    static float[] computeCentroid(float[] points) {
         float centerX = 0;
         float centerY = 0;
         int count = points.length;
@@ -283,7 +304,7 @@
         return array;
     }
 
-    public static float computeTotalLength(float[] points) {
+    static float computeTotalLength(float[] points) {
         float sum = 0;
         int count = points.length - 4;
         for (int i = 0; i < count; i += 2) {
@@ -294,14 +315,14 @@
         return sum;
     }
 
-    public static double computeStraightness(float[] points) {
+    static double computeStraightness(float[] points) {
         float totalLen = computeTotalLength(points);
         float dx = points[2] - points[0];
         float dy = points[3] - points[1];
         return Math.sqrt(dx * dx + dy * dy) / totalLen;
     }
 
-    public static double computeStraightness(float[] points, float totalLen) {
+    static double computeStraightness(float[] points, float totalLen) {
         float dx = points[2] - points[0];
         float dy = points[3] - points[1];
         return Math.sqrt(dx * dx + dy * dy) / totalLen;
@@ -314,7 +335,7 @@
      * @param vector2
      * @return the distance
      */
-    protected static double squaredEuclideanDistance(float[] vector1, float[] vector2) {
+    static double squaredEuclideanDistance(float[] vector1, float[] vector2) {
         double squaredDistance = 0;
         int size = vector1.length;
         for (int i = 0; i < size; i++) {
@@ -331,7 +352,7 @@
      * @param in2
      * @return the distance between 0 and Math.PI
      */
-    protected static double cosineDistance(Instance in1, Instance in2) {
+    static double cosineDistance(Instance in1, Instance in2) {
         float sum = 0;
         float[] vector1 = in1.vector;
         float[] vector2 = in2.vector;
@@ -342,20 +363,19 @@
         return Math.acos(sum / (in1.magnitude * in2.magnitude));
     }
 
-    public static OrientedBoundingBox computeOrientedBBX(ArrayList<GesturePoint> pts) {
+    public static OrientedBoundingBox computeOrientedBoundingBox(ArrayList<GesturePoint> pts) {
         GestureStroke stroke = new GestureStroke(pts);
         float[] points = temporalSampling(stroke, TEMPORAL_SAMPLING_RATE);
-        return computeOrientedBBX(points);
+        return computeOrientedBoundingBox(points);
     }
 
-    public static OrientedBoundingBox computeOrientedBBX(float[] points) {
+    public static OrientedBoundingBox computeOrientedBoundingBox(float[] points) {
         float[] meanVector = computeCentroid(points);
-        return computeOrientedBBX(points, meanVector);
+        return computeOrientedBoundingBox(points, meanVector);
     }
 
-    public static OrientedBoundingBox computeOrientedBBX(float[] points, float[] centroid) {
-
-        android.graphics.Matrix tr = new android.graphics.Matrix();
+    public static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) {
+        Matrix tr = new Matrix();
         tr.setTranslate(-centroid[0], -centroid[1]);
         tr.mapPoints(points);
 
@@ -394,9 +414,7 @@
             }
         }
 
-        OrientedBoundingBox bbx = new OrientedBoundingBox(angle, centroid[0], centroid[1], maxx
-                - minx, maxy - miny);
-        return bbx;
+        return new OrientedBoundingBox(angle, centroid[0], centroid[1], maxx - minx, maxy - miny);
     }
 
     private static double[] computeOrientation(double[][] covarianceMatrix) {
diff --git a/tests/sketch/src/com/android/gesture/Instance.java b/tests/sketch/src/com/android/gesture/Instance.java
index 4fbebf9..011d1fc 100755
--- a/tests/sketch/src/com/android/gesture/Instance.java
+++ b/tests/sketch/src/com/android/gesture/Instance.java
@@ -21,7 +21,6 @@
  * label is null.
  */
 class Instance {
-
     private static final int SEQUENCE_SAMPLE_SIZE = 16;
 
     private static final int PATCH_SAMPLE_SIZE = 8;
@@ -40,10 +39,10 @@
     final float magnitude;
 
     // the id of the instance
-    final long instanceID;
+    final long id;
 
     private Instance(long id, float[] sample, String sampleName) {
-        instanceID = id;
+        this.id = id;
         vector = sample;
         label = sampleName;
         float sum = 0;
@@ -72,14 +71,13 @@
     }
 
     private static float[] spatialSampler(Gesture gesture) {
-        float[] pts = GestureUtils.spatialSampling(gesture, PATCH_SAMPLE_SIZE);
-        return pts;
+        return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE);
     }
 
     private static float[] temporalSampler(GestureLibrary gesturelib, Gesture gesture) {
-        float[] pts = GestureUtils.temporalSampling(gesture.getStrokes().get(0),
+        float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0),
                 SEQUENCE_SAMPLE_SIZE);
-        float[] center = GestureUtils.computeCentroid(pts);
+        float[] center = GestureUtilities.computeCentroid(pts);
         float orientation = (float) Math.atan2(pts[1] - center[1], pts[0] - center[0]);
         orientation *= 180 / Math.PI;
 
diff --git a/tests/sketch/src/com/android/gesture/InstanceLearner.java b/tests/sketch/src/com/android/gesture/InstanceLearner.java
index 95241d4..335719a 100644
--- a/tests/sketch/src/com/android/gesture/InstanceLearner.java
+++ b/tests/sketch/src/com/android/gesture/InstanceLearner.java
@@ -46,9 +46,9 @@
             }
             double distance;
             if (lib.getGestureType() == GestureLibrary.SEQUENCE_SENSITIVE) {
-                distance = GestureUtils.cosineDistance(sample, instance);
+                distance = GestureUtilities.cosineDistance(sample, instance);
             } else {
-                distance = GestureUtils.squaredEuclideanDistance(sample.vector, instance.vector);
+                distance = GestureUtilities.squaredEuclideanDistance(sample.vector, instance.vector);
             }
             double weight;
             if (distance == 0) {
diff --git a/tests/sketch/src/com/android/gesture/Learner.java b/tests/sketch/src/com/android/gesture/Learner.java
index 63f3156..b4183d2 100755
--- a/tests/sketch/src/com/android/gesture/Learner.java
+++ b/tests/sketch/src/com/android/gesture/Learner.java
@@ -22,7 +22,6 @@
  * The abstract class of a gesture learner
  */
 abstract class Learner {
-
     private final ArrayList<Instance> mInstances = new ArrayList<Instance>();
 
     /**
@@ -53,7 +52,7 @@
         int count = instances.size();
         for (int i = 0; i < count; i++) {
             Instance instance = instances.get(i);
-            if (id == instance.instanceID) {
+            if (id == instance.id) {
                 instances.remove(instance);
                 return;
             }
@@ -66,16 +65,18 @@
      * @param name the category name
      */
     void removeInstances(String name) {
-        ArrayList<Instance> toDelete = new ArrayList<Instance>();
-        ArrayList<Instance> instances = mInstances;
-        int count = instances.size();
+        final ArrayList<Instance> toDelete = new ArrayList<Instance>();
+        final ArrayList<Instance> instances = mInstances;
+        final int count = instances.size();
+
         for (int i = 0; i < count; i++) {
-            Instance instance = instances.get(i);
-            if (instance.label.equals(name)) {
+            final Instance instance = instances.get(i);
+            // the label can be null, as specified in Instance
+            if ((instance.label == null && name == null) || instance.label.equals(name)) {
                 toDelete.add(instance);
             }
         }
-        mInstances.removeAll(toDelete);
+        instances.removeAll(toDelete);
     }
 
     abstract ArrayList<Prediction> classify(GestureLibrary library, Instance instance);
diff --git a/tests/sketch/src/com/android/gesture/LetterRecognizer.java b/tests/sketch/src/com/android/gesture/LetterRecognizer.java
index 1c15c7d..73151de5 100644
--- a/tests/sketch/src/com/android/gesture/LetterRecognizer.java
+++ b/tests/sketch/src/com/android/gesture/LetterRecognizer.java
@@ -20,45 +20,44 @@
 import android.content.res.Resources;
 import android.util.Log;
 
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.IOException;
+import java.io.DataInputStream;
+import java.io.BufferedInputStream;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 
 public class LetterRecognizer {
+    private static final String LOG_TAG = "LetterRecognizer";
 
-    private static final String LOGTAG = "LetterRecognizer";
-
-    public final static int LATTIN_LOWERCASE = 0;
+    public final static int LATIN_LOWERCASE = 0;
 
     private SigmoidUnit[] mHiddenLayer;
-
     private SigmoidUnit[] mOutputLayer;
 
     private final String[] mClasses;
 
     private final int mInputCount;
 
-    private class SigmoidUnit {
+    private static class SigmoidUnit {
+        final float[] mWeights;
 
-        private float[] mWeights;
-
-        private SigmoidUnit(float[] weights) {
+        SigmoidUnit(float[] weights) {
             mWeights = weights;
         }
 
         private float compute(float[] inputs) {
             float sum = 0;
-            int count = inputs.length;
-            float[] weights = mWeights;
+
+            final int count = inputs.length;
+            final float[] weights = mWeights;
+
             for (int i = 0; i < count; i++) {
                 sum += inputs[i] * weights[i];
             }
             sum += weights[weights.length - 1];
-            return 1 / (float)(1 + Math.exp(-sum));
+
+            return 1.0f / (float) (1 + Math.exp(-sum));
         }
     }
 
@@ -71,33 +70,35 @@
 
     public static LetterRecognizer getLetterRecognizer(Context context, int type) {
         switch (type) {
-            case LATTIN_LOWERCASE: {
-                return createFromResource(context, com.android.internal.R.raw.lattin_lowercase);
+            case LATIN_LOWERCASE: {
+                return createFromResource(context, com.android.internal.R.raw.latin_lowercase);
             }
         }
         return null;
     }
 
     public ArrayList<Prediction> recognize(Gesture gesture) {
-        return this.classify(GestureUtils.spatialSampling(gesture, mInputCount));
+        return classify(GestureUtilities.spatialSampling(gesture, mInputCount));
     }
 
     private ArrayList<Prediction> classify(float[] vector) {
-        float[] intermediateOutput = compute(mHiddenLayer, vector);
-        float[] output = compute(mOutputLayer, intermediateOutput);
-        ArrayList<Prediction> predictions = new ArrayList<Prediction>();
+        final float[] intermediateOutput = compute(mHiddenLayer, vector);
+        final float[] output = compute(mOutputLayer, intermediateOutput);
+        final ArrayList<Prediction> predictions = new ArrayList<Prediction>();
+
         double sum = 0;
-        int count = mClasses.length;
+
+        final String[] classes = mClasses;
+        final int count = classes.length;
+
         for (int i = 0; i < count; i++) {
-            String name = mClasses[i];
             double score = output[i];
             sum += score;
-            predictions.add(new Prediction(name, score));
+            predictions.add(new Prediction(classes[i], score));
         }
 
         for (int i = 0; i < count; i++) {
-            Prediction name = predictions.get(i);
-            name.score /= sum;
+            predictions.get(i).score /= sum;
         }
 
         Collections.sort(predictions, new Comparator<Prediction>() {
@@ -117,82 +118,63 @@
     }
 
     private float[] compute(SigmoidUnit[] layer, float[] input) {
-        float[] output = new float[layer.length];
-        int count = layer.length;
+        final float[] output = new float[layer.length];
+        final int count = layer.length;
+
         for (int i = 0; i < count; i++) {
             output[i] = layer[i].compute(input);
         }
+
         return output;
     }
 
     private static LetterRecognizer createFromResource(Context context, int resourceID) {
-        Resources resources = context.getResources();
-        InputStream stream = resources.openRawResource(resourceID);
+        final Resources resources = context.getResources();
+
+        DataInputStream in = null;
+        LetterRecognizer classifier = null;
+
         try {
-            BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+            in = new DataInputStream(new BufferedInputStream(resources.openRawResource(resourceID)));
 
-            String line = reader.readLine();
-            int startIndex = 0;
-            int endIndex = -1;
-            endIndex = line.indexOf(" ", startIndex);
-            int iCount = Integer.parseInt(line.substring(startIndex, endIndex));
+            final int iCount = in.readInt();
+            final int hCount = in.readInt();
+            final int oCount = in.readInt();
 
-            startIndex = endIndex + 1;
-            endIndex = line.indexOf(" ", startIndex);
-            int hCount = Integer.parseInt(line.substring(startIndex, endIndex));
-
-            startIndex = endIndex + 1;
-            endIndex = line.length();
-            int oCount = Integer.parseInt(line.substring(startIndex, endIndex));
-
-            String[] classes = new String[oCount];
-            line = reader.readLine();
-            startIndex = 0;
-            endIndex = -1;
-            for (int i = 0; i < oCount; i++) {
-                endIndex = line.indexOf(" ", startIndex);
-                classes[i] = line.substring(startIndex, endIndex);
-                startIndex = endIndex + 1;
+            final String[] classes = new String[oCount];
+            for (int i = 0; i < classes.length; i++) {
+                classes[i] = in.readUTF();
             }
 
-            LetterRecognizer classifier = new LetterRecognizer(iCount, hCount, classes);
+            classifier = new LetterRecognizer(iCount, hCount, classes);
             SigmoidUnit[] hiddenLayer = new SigmoidUnit[hCount];
             SigmoidUnit[] outputLayer = new SigmoidUnit[oCount];
 
             for (int i = 0; i < hCount; i++) {
                 float[] weights = new float[iCount];
-                line = reader.readLine();
-                startIndex = 0;
                 for (int j = 0; j < iCount; j++) {
-                    endIndex = line.indexOf(" ", startIndex);
-                    weights[j] = Float.parseFloat(line.substring(startIndex, endIndex));
-                    startIndex = endIndex + 1;
+                    weights[j] = in.readFloat();
                 }
-                hiddenLayer[i] = classifier.new SigmoidUnit(weights);
+                hiddenLayer[i] = new SigmoidUnit(weights);
             }
 
             for (int i = 0; i < oCount; i++) {
                 float[] weights = new float[hCount];
-                line = reader.readLine();
-                startIndex = 0;
                 for (int j = 0; j < hCount; j++) {
-                    endIndex = line.indexOf(" ", startIndex);
-                    weights[j] = Float.parseFloat(line.substring(startIndex, endIndex));
-                    startIndex = endIndex + 1;
+                    weights[j] = in.readFloat();
                 }
-                outputLayer[i] = classifier.new SigmoidUnit(weights);
+                outputLayer[i] = new SigmoidUnit(weights);
             }
 
-            reader.close();
-
             classifier.mHiddenLayer = hiddenLayer;
             classifier.mOutputLayer = outputLayer;
 
-            return classifier;
-
-        } catch (IOException ex) {
-            Log.d(LOGTAG, "Failed to save gestures:", ex);
+        } catch (IOException e) {
+            Log.d(LOG_TAG, "Failed to load gestures:", e);
+        } finally {
+            GestureUtilities.closeStream(in);
         }
-        return null;
+
+        return classifier;
     }
 }
diff --git a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java b/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java
index 90c3969..a07d125 100644
--- a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java
+++ b/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java
@@ -23,7 +23,6 @@
  * An oriented bounding box
  */
 public class OrientedBoundingBox {
-
     public final float squareness;
 
     public final float width;
diff --git a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java b/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
index 0ffc370..7fc7e28 100644
--- a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
+++ b/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
@@ -30,15 +30,11 @@
  */
 
 public class TouchThroughGesturing implements GestureListener {
-
     public static final int SINGLE_STROKE = 0;
-
     public static final int MULTIPLE_STROKE = 1;
 
     private static final float STROKE_LENGTH_THRESHOLD = 30;
-
     private static final float SQUARENESS_THRESHOLD = 0.275f;
-    
     private static final float ANGLE_THRESHOLD = 40;
 
     public static final int DEFAULT_UNCERTAIN_GESTURE_COLOR = Color.argb(60, 255, 255, 0);
@@ -47,15 +43,18 @@
 
     private float mTotalLength;
 
-    private float mX, mY;
+    private float mX;
+    private float mY;
 
+    // TODO: Use WeakReference?
     private View mModel;
 
     private int mGestureType = SINGLE_STROKE;
-    
     private int mUncertainGestureColor = DEFAULT_UNCERTAIN_GESTURE_COLOR;
 
-    private ArrayList<GestureActionListener> mActionListeners = new ArrayList<GestureActionListener>();
+    // TODO: Use WeakReferences
+    private final ArrayList<GestureActionListener> mActionListeners =
+            new ArrayList<GestureActionListener>();
 
     public TouchThroughGesturing(View model) {
         mModel = model;
@@ -77,14 +76,17 @@
         if (mGestureType == MULTIPLE_STROKE) {
             overlay.cancelFadingOut();
         }
+
         mX = event.getX();
         mY = event.getY();
         mTotalLength = 0;
         mIsGesturing = false;
+
         if (mGestureType == SINGLE_STROKE || overlay.getCurrentGesture() == null
                 || overlay.getCurrentGesture().getStrokesCount() == 0) {
             overlay.setGestureColor(mUncertainGestureColor);
         }
+
         mModel.dispatchTouchEvent(event);
     }
 
@@ -92,40 +94,45 @@
         if (mIsGesturing) {
             return;
         }
-        float x = event.getX();
-        float y = event.getY();
-        float dx = x - mX;
-        float dy = y - mY;
+
+        final float x = event.getX();
+        final float y = event.getY();
+        final float dx = x - mX;
+        final float dy = y - mY;
+
         mTotalLength += (float)Math.sqrt(dx * dx + dy * dy);
         mX = x;
         mY = y;
 
         if (mTotalLength > STROKE_LENGTH_THRESHOLD) {
-            OrientedBoundingBox bbx = GestureUtils.computeOrientedBBX(overlay.getCurrentStroke());
-            float angle = Math.abs(bbx.orientation);
+            final OrientedBoundingBox box =
+                    GestureUtilities.computeOrientedBoundingBox(overlay.getCurrentStroke());
+            float angle = Math.abs(box.orientation);
             if (angle > 90) {
                 angle = 180 - angle;
             }
-            if (bbx.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) {
+            if (box.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) {
                 mIsGesturing = true;
                 overlay.setGestureColor(GestureOverlay.DEFAULT_GESTURE_COLOR);
                 event = MotionEvent.obtain(event.getDownTime(), System.currentTimeMillis(),
-                        MotionEvent.ACTION_UP, x, y, event.getPressure(), event.getSize(), event
-                                .getMetaState(), event.getXPrecision(), event.getYPrecision(),
+                        MotionEvent.ACTION_UP, x, y, event.getPressure(), event.getSize(),
+                        event.getMetaState(), event.getXPrecision(), event.getYPrecision(),
                         event.getDeviceId(), event.getEdgeFlags());
             }
         }
+
         mModel.dispatchTouchEvent(event);
     }
 
     public void onFinishGesture(GestureOverlay overlay, MotionEvent event) {
         if (mIsGesturing) {
             overlay.clear(true);
-            ArrayList<GestureActionListener> listeners = mActionListeners;
-            int count = listeners.size();
+
+            final ArrayList<GestureActionListener> listeners = mActionListeners;
+            final int count = listeners.size();
+
             for (int i = 0; i < count; i++) {
-                GestureActionListener listener = listeners.get(i);
-                listener.onGesturePerformed(overlay, overlay.getCurrentGesture());
+                listeners.get(i).onGesturePerformed(overlay, overlay.getCurrentGesture());
             }
         } else {
             mModel.dispatchTouchEvent(event);
diff --git a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
index 1d3fdf3..fc26757 100644
--- a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
+++ b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
@@ -69,7 +69,7 @@
         setProgressBarIndeterminateVisibility(true);
 
         // create a letter recognizer
-        mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.LATTIN_LOWERCASE);
+        mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.LATIN_LOWERCASE);
 
         // load the contact list
         mContactList = (ListView) findViewById(R.id.list);
diff --git a/tests/sketch/tools/Converter.java b/tests/sketch/tools/Converter.java
new file mode 100644
index 0000000..b4654f8
--- /dev/null
+++ b/tests/sketch/tools/Converter.java
@@ -0,0 +1,222 @@
+import java.io.File;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.Closeable;
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+
+/**
+ * Converts text-based letter stores to binary-based stores.
+ */
+public class Converter {
+    private final File mFile;
+
+    Converter(File file) {
+        mFile = file;
+    }
+
+    private void convert() {
+        boolean read = false;
+
+        String[] classes = null;
+        int iCount = 0;
+        int hCount = 0;
+        int oCount = 0;
+        float[][] iWeights = null;
+        float[][] oWeights = null;
+        
+        BufferedReader reader = null;
+
+        try {
+            reader = new BufferedReader(new FileReader(mFile));
+
+            long start = System.nanoTime();
+
+            String line = reader.readLine();
+            int startIndex = 0;
+            int endIndex;
+            endIndex = line.indexOf(" ", startIndex);
+            iCount = Integer.parseInt(line.substring(startIndex, endIndex));
+
+            startIndex = endIndex + 1;
+            endIndex = line.indexOf(" ", startIndex);
+            hCount = Integer.parseInt(line.substring(startIndex, endIndex));
+
+            startIndex = endIndex + 1;
+            endIndex = line.length();
+            oCount = Integer.parseInt(line.substring(startIndex, endIndex));
+
+            classes = new String[oCount];
+            line = reader.readLine();
+            startIndex = 0;
+
+            for (int i = 0; i < oCount; i++) {
+                endIndex = line.indexOf(" ", startIndex);
+                classes[i] = line.substring(startIndex, endIndex);
+                startIndex = endIndex + 1;
+            }
+
+            iWeights = new float[hCount][];
+            for (int i = 0; i < hCount; i++) {
+                iWeights[i] = new float[iCount];
+                line = reader.readLine();
+                startIndex = 0;
+                for (int j = 0; j < iCount; j++) {
+                    endIndex = line.indexOf(" ", startIndex);
+                    iWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex));
+                    startIndex = endIndex + 1;
+                }
+            }
+
+            oWeights = new float[oCount][];
+            for (int i = 0; i < oCount; i++) {
+                oWeights[i] = new float[hCount];
+                line = reader.readLine();
+                startIndex = 0;
+                for (int j = 0; j < hCount; j++) {
+                    endIndex = line.indexOf(" ", startIndex);
+                    oWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex));
+                    startIndex = endIndex + 1;
+                }
+            }
+
+            long end = System.nanoTime();
+            System.out.println("time to read text file = " +
+                    ((end - start) / 1000.0f / 1000.0f) + " ms");
+
+            read = true;
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            close(reader);
+        }
+
+        if (read) {
+            boolean wrote = false;
+            DataOutputStream out = null;
+
+            try {
+                out = new DataOutputStream(new FileOutputStream(mFile));
+
+                out.writeInt(iCount);
+                out.writeInt(hCount);
+                out.writeInt(oCount);
+
+                for (String aClass : classes) {
+                    out.writeUTF(aClass);
+                }
+
+                for (float[] weights : iWeights) {
+                    for (float weight : weights) {
+                        out.writeFloat(weight);
+                    }
+                }
+
+                for (float[] weights : oWeights) {
+                    for (float weight : weights) {
+                        out.writeFloat(weight);
+                    }
+                }
+
+                out.flush();
+
+                wrote = true;
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            } finally {
+                close(out);
+            }
+
+            if (wrote) {
+                DataInputStream in = null;
+
+                try {
+                    in = new DataInputStream(new BufferedInputStream(new FileInputStream(mFile)));
+
+                    long start = System.nanoTime();
+
+                    iCount = in.readInt();
+                    hCount = in.readInt();
+                    oCount = in.readInt();
+
+                    classes = new String[oCount];
+                    for (int i = 0; i < classes.length; i++) {
+                        classes[i] = in.readUTF();
+                    }
+
+                    iWeights = new float[hCount][];
+                    for (int i = 0; i < iWeights.length; i++) {
+                        iWeights[i] = new float[iCount];
+                        for (int j = 0; j < iCount; j++) {
+                            iWeights[i][j] = in.readFloat();
+                        }
+                    }
+
+                    oWeights = new float[oCount][];
+                    for (int i = 0; i < oWeights.length; i++) {
+                        oWeights[i] = new float[hCount];
+                        for (int j = 0; j < hCount; j++) {
+                            oWeights[i][j] = in.readFloat();
+                        }
+                    }
+
+                    long end = System.nanoTime();
+                    System.out.println("time to read binary file = " +
+                            ((end - start) / 1000.0f / 1000.0f) + " ms");
+
+                } catch (FileNotFoundException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                } finally {
+                    close(in);
+                }
+            }
+        }
+    }
+
+    private static void close(Closeable reader) {
+        if (reader != null) {
+            try {
+                reader.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        String fileName = args[0];
+        if (fileName != null) {
+            File file = new File(fileName);
+            if (!file.exists()) {
+                printHelp(fileName);
+            } else {
+                new Converter(file).convert();
+            }
+        } else {
+            printHelp(null);
+        }
+    }
+
+    private static void printHelp(String name) {
+        if (name == null) {
+            System.out.println("You must specify the name of the file to convert:");
+        } else {
+            System.out.println("The specified file does not exist: " + name);
+        }
+        System.out.println("java Converter [filename]");
+        System.out.println("");
+        System.out.println("\t[filename]\tPath to the file to convert. The file is replaced by "
+                + "the conversion result.");
+    }
+}
\ No newline at end of file