Merge "Corrected debug message in WindowManager"
diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java
index 79178f4..6539156 100644
--- a/core/java/android/database/Cursor.java
+++ b/core/java/android/database/Cursor.java
@@ -25,6 +25,9 @@
 /**
  * This interface provides random read-write access to the result set returned
  * by a database query.
+ *
+ * Cursor implementations are not required to be synchronized so code using a Cursor from multiple
+ * threads should perform its own synchronization when using the Cursor.
  */
 public interface Cursor {
     /**
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 70b9b83..1c1dacd 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -36,6 +36,9 @@
 /**
  * A Cursor implementation that exposes results from a query on a
  * {@link SQLiteDatabase}.
+ *
+ * SQLiteCursor is not internally synchronized so code using a SQLiteCursor from multiple
+ * threads should perform its own synchronization when using the SQLiteCursor.
  */
 public class SQLiteCursor extends AbstractWindowedCursor {
     static final String TAG = "Cursor";
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 9ebf5d9..342c0f5 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1019,7 +1019,8 @@
      *
      * @param sql The raw SQL statement, may contain ? for unknown values to be
      *            bound later.
-     * @return a pre-compiled statement object.
+     * @return A pre-compiled {@link SQLiteStatement} object. Note that
+     * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
      */
     public SQLiteStatement compileStatement(String sql) throws SQLException {
         lock();
@@ -1057,7 +1058,8 @@
      *            default sort order, which may be unordered.
      * @param limit Limits the number of rows returned by the query,
      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
-     * @return A Cursor object, which is positioned before the first entry
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
      * @see Cursor
      */
     public Cursor query(boolean distinct, String table, String[] columns,
@@ -1095,7 +1097,8 @@
      *            default sort order, which may be unordered.
      * @param limit Limits the number of rows returned by the query,
      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
-     * @return A Cursor object, which is positioned before the first entry
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
      * @see Cursor
      */
     public Cursor queryWithFactory(CursorFactory cursorFactory,
@@ -1133,7 +1136,8 @@
      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
      *            (excluding the ORDER BY itself). Passing null will use the
      *            default sort order, which may be unordered.
-     * @return A {@link Cursor} object, which is positioned before the first entry
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
      * @see Cursor
      */
     public Cursor query(String table, String[] columns, String selection,
@@ -1170,7 +1174,8 @@
      *            default sort order, which may be unordered.
      * @param limit Limits the number of rows returned by the query,
      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
-     * @return A {@link Cursor} object, which is positioned before the first entry
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
      * @see Cursor
      */
     public Cursor query(String table, String[] columns, String selection,
@@ -1188,7 +1193,8 @@
      * @param selectionArgs You may include ?s in where clause in the query,
      *     which will be replaced by the values from selectionArgs. The
      *     values will be bound as Strings.
-     * @return A {@link Cursor} object, which is positioned before the first entry
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
      */
     public Cursor rawQuery(String sql, String[] selectionArgs) {
         return rawQueryWithFactory(null, sql, selectionArgs, null);
@@ -1203,7 +1209,8 @@
      *     which will be replaced by the values from selectionArgs. The
      *     values will be bound as Strings.
      * @param editTable the name of the first table, which is editable
-     * @return A {@link Cursor} object, which is positioned before the first entry
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
      */
     public Cursor rawQueryWithFactory(
             CursorFactory cursorFactory, String sql, String[] selectionArgs,
@@ -1255,7 +1262,8 @@
      *     values will be bound as Strings.
      * @param initialRead set the initial count of items to read from the cursor
      * @param maxRead set the count of items to read on each iteration after the first
-     * @return A {@link Cursor} object, which is positioned before the first entry
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
      *
      * This work is incomplete and not fully tested or reviewed, so currently
      * hidden.
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index 9e85452..d6aa9e6 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -20,6 +20,9 @@
 
 /**
  * A base class for compiled SQLite programs.
+ *
+ * SQLiteProgram is not internally synchronized so code using a SQLiteProgram from multiple
+ * threads should perform its own synchronization when using the SQLiteProgram.
  */
 public abstract class SQLiteProgram extends SQLiteClosable {
     private static final String TAG = "SQLiteProgram";
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index cdd9f86..66f7e6d 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -23,6 +23,9 @@
 /**
  * A SQLite program that represents a query that reads the resulting rows into a CursorWindow.
  * This class is used by SQLiteCursor and isn't useful itself.
+ *
+ * SQLiteQuery is not internally synchronized so code using a SQLiteQuery from multiple
+ * threads should perform its own synchronization when using the SQLiteQuery.
  */
 public class SQLiteQuery extends SQLiteProgram {
     private static final String TAG = "Cursor";
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index 5889ad9..46eae65 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -24,6 +24,9 @@
  * The statement cannot return multiple rows, but 1x1 result sets are allowed.
  * Don't use SQLiteStatement constructor directly, please use
  * {@link SQLiteDatabase#compileStatement(String)}
+ *
+ * SQLiteStatement is not internally synchronized so code using a SQLiteStatement from multiple
+ * threads should perform its own synchronization when using the SQLiteStatement.
  */
 public class SQLiteStatement extends SQLiteProgram
 {
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 9a8ee02..b976378 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -190,7 +190,7 @@
             final long oldestTime = pastTime[oldestTouch];
             float accumX = 0;
             float accumY = 0;
-            float N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1;
+            int N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1;
             // Skip the last received event, since it is probably pretty noisy.
             if (N > 3) N--;
 
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 1aa1c76..3f08676 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -689,7 +689,8 @@
             return "";
         }
 
-        if ((bytes[offset] & 0xff) == TOA_International) {
+        //Only TON field should be taken in concideration
+        if ((bytes[offset] & 0xf0) == (TOA_International & 0xf0)) {
             prependPlus = true;
         }
 
diff --git a/telephony/java/com/android/internal/telephony/UUSInfo.java b/telephony/java/com/android/internal/telephony/UUSInfo.java
index 30f7c82..801b845 100644
--- a/telephony/java/com/android/internal/telephony/UUSInfo.java
+++ b/telephony/java/com/android/internal/telephony/UUSInfo.java
@@ -1,29 +1,17 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/*
+ * Copyright (C) 2010 The Android Open Source Project
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of Code Aurora nor
- *       the names of its contributors may be used to endorse or promote
- *       products derived from this software without specific prior written
- *       permission.
+ * 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
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *      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.internal.telephony;
diff --git a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
index 20ea4d7..e14240f 100644
--- a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -82,6 +82,16 @@
         assertEquals("17005550020",
             PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
 
+        b[0] = (byte) 0x80; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
+        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
+        assertEquals("17005550020",
+            PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
+
+        b[0] = (byte) 0x90; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
+        b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
+        assertEquals("+17005550020",
+            PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
+
         b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
         b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
         assertEquals("+17005550020",
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VelocityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VelocityTest.java
new file mode 100644
index 0000000..fb28e1e
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VelocityTest.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2010 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.frameworktest.view;
+
+import junit.framework.Assert;
+
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+
+/**
+ * Exercises {@link android.view.VelocityTracker} to compute correct velocity.<br>
+ * To launch this test, use :<br>
+ * <code>./development/testrunner/runtest.py framework -c com.android.frameworktest.view.VelocityTest</code>
+ */
+public class VelocityTest extends InstrumentationTestCase {
+
+    @MediumTest
+    public void testInitialCondiditions() {
+        VelocityTracker vt = VelocityTracker.obtain();
+        assertNotNull(vt);
+        vt.recycle();
+    }
+
+    /**
+     * Test that {@link android.view.VelocityTracker}.clear() clears
+     * the previous values after a call to computeCurrentVelocity()
+     */
+    @MediumTest
+    public void testClear() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 300);
+        vt.computeCurrentVelocity(1);
+        assertFalse("Velocity should not be null", vt.getXVelocity() == 0.0f);
+        assertFalse("Velocity should not be null", vt.getYVelocity() == 0.0f);
+        vt.clear();
+        vt.computeCurrentVelocity(1);
+        assertEquals(0.0f, vt.getXVelocity());
+        assertEquals(0.0f, vt.getYVelocity());
+        vt.recycle();
+    }
+
+    @MediumTest
+    public void testDragAcceleration () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 15, t, 400, new AccelerateInterpolator());
+        vt.computeCurrentVelocity(1000);
+        assertGreater(250.0f, vt.getXVelocity());
+        assertGreater(250.0f, vt.getYVelocity());
+        vt.recycle();
+    }
+
+    @MediumTest
+    public void testDragDeceleration () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 15, t, 400, new DecelerateInterpolator());
+        vt.computeCurrentVelocity(1000);
+        assertLower(250.0f, vt.getXVelocity());
+        assertLower(250.0f, vt.getYVelocity());
+        vt.recycle();
+    }
+
+    @MediumTest
+    public void testDragLinearHorizontal() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        // 100px in 400ms => 250px/s
+        drag(vt, 100, 200, 200, 200, 15, t, 400);
+        vt.computeCurrentVelocity(1000);
+        assertEquals(0.0f, vt.getYVelocity());
+        assertEqualFuzzy(250.0f, vt.getXVelocity(), 4f);
+        vt.recycle();
+    }
+
+    @MediumTest
+    public void testDragLinearVertical() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        // 100px in 400ms => 250px/s
+        drag(vt, 200, 200, 100, 200, 15, t, 400);
+        vt.computeCurrentVelocity(1000);
+        assertEquals(0.0f, vt.getXVelocity());
+        assertEqualFuzzy(250.0f, vt.getYVelocity(), 4f);
+        vt.recycle();
+    }
+
+    /**
+     * Test dragging with two points only
+     * (velocity must be an exact value)
+     */
+    @MediumTest
+    public void testDragWith2Points () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        // 100px, 2 steps, 100ms => 1000px/s
+        drag(vt, 100, 200, 100, 200, 2, t, 100);
+        vt.computeCurrentVelocity(1000);
+        assertEquals(1000.0f, vt.getXVelocity());
+        assertEquals(1000.0f, vt.getYVelocity());
+        vt.recycle();
+    }
+
+    /**
+     * Velocity is independent of the number of points used during
+     * the same interval
+     */
+    @MediumTest
+    public void testStabilityInNbPoints () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 400); // 10 steps over 400ms
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.clear();
+        drag(vt, 100, 200, 100, 200, 20, t, 400); // 20 steps over 400ms
+        vt.computeCurrentVelocity(1);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEqualFuzzy(firstX, secondX, 0.1f);
+        assertEqualFuzzy(firstY, secondY, 0.1f);
+        vt.recycle();
+    }
+
+    /**
+     * Velocity is independent of the time when the events occurs,
+     * it only depends on delays between the events.
+     */
+    @MediumTest
+    public void testStabilityInTime () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 400);
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.clear();
+        drag(vt, 100, 200, 100, 200, 10, t + 3600*1000, 400); // on hour later
+        vt.computeCurrentVelocity(1);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEqualFuzzy(firstX, secondX, 0.1f);
+        assertEqualFuzzy(firstY, secondY, 0.1f);
+        vt.recycle();
+    }
+
+    /**
+     * Velocity is independent of the position of the events,
+     * it only depends on their relative distance.
+     */
+    @MediumTest
+    public void testStabilityInSpace () {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 400);
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.clear();
+        drag(vt, 200, 300, 200, 300, 10, t, 400); // 100px further
+        vt.computeCurrentVelocity(1);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEqualFuzzy(firstX, secondX, 0.1f);
+        assertEqualFuzzy(firstY, secondY, 0.1f);
+        vt.recycle();
+    }
+
+    /**
+     * Test that calls to {@link android.view.VelocityTracker}.computeCurrentVelocity()
+     * will output same values when using the same data.
+     */
+    @MediumTest
+    public void testStabilityOfComputation() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 300);
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.computeCurrentVelocity(1);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEquals(firstX, secondX);
+        assertEquals(firstY, secondY);
+        vt.recycle();
+    }
+
+    /**
+     * Test the units parameter of {@link android.view.VelocityTracker}.computeCurrentVelocity()
+     */
+    @MediumTest
+    public void testStabilityOfUnits() {
+        long t = System.currentTimeMillis();
+        VelocityTracker vt = VelocityTracker.obtain();
+        drag(vt, 100, 200, 100, 200, 10, t, 300);
+        vt.computeCurrentVelocity(1);
+        float firstX = vt.getXVelocity();
+        float firstY = vt.getYVelocity();
+        vt.computeCurrentVelocity(1000);
+        float secondX = vt.getXVelocity();
+        float secondY = vt.getYVelocity();
+        assertEqualFuzzy(firstX, secondX / 1000.0f, 0.1f);
+        assertEqualFuzzy(firstY, secondY / 1000.0f, 0.1f);
+        vt.recycle();
+    }
+
+    /**
+     * Simulate a drag by giving directly MotionEvents to
+     * the VelocityTracker using a linear interpolator
+     */
+    private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps,
+            long startime, int duration) {
+        drag(vt, startX, endX, startY, endY, steps, startime, duration, new LinearInterpolator());
+    }
+
+    /**
+     * Simulate a drag by giving directly MotionEvents to
+     * the VelocityTracker using a given interpolator
+     */
+    private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps,
+            long startime, int duration, Interpolator interpolator) {
+        addMotionEvent(vt, startX, startY, startime, MotionEvent.ACTION_DOWN);
+        float dt = duration / (float)steps;
+        int distX = endX - startX;
+        int distY = endY - startY;
+        for (int i=1; i<steps-1; i++) {
+            float ii = interpolator.getInterpolation(i / (float)steps);
+            int x = (int) (startX + distX * ii);
+            int y = (int) (startY + distY * ii);
+            long time = startime + (int) (i * dt);
+            addMotionEvent(vt, x, y, time, MotionEvent.ACTION_MOVE);
+        }
+        addMotionEvent(vt, endX, endY, startime + duration, MotionEvent.ACTION_UP);
+    }
+
+    private void addMotionEvent(VelocityTracker vt, int x, int y, long time, int action) {
+        MotionEvent me = MotionEvent.obtain(time, time, action, x, y, 0);
+        vt.addMovement(me);
+        me.recycle();
+    }
+
+    /**
+     * Float imprecision of the average computations and filtering
+     * (removing last MotionEvent for N > 3) implies that tests
+     *  accepts some approximated values.
+     */
+    private void assertEqualFuzzy(float expected, float actual, float threshold) {
+        boolean fuzzyEqual = actual >= expected - threshold && actual <= expected + threshold;
+        Assert.assertTrue("Expected: <"+expected+"> but was: <"+actual+
+                "> while accepting a variation of: <"+threshold+">", fuzzyEqual);
+    }
+
+    private void assertGreater(float minExpected, float actual) {
+        Assert.assertTrue("Expected: minimum <"+minExpected+"> but was: <"+actual+">",
+                actual > minExpected);
+    }
+
+    private void assertLower(float maxExpected, float actual) {
+        Assert.assertTrue("Expected: maximum <"+maxExpected+"> but was: <"+actual+">",
+                actual < maxExpected);
+    }
+}