Merge "Fix 3298264: Update LockScreen DigitalClock with new font"
diff --git a/api/11.xml b/api/11.xml
index 5fd9c8c..43bb440 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -165317,7 +165317,7 @@
 <package name="android.text.method"
 >
 <class name="ArrowKeyMovementMethod"
- extends="java.lang.Object"
+ extends="android.text.method.BaseMovementMethod"
  abstract="false"
  static="false"
  final="false"
@@ -166987,7 +166987,7 @@
 </method>
 </class>
 <class name="ScrollingMovementMethod"
- extends="java.lang.Object"
+ extends="android.text.method.BaseMovementMethod"
  abstract="false"
  static="false"
  final="false"
diff --git a/api/current.xml b/api/current.xml
index 9ab1dd0..35daa43c 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -26765,6 +26765,21 @@
 <parameter name="day" type="int">
 </parameter>
 </method>
+<method name="setRange"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startYear" type="int">
+</parameter>
+<parameter name="endYear" type="int">
+</parameter>
+</method>
 <method name="updateDate"
  return="void"
  abstract="false"
@@ -30028,6 +30043,19 @@
 <parameter name="args" type="java.lang.String[]">
 </parameter>
 </method>
+<method name="enableDebugLogging"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="enabled" type="boolean">
+</parameter>
+</method>
 <method name="executePendingTransactions"
  return="boolean"
  abstract="true"
@@ -32314,6 +32342,19 @@
 <parameter name="args" type="java.lang.String[]">
 </parameter>
 </method>
+<method name="enableDebugLogging"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="enabled" type="boolean">
+</parameter>
+</method>
 <method name="getLoader"
  return="android.content.Loader&lt;D&gt;"
  abstract="true"
@@ -42885,17 +42926,6 @@
  visibility="public"
 >
 </method>
-<method name="forceLoad"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="loadInBackground"
  return="D"
  abstract="true"
@@ -49578,28 +49608,6 @@
 <parameter name="uri" type="android.net.Uri">
 </parameter>
 </method>
-<method name="startLoading"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="stopLoading"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 </class>
 <interface name="DialogInterface"
  abstract="true"
@@ -54694,7 +54702,7 @@
 </class>
 <class name="Loader"
  extends="java.lang.Object"
- abstract="true"
+ abstract="false"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -54710,6 +54718,19 @@
 <parameter name="context" type="android.content.Context">
 </parameter>
 </constructor>
+<method name="dataToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="D">
+</parameter>
+</method>
 <method name="deliverResult"
  return="void"
  abstract="false"
@@ -54723,24 +54744,32 @@
 <parameter name="data" type="D">
 </parameter>
 </method>
-<method name="destroy"
+<method name="dump"
  return="void"
  abstract="false"
  native="false"
  synchronized="false"
  static="false"
  final="false"
- deprecated="deprecated"
+ deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="prefix" type="java.lang.String">
+</parameter>
+<parameter name="fd" type="java.io.FileDescriptor">
+</parameter>
+<parameter name="writer" type="java.io.PrintWriter">
+</parameter>
+<parameter name="args" type="java.lang.String[]">
+</parameter>
 </method>
 <method name="forceLoad"
  return="void"
- abstract="true"
+ abstract="false"
  native="false"
  synchronized="false"
  static="false"
- final="false"
+ final="true"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -54767,6 +54796,28 @@
  visibility="public"
 >
 </method>
+<method name="isReset"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isStarted"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onContentChanged"
  return="void"
  abstract="false"
@@ -54778,6 +54829,50 @@
  visibility="public"
 >
 </method>
+<method name="onForceLoad"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="onReset"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="onStartLoading"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="onStopLoading"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
 <method name="registerListener"
  return="void"
  abstract="false"
@@ -54799,25 +54894,36 @@
  native="false"
  synchronized="false"
  static="false"
- final="false"
+ final="true"
  deprecated="not deprecated"
  visibility="public"
 >
 </method>
 <method name="startLoading"
  return="void"
- abstract="true"
+ abstract="false"
  native="false"
  synchronized="false"
  static="false"
- final="false"
+ final="true"
  deprecated="not deprecated"
  visibility="public"
 >
 </method>
 <method name="stopLoading"
  return="void"
- abstract="true"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="takeContentChanged"
+ return="boolean"
+ abstract="false"
  native="false"
  synchronized="false"
  static="false"
@@ -103907,6 +104013,17 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<field name="AAC"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="AMR_NB"
  type="int"
  transient="false"
@@ -103918,6 +104035,17 @@
  visibility="public"
 >
 </field>
+<field name="AMR_WB"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="DEFAULT"
  type="int"
  transient="false"
@@ -104085,6 +104213,28 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<field name="AMR_NB"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AMR_WB"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="DEFAULT"
  type="int"
  transient="false"
@@ -143200,7 +143350,7 @@
  synchronized="false"
  static="true"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="data" type="byte[]">
@@ -184945,7 +185095,7 @@
 <package name="android.text.method"
 >
 <class name="ArrowKeyMovementMethod"
- extends="java.lang.Object"
+ extends="android.text.method.BaseMovementMethod"
  abstract="false"
  static="false"
  final="false"
@@ -184962,17 +185112,6 @@
  visibility="public"
 >
 </constructor>
-<method name="canSelectArbitrarily"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="getInstance"
  return="android.text.method.MovementMethod"
  abstract="false"
@@ -184984,127 +185123,6 @@
  visibility="public"
 >
 </method>
-<method name="initialize"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="text" type="android.text.Spannable">
-</parameter>
-</method>
-<method name="onKeyDown"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-<parameter name="keyCode" type="int">
-</parameter>
-<parameter name="event" type="android.view.KeyEvent">
-</parameter>
-</method>
-<method name="onKeyOther"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="view" type="android.widget.TextView">
-</parameter>
-<parameter name="text" type="android.text.Spannable">
-</parameter>
-<parameter name="event" type="android.view.KeyEvent">
-</parameter>
-</method>
-<method name="onKeyUp"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-<parameter name="keyCode" type="int">
-</parameter>
-<parameter name="event" type="android.view.KeyEvent">
-</parameter>
-</method>
-<method name="onTakeFocus"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="view" type="android.widget.TextView">
-</parameter>
-<parameter name="text" type="android.text.Spannable">
-</parameter>
-<parameter name="dir" type="int">
-</parameter>
-</method>
-<method name="onTouchEvent"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="onTrackballEvent"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="text" type="android.text.Spannable">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
 </class>
 <class name="BaseKeyListener"
  extends="android.text.method.MetaKeyKeyListener"
@@ -185143,6 +185161,25 @@
 <parameter name="event" type="android.view.KeyEvent">
 </parameter>
 </method>
+<method name="forwardDelete"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.view.View">
+</parameter>
+<parameter name="content" type="android.text.Editable">
+</parameter>
+<parameter name="keyCode" type="int">
+</parameter>
+<parameter name="event" type="android.view.KeyEvent">
+</parameter>
+</method>
 <method name="onKeyOther"
  return="boolean"
  abstract="false"
@@ -185161,6 +185198,373 @@
 </parameter>
 </method>
 </class>
+<class name="BaseMovementMethod"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.text.method.MovementMethod">
+</implements>
+<constructor name="BaseMovementMethod"
+ type="android.text.method.BaseMovementMethod"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="bottom"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="canSelectArbitrarily"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="down"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="end"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="getMovementMetaState"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+<parameter name="event" type="android.view.KeyEvent">
+</parameter>
+</method>
+<method name="handleMovementKey"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+<parameter name="keyCode" type="int">
+</parameter>
+<parameter name="movementMetaState" type="int">
+</parameter>
+<parameter name="event" type="android.view.KeyEvent">
+</parameter>
+</method>
+<method name="home"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="initialize"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="left"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="lineEnd"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="lineStart"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="onKeyDown"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="android.text.Spannable">
+</parameter>
+<parameter name="keyCode" type="int">
+</parameter>
+<parameter name="event" type="android.view.KeyEvent">
+</parameter>
+</method>
+<method name="onKeyOther"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="android.text.Spannable">
+</parameter>
+<parameter name="event" type="android.view.KeyEvent">
+</parameter>
+</method>
+<method name="onKeyUp"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="android.text.Spannable">
+</parameter>
+<parameter name="keyCode" type="int">
+</parameter>
+<parameter name="event" type="android.view.KeyEvent">
+</parameter>
+</method>
+<method name="onTakeFocus"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="android.text.Spannable">
+</parameter>
+<parameter name="direction" type="int">
+</parameter>
+</method>
+<method name="onTouchEvent"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="android.text.Spannable">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+<method name="onTrackballEvent"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="android.text.Spannable">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+<method name="pageDown"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="pageUp"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="right"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="top"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+<method name="up"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="buffer" type="android.text.Spannable">
+</parameter>
+</method>
+</class>
 <class name="CharacterPickerDialog"
  extends="android.app.Dialog"
  abstract="false"
@@ -186626,7 +187030,7 @@
 </method>
 </class>
 <class name="ScrollingMovementMethod"
- extends="java.lang.Object"
+ extends="android.text.method.BaseMovementMethod"
  abstract="false"
  static="false"
  final="false"
@@ -186643,32 +187047,6 @@
  visibility="public"
 >
 </constructor>
-<method name="canSelectArbitrarily"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="down"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="protected"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-</method>
 <method name="getInstance"
  return="android.text.method.MovementMethod"
  abstract="false"
@@ -186680,172 +187058,6 @@
  visibility="public"
 >
 </method>
-<method name="initialize"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="text" type="android.text.Spannable">
-</parameter>
-</method>
-<method name="left"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="protected"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-</method>
-<method name="onKeyDown"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-<parameter name="keyCode" type="int">
-</parameter>
-<parameter name="event" type="android.view.KeyEvent">
-</parameter>
-</method>
-<method name="onKeyOther"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="view" type="android.widget.TextView">
-</parameter>
-<parameter name="text" type="android.text.Spannable">
-</parameter>
-<parameter name="event" type="android.view.KeyEvent">
-</parameter>
-</method>
-<method name="onKeyUp"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-<parameter name="keyCode" type="int">
-</parameter>
-<parameter name="event" type="android.view.KeyEvent">
-</parameter>
-</method>
-<method name="onTakeFocus"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="text" type="android.text.Spannable">
-</parameter>
-<parameter name="dir" type="int">
-</parameter>
-</method>
-<method name="onTouchEvent"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="onTrackballEvent"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="text" type="android.text.Spannable">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="right"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="protected"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-</method>
-<method name="up"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="protected"
->
-<parameter name="widget" type="android.widget.TextView">
-</parameter>
-<parameter name="buffer" type="android.text.Spannable">
-</parameter>
-</method>
 </class>
 <class name="SingleLineTransformationMethod"
  extends="android.text.method.ReplacementTransformationMethod"
@@ -222639,6 +222851,8 @@
 >
 <parameter name="imi" type="android.view.inputmethod.InputMethodInfo">
 </parameter>
+<parameter name="allowsImplicitlySelectedSubtypes" type="boolean">
+</parameter>
 </method>
 <method name="getInputMethodList"
  return="java.util.List&lt;android.view.inputmethod.InputMethodInfo&gt;"
@@ -234963,6 +235177,21 @@
 <parameter name="onDateChangedListener" type="android.widget.DatePicker.OnDateChangedListener">
 </parameter>
 </method>
+<method name="setRange"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startYear" type="int">
+</parameter>
+<parameter name="endYear" type="int">
+</parameter>
+</method>
 <method name="updateDate"
  return="void"
  abstract="false"
@@ -251375,7 +251604,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
 </parameter>
 </method>
 </interface>
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index 448b3ef..e6e55ee 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
-import android.os.Build;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -118,6 +117,28 @@
         mDatePicker.init(year, month, day, null);
     }
 
+    /**
+     * Sets the range of years in which dates can be selected.
+     * <p>
+     * Note: If the range is set to a value that does not include the currently
+     * selected date the value of the picker shown by this dialog will be
+     * updated to the closest date in the range.
+     * </p>
+     *
+     * @param startYear The start year of the range.
+     * @param endYear The end year of the range.
+     */
+    public void setRange(int startYear, int endYear) {
+        mDatePicker.setRange(startYear, endYear);
+    }
+
+    /**
+     * Sets the current date.
+     *
+     * @param year The date year.
+     * @param monthOfYear The date month.
+     * @param dayOfMonth The date day of month.
+     */
     public void updateDate(int year, int monthOfYear, int dayOfMonth) {
         mDatePicker.updateDate(year, monthOfYear, dayOfMonth);
     }
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 348149e..f06f2cf 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -27,6 +27,7 @@
 import android.os.Parcelable;
 import android.util.AndroidRuntimeException;
 import android.util.AttributeSet;
+import android.util.DebugUtils;
 import android.util.SparseArray;
 import android.view.ContextMenu;
 import android.view.LayoutInflater;
@@ -526,17 +527,7 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(128);
-        String simpleName = getClass().getSimpleName();
-        if (simpleName == null || simpleName.isEmpty()) {
-            simpleName = getClass().getName();
-            int end = simpleName.lastIndexOf('.');
-            if (end > 0) {
-                simpleName = simpleName.substring(end+1);
-            }
-        }
-        sb.append(simpleName);
-        sb.append("{");
-        sb.append(Integer.toHexString(System.identityHashCode(this)));
+        DebugUtils.buildShortClassTag(this, sb);
         if (mIndex >= 0) {
             sb.append(" #");
             sb.append(mIndex);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 488b673..fe2ebed 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -26,6 +26,7 @@
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.DebugUtils;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.Menu;
@@ -251,6 +252,15 @@
      * @param args Additional arguments to the dump request.
      */
     public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
+
+    /**
+     * Control whether the framework's internal fragment manager debugging
+     * logs are turned on.  If enabled, you will see output in logcat as
+     * the framework performs fragment operations.
+     */
+    public static void enableDebugLogging(boolean enabled) {
+        FragmentManagerImpl.DEBUG = enabled;
+    }
 }
 
 final class FragmentManagerState implements Parcelable {
@@ -293,7 +303,7 @@
  * Container for fragments associated with an activity.
  */
 final class FragmentManagerImpl extends FragmentManager {
-    static final boolean DEBUG = false;
+    static boolean DEBUG = true;
     static final String TAG = "FragmentManager";
     
     static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
@@ -451,6 +461,17 @@
     }
 
     @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(128);
+        sb.append("FragmentManager{");
+        sb.append(Integer.toHexString(System.identityHashCode(this)));
+        sb.append(" in ");
+        DebugUtils.buildShortClassTag(mActivity, sb);
+        sb.append("}}");
+        return sb.toString();
+    }
+
+    @Override
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
         if (mActive == null || mActive.size() <= 0) {
             return;
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 7125054..5f8c098 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -18,11 +18,13 @@
 
 import android.content.Loader;
 import android.os.Bundle;
+import android.util.DebugUtils;
 import android.util.Log;
 import android.util.SparseArray;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.reflect.Modifier;
 
 /**
  * Interface associated with an {@link Activity} or {@link Fragment} for managing
@@ -122,6 +124,8 @@
      * @param id A unique identifier for this loader.  Can be whatever you want.
      * Identifiers are scoped to a particular LoaderManager instance.
      * @param args Optional arguments to supply to the loader at construction.
+     * If a loader already exists (a new one does not need to be created), this
+     * parameter will be ignored and the last arguments continue to be used.
      * @param callback Interface the LoaderManager will call to report about
      * changes in the state of the loader.  Required.
      */
@@ -177,11 +181,20 @@
      * @param args Additional arguments to the dump request.
      */
     public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
+
+    /**
+     * Control whether the framework's internal loader manager debugging
+     * logs are turned on.  If enabled, you will see output in logcat as
+     * the framework performs loader operations.
+     */
+    public static void enableDebugLogging(boolean enabled) {
+        LoaderManagerImpl.DEBUG = enabled;
+    }
 }
 
 class LoaderManagerImpl extends LoaderManager {
-    static final String TAG = "LoaderManagerImpl";
-    static final boolean DEBUG = true;
+    static final String TAG = "LoaderManager";
+    static boolean DEBUG = true;
 
     // These are the currently active loaders.  A loader is here
     // from the time its load is started until it has been explicitly
@@ -205,8 +218,8 @@
         LoaderManager.LoaderCallbacks<Object> mCallbacks;
         Loader<Object> mLoader;
         Object mData;
+        Object mDeliveredData;
         boolean mStarted;
-        boolean mNeedReset;
         boolean mRetaining;
         boolean mRetainingStarted;
         boolean mDestroyed;
@@ -232,17 +245,24 @@
                 return;
             }
 
+            mStarted = true;
+            
             if (DEBUG) Log.v(TAG, "  Starting: " + this);
             if (mLoader == null && mCallbacks != null) {
                mLoader = mCallbacks.onCreateLoader(mId, mArgs);
             }
             if (mLoader != null) {
+                if (mLoader.getClass().isMemberClass()
+                        && !Modifier.isStatic(mLoader.getClass().getModifiers())) {
+                    throw new IllegalArgumentException(
+                            "Object returned from onCreateLoader must not be a non-static inner member class: "
+                            + mLoader);
+                }
                 if (!mListenerRegistered) {
                     mLoader.registerListener(mId, this);
                     mListenerRegistered = true;
                 }
                 mLoader.startLoading();
-                mStarted = true;
             }
         }
         
@@ -295,7 +315,10 @@
         void destroy() {
             if (DEBUG) Log.v(TAG, "  Destroying: " + this);
             mDestroyed = true;
-            if (mCallbacks != null && mLoader != null && mData != null && mNeedReset) {
+            boolean needReset = mDeliveredData != null;
+            mDeliveredData = null;
+            if (mCallbacks != null && mLoader != null && mData != null && needReset) {
+                if (DEBUG) Log.v(TAG, "  Reseting: " + this);
                 String lastBecause = null;
                 if (mActivity != null) {
                     lastBecause = mActivity.mFragments.mNoTransactionsBecause;
@@ -309,7 +332,6 @@
                     }
                 }
             }
-            mNeedReset = false;
             mCallbacks = null;
             mData = null;
             if (mLoader != null) {
@@ -322,20 +344,23 @@
         }
         
         @Override public void onLoadComplete(Loader<Object> loader, Object data) {
-            if (DEBUG) Log.v(TAG, "onLoadComplete: " + this + " mDestroyed=" + mDestroyed);
+            if (DEBUG) Log.v(TAG, "onLoadComplete: " + this);
 
             if (mDestroyed) {
+                if (DEBUG) Log.v(TAG, "  Ignoring load complete -- destroyed");
                 return;
             }
             
             // Notify of the new data so the app can switch out the old data before
             // we try to destroy it.
-            mData = data;
-            if (mStarted) {
-                callOnLoadFinished(loader, data);
+            if (mData != data) {
+                mData = data;
+                if (mStarted) {
+                    callOnLoadFinished(loader, data);
+                }
             }
 
-            if (DEBUG) Log.v(TAG, "onLoadFinished returned: " + this);
+            //if (DEBUG) Log.v(TAG, "  onLoadFinished returned: " + this);
 
             // We have now given the application the new loader with its
             // loaded data, so it should have stopped using the previous
@@ -343,7 +368,7 @@
             // clean it up.
             LoaderInfo info = mInactiveLoaders.get(mId);
             if (info != null && info != this) {
-                info.mNeedReset = false;
+                info.mDeliveredData = null;
                 info.destroy();
                 mInactiveLoaders.remove(mId);
             }
@@ -357,13 +382,15 @@
                     mActivity.mFragments.mNoTransactionsBecause = "onLoadFinished";
                 }
                 try {
+                    if (DEBUG) Log.v(TAG, "  onLoadFinished in " + loader + ": "
+                            + loader.dataToString(data));
                     mCallbacks.onLoadFinished(loader, data);
                 } finally {
                     if (mActivity != null) {
                         mActivity.mFragments.mNoTransactionsBecause = lastBecause;
                     }
                 }
-                mNeedReset = true;
+                mDeliveredData = data;
             }
         }
         
@@ -374,21 +401,9 @@
             sb.append(Integer.toHexString(System.identityHashCode(this)));
             sb.append(" #");
             sb.append(mId);
-            if (mArgs != null) {
-                sb.append(" ");
-                sb.append(mArgs.toString());
-            }
-            sb.append("}");
-            return sb.toString();
-        }
-
-        public String toBasicString() {
-            StringBuilder sb = new StringBuilder(64);
-            sb.append("LoaderInfo{");
-            sb.append(Integer.toHexString(System.identityHashCode(this)));
-            sb.append(" #");
-            sb.append(mId);
-            sb.append("}");
+            sb.append(" : ");
+            DebugUtils.buildShortClassTag(mLoader, sb);
+            sb.append("}}");
             return sb.toString();
         }
 
@@ -397,12 +412,16 @@
                     writer.print(" mArgs="); writer.println(mArgs);
             writer.print(prefix); writer.print("mCallbacks="); writer.println(mCallbacks);
             writer.print(prefix); writer.print("mLoader="); writer.println(mLoader);
+            if (mLoader != null) {
+                mLoader.dump(prefix + "  ", fd, writer, args);
+            }
             writer.print(prefix); writer.print("mData="); writer.println(mData);
+            writer.print(prefix); writer.print("mDeliveredData="); writer.println(mDeliveredData);
             writer.print(prefix); writer.print("mStarted="); writer.print(mStarted);
                     writer.print(" mRetaining="); writer.print(mRetaining);
                     writer.print(" mDestroyed="); writer.println(mDestroyed);
-            writer.print(prefix); writer.print("mNeedReset="); writer.print(mNeedReset);
-                    writer.print(" mListenerRegistered="); writer.println(mListenerRegistered);
+            writer.print(prefix); writer.print("mListenerRegistered=");
+                    writer.println(mListenerRegistered);
         }
     }
     
@@ -434,12 +453,14 @@
     public <D> Loader<D> initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callback) {
         LoaderInfo info = mLoaders.get(id);
         
-        if (DEBUG) Log.v(TAG, "initLoader in " + this + ": cur=" + info);
+        if (DEBUG) Log.v(TAG, "initLoader in " + this + ": args=" + args);
 
         if (info == null) {
             // Loader doesn't already exist; create.
             info = createLoader(id, args,  (LoaderManager.LoaderCallbacks<Object>)callback);
+            if (DEBUG) Log.v(TAG, "  Created new loader " + info);
         } else {
+            if (DEBUG) Log.v(TAG, "  Re-using existing loader " + info);
             info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback;
         }
         
@@ -454,7 +475,7 @@
     @SuppressWarnings("unchecked")
     public <D> Loader<D> restartLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callback) {
         LoaderInfo info = mLoaders.get(id);
-        if (DEBUG) Log.v(TAG, "restartLoader in " + this + ": cur=" + info);
+        if (DEBUG) Log.v(TAG, "restartLoader in " + this + ": args=" + args);
         if (info != null) {
             LoaderInfo inactive = mInactiveLoaders.get(id);
             if (inactive != null) {
@@ -463,8 +484,8 @@
                     // called from within onLoadComplete, where we haven't
                     // yet destroyed the last inactive loader.  So just do
                     // that now.
-                    if (DEBUG) Log.v(TAG, "  Removing last inactive loader in " + this);
-                    inactive.mNeedReset = false;
+                    if (DEBUG) Log.v(TAG, "  Removing last inactive loader: " + info);
+                    inactive.mDeliveredData = null;
                     inactive.destroy();
                     mInactiveLoaders.put(id, info);
                 } else {
@@ -472,13 +493,13 @@
                     // waiting for!  Now we have three active loaders... let's just
                     // drop the one in the middle, since we are still waiting for
                     // its result but that result is already out of date.
-                    if (DEBUG) Log.v(TAG, "  Removing intermediate loader in " + this);
+                    if (DEBUG) Log.v(TAG, "  Removing intermediate loader: " + info);
                     info.destroy();
                 }
             } else {
                 // Keep track of the previous instance of this loader so we can destroy
                 // it when the new one completes.
-                if (DEBUG) Log.v(TAG, "  Making inactive: " + info);
+                if (DEBUG) Log.v(TAG, "  Making last loader inactive: " + info);
                 mInactiveLoaders.put(id, info);
             }
         }
@@ -488,7 +509,7 @@
     }
     
     public void destroyLoader(int id) {
-        if (DEBUG) Log.v(TAG, "stopLoader in " + this + " of " + id);
+        if (DEBUG) Log.v(TAG, "destroyLoader in " + this + " of " + id);
         int idx = mLoaders.indexOfKey(id);
         if (idx >= 0) {
             LoaderInfo info = mLoaders.valueAt(idx);
@@ -513,7 +534,7 @@
     }
  
     void doStart() {
-        if (DEBUG) Log.v(TAG, "Starting: " + this);
+        if (DEBUG) Log.v(TAG, "Starting in " + this);
         if (mStarted) {
             RuntimeException e = new RuntimeException("here");
             e.fillInStackTrace();
@@ -531,7 +552,7 @@
     }
     
     void doStop() {
-        if (DEBUG) Log.v(TAG, "Stopping: " + this);
+        if (DEBUG) Log.v(TAG, "Stopping in " + this);
         if (!mStarted) {
             RuntimeException e = new RuntimeException("here");
             e.fillInStackTrace();
@@ -546,7 +567,7 @@
     }
     
     void doRetain() {
-        if (DEBUG) Log.v(TAG, "Retaining: " + this);
+        if (DEBUG) Log.v(TAG, "Retaining in " + this);
         if (!mStarted) {
             RuntimeException e = new RuntimeException("here");
             e.fillInStackTrace();
@@ -562,23 +583,25 @@
     }
     
     void finishRetain() {
-        if (DEBUG) Log.v(TAG, "Finished Retaining: " + this);
+        if (mRetaining) {
+            if (DEBUG) Log.v(TAG, "Finished Retaining in " + this);
 
-        mRetaining = false;
-        for (int i = mLoaders.size()-1; i >= 0; i--) {
-            mLoaders.valueAt(i).finishRetain();
+            mRetaining = false;
+            for (int i = mLoaders.size()-1; i >= 0; i--) {
+                mLoaders.valueAt(i).finishRetain();
+            }
         }
     }
     
     void doDestroy() {
         if (!mRetaining) {
-            if (DEBUG) Log.v(TAG, "Destroying Active: " + this);
+            if (DEBUG) Log.v(TAG, "Destroying Active in " + this);
             for (int i = mLoaders.size()-1; i >= 0; i--) {
                 mLoaders.valueAt(i).destroy();
             }
         }
         
-        if (DEBUG) Log.v(TAG, "Destroying Inactive: " + this);
+        if (DEBUG) Log.v(TAG, "Destroying Inactive in " + this);
         for (int i = mInactiveLoaders.size()-1; i >= 0; i--) {
             mInactiveLoaders.valueAt(i).destroy();
         }
@@ -586,6 +609,17 @@
     }
 
     @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(128);
+        sb.append("LoaderManager{");
+        sb.append(Integer.toHexString(System.identityHashCode(this)));
+        sb.append(" in ");
+        DebugUtils.buildShortClassTag(mActivity, sb);
+        sb.append("}}");
+        return sb.toString();
+    }
+
+    @Override
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
         if (mLoaders.size() > 0) {
             writer.print(prefix); writer.println("Active Loaders:");
@@ -593,7 +627,7 @@
             for (int i=0; i < mLoaders.size(); i++) {
                 LoaderInfo li = mLoaders.valueAt(i);
                 writer.print(prefix); writer.print("  #"); writer.print(mLoaders.keyAt(i));
-                        writer.print(": "); writer.println(li.toBasicString());
+                        writer.print(": "); writer.println(li.toString());
                 li.dump(innerPrefix, fd, writer, args);
             }
         }
@@ -603,7 +637,7 @@
             for (int i=0; i < mInactiveLoaders.size(); i++) {
                 LoaderInfo li = mInactiveLoaders.valueAt(i);
                 writer.print(prefix); writer.print("  #"); writer.print(mInactiveLoaders.keyAt(i));
-                        writer.print(": "); writer.println(li.toBasicString());
+                        writer.print(": "); writer.println(li.toString());
                 li.dump(innerPrefix, fd, writer, args);
             }
         }
diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java
index 5da04f1..c958e1b 100644
--- a/core/java/android/app/LocalActivityManager.java
+++ b/core/java/android/app/LocalActivityManager.java
@@ -493,7 +493,7 @@
                 // We need to save the state now, if we don't currently
                 // already have it or the activity is currently resumed.
                 final Bundle childState = new Bundle();
-                r.activity.onSaveInstanceState(childState);
+                r.activity.performSaveInstanceState(childState);
                 r.instanceState = childState;
             }
             if (r.instanceState != null) {
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index f55e96a..7dee25e 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -34,21 +34,31 @@
     private static final String TAG = "BluetoothPan";
     private static final boolean DBG = false;
 
+    //TODO: This needs to inherit from BluetoothProfile like other profiles.
+
     /** int extra for ACTION_PAN_STATE_CHANGED */
-    public static final String EXTRA_PAN_STATE =
-        "android.bluetooth.pan.extra.STATE";
+    public static final String EXTRA_PAN_STATE = "android.bluetooth.pan.extra.STATE";
+
     /** int extra for ACTION_PAN_STATE_CHANGED */
     public static final String EXTRA_PREVIOUS_PAN_STATE =
         "android.bluetooth.pan.extra.PREVIOUS_STATE";
 
-    /** Indicates the state of an PAN device has changed.
+    /** int extra for ACTION_PAN_STATE_CHANGED */
+    public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE";
+
+    public static final int LOCAL_NAP_ROLE = 1;
+    public static final int LOCAL_PANU_ROLE = 2;
+
+    /**
+     * Indicates the state of an PAN device has changed.
      * This intent will always contain EXTRA_DEVICE_STATE,
-     * EXTRA_PREVIOUS_DEVICE_STATE and BluetoothDevice.EXTRA_DEVICE
+     * EXTRA_PREVIOUS_DEVICE_STATE, BluetoothDevice.EXTRA_DEVICE
+     * and EXTRA_LOCAL_ROLE.
      * extras.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PAN_STATE_CHANGED =
-        "android.bluetooth.pan.action.STATE_CHANGED";
+      "android.bluetooth.pan.action.STATE_CHANGED";
 
     public static final String NAP_ROLE = "nap";
     public static final String NAP_BRIDGE = "pan1";
@@ -130,40 +140,42 @@
         }
     }
 
-    /** Get the state of a PAN Device.
-    *
-    * This function returns an int representing the state of the PAN connection
-    *
-    *  @param device Remote BT device.
-    *  @return The current state of the PAN Device
-    *  @hide
-    */
-   public int getPanDeviceState(BluetoothDevice device) {
-       if (DBG) log("getPanDeviceState(" + device + ")");
+    /**
+     * Get the state of a PAN Device.
+     *
+     * This function returns an int representing the state of the PAN connection
+     *
+     *  @param device Remote BT device.
+     *  @return The current state of the PAN Device
+     *  @hide
+     */
+    public int getPanDeviceState(BluetoothDevice device) {
+        if (DBG) log("getPanDeviceState(" + device + ")");
+        try {
+            return mService.getPanDeviceState(device);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+            return STATE_DISCONNECTED;
+        }
+    }
+
+    /**
+     * Returns a set of all the connected PAN Devices
+     *
+     * Does not include devices that are currently connecting or disconnecting
+     *
+     *  @return List of PAN devices or empty on Error
+     * @hide
+     */
+    public List<BluetoothDevice> getConnectedDevices() {
+       if (DBG) log("getConnectedDevices");
        try {
-           return mService.getPanDeviceState(device);
+           return mService.getConnectedPanDevices();
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
-           return STATE_DISCONNECTED;
+           return new ArrayList<BluetoothDevice>();
        }
-   }
-
-   /** Returns a set of all the connected PAN Devices
-   *
-   * Does not include devices that are currently connecting or disconnecting
-   *
-   * @return List of PAN devices or empty on Error
-   * @hide
-   */
-   public List<BluetoothDevice> getConnectedDevices() {
-      if (DBG) log("getConnectedDevices");
-      try {
-          return mService.getConnectedPanDevices();
-      } catch (RemoteException e) {
-          Log.e(TAG, "", e);
-          return new ArrayList<BluetoothDevice>();
-      }
-   }
+    }
 
     private static void log(String msg) {
         Log.d(TAG, msg);
diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
new file mode 100644
index 0000000..7b083f1
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
@@ -0,0 +1,299 @@
+/*
+ * 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 android.bluetooth;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.DhcpInfo;
+import android.net.LinkAddress;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkStateTracker;
+import android.net.NetworkUtils;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * This class tracks the data connection associated with Bluetooth
+ * reverse tethering. This is a singleton class and an instance will be
+ * created by ConnectivityService. BluetoothService will call into this
+ * when a reverse tethered connection needs to be activated.
+ *
+ * @hide
+ */
+public class BluetoothTetheringDataTracker implements NetworkStateTracker {
+    private static final String NETWORKTYPE = "BLUETOOTH_TETHER";
+    private static final String TAG = "BluetoothTethering";
+
+    private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
+    private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
+    private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
+    private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
+
+    private LinkProperties mLinkProperties;
+    private LinkCapabilities mLinkCapabilities;
+    private NetworkInfo mNetworkInfo;
+
+    private BluetoothPan mBluetoothPan;
+    private BluetoothDevice mDevice;
+    private static String mIface;
+
+    /* For sending events to connectivity service handler */
+    private Handler mCsHandler;
+    private Context mContext;
+    public static BluetoothTetheringDataTracker sInstance;
+
+    private BluetoothTetheringDataTracker() {
+        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_BLUETOOTH, 0, NETWORKTYPE, "");
+        mLinkProperties = new LinkProperties();
+        mLinkCapabilities = new LinkCapabilities();
+
+        mNetworkInfo.setIsAvailable(false);
+        setTeardownRequested(false);
+    }
+
+    public static synchronized BluetoothTetheringDataTracker getInstance() {
+        if (sInstance == null) sInstance = new BluetoothTetheringDataTracker();
+        return sInstance;
+    }
+
+    public Object Clone() throws CloneNotSupportedException {
+        throw new CloneNotSupportedException();
+    }
+
+    public void setTeardownRequested(boolean isRequested) {
+        mTeardownRequested.set(isRequested);
+    }
+
+    public boolean isTeardownRequested() {
+        return mTeardownRequested.get();
+    }
+
+    /**
+     * Begin monitoring connectivity
+     */
+    public void startMonitoring(Context context, Handler target) {
+        mContext = context;
+        mCsHandler = target;
+        mBluetoothPan = new BluetoothPan(mContext);
+    }
+
+    /**
+     * Disable connectivity to a network
+     * TODO: do away with return value after making MobileDataStateTracker async
+     */
+    public boolean teardown() {
+        mTeardownRequested.set(true);
+        for (BluetoothDevice device: mBluetoothPan.getConnectedDevices()) {
+            mBluetoothPan.disconnect(device);
+        }
+        return true;
+    }
+
+    /**
+     * Re-enable connectivity to a network after a {@link #teardown()}.
+     */
+    public boolean reconnect() {
+        mTeardownRequested.set(false);
+        //Ignore
+        return true;
+    }
+
+    /**
+     * Turn the wireless radio off for a network.
+     * @param turnOn {@code true} to turn the radio on, {@code false}
+     */
+    public boolean setRadio(boolean turnOn) {
+        return true;
+    }
+
+    /**
+     * @return true - If are we currently tethered with another device.
+     */
+    public synchronized boolean isAvailable() {
+        return mNetworkInfo.isAvailable();
+    }
+
+    /**
+     * Tells the underlying networking system that the caller wants to
+     * begin using the named feature. The interpretation of {@code feature}
+     * is completely up to each networking implementation.
+     * @param feature the name of the feature to be used
+     * @param callingPid the process ID of the process that is issuing this request
+     * @param callingUid the user ID of the process that is issuing this request
+     * @return an integer value representing the outcome of the request.
+     * The interpretation of this value is specific to each networking
+     * implementation+feature combination, except that the value {@code -1}
+     * always indicates failure.
+     * TODO: needs to go away
+     */
+    public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
+        return -1;
+    }
+
+    /**
+     * Tells the underlying networking system that the caller is finished
+     * using the named feature. The interpretation of {@code feature}
+     * is completely up to each networking implementation.
+     * @param feature the name of the feature that is no longer needed.
+     * @param callingPid the process ID of the process that is issuing this request
+     * @param callingUid the user ID of the process that is issuing this request
+     * @return an integer value representing the outcome of the request.
+     * The interpretation of this value is specific to each networking
+     * implementation+feature combination, except that the value {@code -1}
+     * always indicates failure.
+     * TODO: needs to go away
+     */
+    public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
+        return -1;
+    }
+
+    /**
+     * @param enabled
+     */
+    public void setDataEnable(boolean enabled) {
+        android.util.Log.d(TAG, "setDataEnabled: IGNORING enabled=" + enabled);
+    }
+
+    /**
+     * Check if private DNS route is set for the network
+     */
+    public boolean isPrivateDnsRouteSet() {
+        return mPrivateDnsRouteSet.get();
+    }
+
+    /**
+     * Set a flag indicating private DNS route is set
+     */
+    public void privateDnsRouteSet(boolean enabled) {
+        mPrivateDnsRouteSet.set(enabled);
+    }
+
+    /**
+     * Fetch NetworkInfo for the network
+     */
+    public synchronized NetworkInfo getNetworkInfo() {
+        return mNetworkInfo;
+    }
+
+    /**
+     * Fetch LinkProperties for the network
+     */
+    public synchronized LinkProperties getLinkProperties() {
+        return new LinkProperties(mLinkProperties);
+    }
+
+   /**
+     * A capability is an Integer/String pair, the capabilities
+     * are defined in the class LinkSocket#Key.
+     *
+     * @return a copy of this connections capabilities, may be empty but never null.
+     */
+    public LinkCapabilities getLinkCapabilities() {
+        return new LinkCapabilities(mLinkCapabilities);
+    }
+
+    /**
+     * Fetch default gateway address for the network
+     */
+    public int getDefaultGatewayAddr() {
+        return mDefaultGatewayAddr.get();
+    }
+
+    /**
+     * Check if default route is set
+     */
+    public boolean isDefaultRouteSet() {
+        return mDefaultRouteSet.get();
+    }
+
+    /**
+     * Set a flag indicating default route is set for the network
+     */
+    public void defaultRouteSet(boolean enabled) {
+        mDefaultRouteSet.set(enabled);
+    }
+
+    /**
+     * Return the system properties name associated with the tcp buffer sizes
+     * for this network.
+     */
+    public String getTcpBufferSizesPropName() {
+        return "net.tcp.buffersize.wifi";
+    }
+
+
+    public synchronized void startReverseTether(String iface, BluetoothDevice device) {
+        mIface = iface;
+        mDevice = device;
+        Thread dhcpThread = new Thread(new Runnable() {
+            public void run() {
+                //TODO(): Add callbacks for failure and success case.
+                //Currently this thread runs independently.
+                DhcpInfo dhcpInfo = new DhcpInfo();
+                if (!NetworkUtils.runDhcp(mIface, dhcpInfo)) {
+                    Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
+                    return;
+                }
+                mLinkProperties.addLinkAddress(new LinkAddress(
+                    NetworkUtils.intToInetAddress(dhcpInfo.ipAddress),
+                    NetworkUtils.intToInetAddress(dhcpInfo.netmask)));
+                mLinkProperties.setGateway(NetworkUtils.intToInetAddress(dhcpInfo.gateway));
+                InetAddress dns1Addr = NetworkUtils.intToInetAddress(dhcpInfo.dns1);
+                if (dns1Addr == null || dns1Addr.equals("0.0.0.0")) {
+                    mLinkProperties.addDns(dns1Addr);
+                }
+                InetAddress dns2Addr = NetworkUtils.intToInetAddress(dhcpInfo.dns2);
+                if (dns2Addr == null || dns2Addr.equals("0.0.0.0")) {
+                    mLinkProperties.addDns(dns2Addr);
+                }
+                mLinkProperties.setInterfaceName(mIface);
+
+                mNetworkInfo.setIsAvailable(true);
+                mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
+
+                Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
+                msg.sendToTarget();
+
+                msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+                msg.sendToTarget();
+            }
+        });
+        dhcpThread.start();
+    }
+
+    public synchronized void stopReverseTether(String iface) {
+        NetworkUtils.stopDhcp(iface);
+
+        mLinkProperties.clear();
+        mNetworkInfo.setIsAvailable(false);
+        mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
+
+        Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
+        msg.sendToTarget();
+
+        msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+        msg.sendToTarget();
+    }
+}
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index b19c072..d6bc959 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -38,7 +38,7 @@
         /* Runs on the UI thread */
         @Override
         protected void onPostExecute(D data) {
-            AsyncTaskLoader.this.dispatchOnLoadComplete(data);
+            AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
         }
 
         @Override
@@ -53,12 +53,9 @@
         super(context);
     }
 
-    /**
-     * Force an asynchronous load. Unlike {@link #startLoading()} this will ignore a previously
-     * loaded data set and load a new one.
-     */
     @Override
-    public void forceLoad() {
+    protected void onForceLoad() {
+        super.onForceLoad();
         cancelLoad();
         mTask = new LoadTask();
         mTask.execute((Void[]) null);
@@ -89,9 +86,13 @@
     public void onCancelled(D data) {
     }
 
-    void dispatchOnLoadComplete(D data) {
-        mTask = null;
-        deliverResult(data);
+    void dispatchOnLoadComplete(LoadTask task, D data) {
+        if (mTask != task) {
+            onCancelled(data);
+        } else {
+            mTask = null;
+            deliverResult(data);
+        }
     }
 
     /**
diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java
index 9e03c25..8ab0973 100644
--- a/core/java/android/content/CursorLoader.java
+++ b/core/java/android/content/CursorLoader.java
@@ -20,21 +20,24 @@
 import android.database.Cursor;
 import android.net.Uri;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
 /**
  * A loader that queries the {@link ContentResolver} and returns a {@link Cursor}.
  */
 public class CursorLoader extends AsyncTaskLoader<Cursor> {
-    Cursor mCursor;
-    ForceLoadContentObserver mObserver;
-    boolean mStopped;
-    boolean mContentChanged;
-    boolean mReset;
+    final ForceLoadContentObserver mObserver;
+
     Uri mUri;
     String[] mProjection;
     String mSelection;
     String[] mSelectionArgs;
     String mSortOrder;
 
+    Cursor mCursor;
+
     /* Runs on a worker thread */
     @Override
     public Cursor loadInBackground() {
@@ -59,7 +62,7 @@
     /* Runs on the UI thread */
     @Override
     public void deliverResult(Cursor cursor) {
-        if (mReset) {
+        if (isReset()) {
             // An async query came in while the loader is stopped
             if (cursor != null) {
                 cursor.close();
@@ -69,7 +72,7 @@
         Cursor oldCursor = mCursor;
         mCursor = cursor;
 
-        if (!mStopped) {
+        if (isStarted()) {
             super.deliverResult(cursor);
         }
 
@@ -97,15 +100,11 @@
      * Must be called from the UI thread
      */
     @Override
-    public void startLoading() {
-        mStopped = false;
-        mReset = false;
-
+    protected void onStartLoading() {
         if (mCursor != null) {
             deliverResult(mCursor);
         }
-        if (mCursor == null || mContentChanged) {
-            mContentChanged = false;
+        if (takeContentChanged() || mCursor == null) {
             forceLoad();
         }
     }
@@ -114,27 +113,12 @@
      * Must be called from the UI thread
      */
     @Override
-    public void stopLoading() {
+    protected void onStopLoading() {
         // Attempt to cancel the current load task if possible.
         cancelLoad();
-
-        // Make sure that any outstanding loads clean themselves up properly
-        mStopped = true;
     }
 
     @Override
-    public void onContentChanged() {
-        if (mStopped) {
-            // This loader has been stopped, so we don't want to load
-            // new data right now...  but keep track of it changing to
-            // refresh later if we start again.
-            mContentChanged = true;
-            return;
-        }
-        super.onContentChanged();
-    }
-    
-    @Override
     public void onCancelled(Cursor cursor) {
         if (cursor != null && !cursor.isClosed()) {
             cursor.close();
@@ -142,11 +126,11 @@
     }
 
     @Override
-    public void reset() {
-        mReset = true;
-
+    protected void onReset() {
+        super.onReset();
+        
         // Ensure the loader is stopped
-        stopLoading();
+        onStopLoading();
 
         if (mCursor != null && !mCursor.isClosed()) {
             mCursor.close();
@@ -193,4 +177,18 @@
     public void setSortOrder(String sortOrder) {
         mSortOrder = sortOrder;
     }
+
+    @Override
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        super.dump(prefix, fd, writer, args);
+        writer.print(prefix); writer.print("mUri="); writer.println(mUri);
+        writer.print(prefix); writer.print("mProjection=");
+                writer.println(Arrays.toString(mProjection));
+        writer.print(prefix); writer.print("mSelection="); writer.println(mSelection);
+        writer.print(prefix); writer.print("mSelectionArgs=");
+                writer.println(Arrays.toString(mSelectionArgs));
+        writer.print(prefix); writer.print("mSortOrder="); writer.println(mSortOrder);
+        writer.print(prefix); writer.print("mCursor="); writer.println(mCursor);
+        writer.print(prefix); writer.print("mContentChanged="); writer.println(mContentChanged);
+    }
 }
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index 73d7103..ef81fe4 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -18,18 +18,28 @@
 
 import android.database.ContentObserver;
 import android.os.Handler;
+import android.util.DebugUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 
 /**
  * An abstract class that performs asynchronous loading of data. While Loaders are active
  * they should monitor the source of their data and deliver new results when the contents
  * change.
  *
+ * <p>Subclasses generally must implement at least {@link #onStartLoading()},
+ * {@link #onStopLoading()}, {@link #onForceLoad()}, and {@link #onReset()}.
+ *
  * @param <D> The result returned when the load is complete
  */
-public abstract class Loader<D> {
+public class Loader<D> {
     int mId;
     OnLoadCompleteListener<D> mListener;
     Context mContext;
+    boolean mStarted = false;
+    boolean mReset = true;
+    boolean mContentChanged = false;
 
     public final class ForceLoadContentObserver extends ContentObserver {
         public ForceLoadContentObserver() {
@@ -122,28 +132,94 @@
     }
 
     /**
+     * Return whether this load has been started.  That is, its {@link #startLoading()}
+     * has been called and no calls to {@link #stopLoading()} or
+     * {@link #reset()} have yet been made.
+     */
+    public boolean isStarted() {
+        return mStarted;
+    }
+
+    /**
+     * Return whether this load has been reset.  That is, either the loader
+     * has not yet been started for the first time, or its {@link #reset()}
+     * has been called.
+     */
+    public boolean isReset() {
+        return mReset;
+    }
+
+    /**
      * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks
      * will be called on the UI thread. If a previous load has been completed and is still valid
      * the result may be passed to the callbacks immediately. The loader will monitor the source of
      * the data set and may deliver future callbacks if the source changes. Calling
      * {@link #stopLoading} will stop the delivery of callbacks.
      *
-     * <p>Must be called from the UI thread
+     * <p>This updates the Loader's internal state so that
+     * {@link #isStarted()} and {@link #isReset()} will return the correct
+     * values, and then calls the implementation's {@link #onStartLoading()}.
+     *
+     * <p>Must be called from the UI thread.
      */
-    public abstract void startLoading();
+    public final void startLoading() {
+        mStarted = true;
+        mReset = false;
+        onStartLoading();
+    }
+
+    /**
+     * Subclasses must implement this to take care of loading their data,
+     * as per {@link #startLoading()}.  This is not called by clients directly,
+     * but as a result of a call to {@link #startLoading()}.
+     */
+    protected void onStartLoading() {
+    }
 
     /**
      * Force an asynchronous load. Unlike {@link #startLoading()} this will ignore a previously
-     * loaded data set and load a new one.
+     * loaded data set and load a new one.  This simply calls through to the
+     * implementation's {@link #onForceLoad()}.  You generally should only call this
+     * when the loader is started -- that is, {@link #isStarted()} returns true.
+     *
+     * <p>Must be called from the UI thread.
      */
-    public abstract void forceLoad();
+    public final void forceLoad() {
+        onForceLoad();
+    }
 
     /**
-     * Stops delivery of updates until the next time {@link #startLoading()} is called
-     *
-     * <p>Must be called from the UI thread
+     * Subclasses must implement this to take care of requests to {@link #forceLoad()}.
      */
-    public abstract void stopLoading();
+    protected void onForceLoad() {
+    }
+
+    /**
+     * Stops delivery of updates until the next time {@link #startLoading()} is called.
+     * Implementations should <em>not</em> invalidate their data at this point --
+     * clients are still free to use the last data the loader reported.  They will,
+     * however, typically stop reporting new data if the data changes; they can
+     * still monitor for changes, but must not report them to the client until and
+     * if {@link #startLoading()} is later called.
+     *
+     * <p>This updates the Loader's internal state so that
+     * {@link #isStarted()} will return the correct
+     * value, and then calls the implementation's {@link #onStopLoading()}.
+     *
+     * <p>Must be called from the UI thread.
+     */
+    public final void stopLoading() {
+        mStarted = false;
+        onStopLoading();
+    }
+
+    /**
+     * Subclasses must implement this to take care of stopping their loader,
+     * as per {@link #stopLoading()}.  This is not called by clients directly,
+     * but as a result of a call to {@link #stopLoading()}.
+     */
+    protected void onStopLoading() {
+    }
 
     /**
      * Resets the state of the Loader.  The Loader should at this point free
@@ -151,26 +227,91 @@
      * {@link #startLoading()} may later be called at which point it must be
      * able to start running again.
      *
-     * <p>Must be called from the UI thread
-     */
-    public void reset() {
-        destroy();
-    }
-
-    /**
-     * @deprecated Old API, implement reset() now.
-     */
-    @Deprecated
-    public void destroy() {
-    }
-
-    /**
-     * Called when {@link ForceLoadContentObserver} detects a change.  Calls {@link #forceLoad()}
-     * by default.
+     * <p>This updates the Loader's internal state so that
+     * {@link #isStarted()} and {@link #isReset()} will return the correct
+     * values, and then calls the implementation's {@link #onReset()}.
      *
-     * <p>Must be called from the UI thread
+     * <p>Must be called from the UI thread.
+     */
+    public final void reset() {
+        onReset();
+        mReset = true;
+        mStarted = false;
+        mContentChanged = false;
+    }
+
+    /**
+     * Subclasses must implement this to take care of resetting their loader,
+     * as per {@link #reset()}.  This is not called by clients directly,
+     * but as a result of a call to {@link #reset()}.
+     */
+    protected void onReset() {
+    }
+
+    /**
+     * Take the current flag indicating whether the loader's content had
+     * changed while it was stopped.  If it had, true is returned and the
+     * flag is cleared.
+     */
+    public boolean takeContentChanged() {
+        boolean res = mContentChanged;
+        mContentChanged = false;
+        return res;
+    }
+    
+    /**
+     * Called when {@link ForceLoadContentObserver} detects a change.  The
+     * default implementation checks to see if the loader is currently started;
+     * if so, it simply calls {@link #forceLoad()}; otherwise, it sets a flag
+     * so that {@link #takeContentChanged()} returns true.
+     *
+     * <p>Must be called from the UI thread.
      */
     public void onContentChanged() {
-        forceLoad();
+        if (mStarted) {
+            forceLoad();
+        } else {
+            // This loader has been stopped, so we don't want to load
+            // new data right now...  but keep track of it changing to
+            // refresh later if we start again.
+            mContentChanged = true;
+        }
+    }
+
+    /**
+     * For debugging, converts an instance of the Loader's data class to
+     * a string that can be printed.  Must handle a null data.
+     */
+    public String dataToString(D data) {
+        StringBuilder sb = new StringBuilder(64);
+        DebugUtils.buildShortClassTag(data, sb);
+        sb.append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(64);
+        DebugUtils.buildShortClassTag(this, sb);
+        sb.append(" id=");
+        sb.append(mId);
+        sb.append("}");
+        return sb.toString();
+    }
+
+    /**
+     * Print the Loader's state into the given stream.
+     *
+     * @param prefix Text to print at the front of each line.
+     * @param fd The raw file descriptor that the dump is being sent to.
+     * @param writer A PrintWriter to which the dump is to be set.
+     * @param args Additional arguments to the dump request.
+     */
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        writer.print(prefix); writer.print("mId="); writer.print(mId);
+                writer.print(" mListener="); writer.println(mListener);
+        writer.print(prefix); writer.print("mStarted="); writer.print(mStarted);
+                writer.print(" mContentChanged="); writer.print(mContentChanged);
+                writer.print(" mReset="); writer.println(mReset);
     }
 }
\ No newline at end of file
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index a026eca..9a8f2d2 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -16,6 +16,7 @@
 
 package android.database;
 
+import android.content.res.Resources;
 import android.database.sqlite.SQLiteClosable;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -25,6 +26,13 @@
  * A buffer containing multiple cursor rows.
  */
 public class CursorWindow extends SQLiteClosable implements Parcelable {
+    /** The cursor window size. resource xml file specifies the value in kB.
+     * convert it to bytes here by multiplying with 1024.
+     */
+    private static final int sCursorWindowSize =
+        Resources.getSystem().getInteger(
+                com.android.internal.R.integer.config_cursorWindowSize) * 1024;
+
     /** The pointer to the native window class */
     @SuppressWarnings("unused")
     private int nWindow;
@@ -38,7 +46,7 @@
      */
     public CursorWindow(boolean localWindow) {
         mStartPos = 0;
-        native_init(localWindow);
+        native_init(sCursorWindowSize, localWindow);
     }
 
     /**
@@ -574,7 +582,7 @@
     private native IBinder native_getBinder();
 
     /** Does the native side initialization for an empty window */
-    private native void native_init(boolean localOnly);
+    private native void native_init(int cursorWindowSize, boolean localOnly);
 
     /** Does the native side initialization with an existing binder from another process */
     private native void native_init(IBinder nativeBinder);
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 184988b..6f59dc9 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -18,6 +18,7 @@
 
 import android.app.AppGlobals;
 import android.content.ContentValues;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.DatabaseErrorHandler;
 import android.database.DatabaseUtils;
@@ -1963,6 +1964,15 @@
         // If the caller sets errorHandler = null, then use default errorhandler.
         mErrorHandler = (errorHandler == null) ? new DefaultDatabaseErrorHandler() : errorHandler;
         mConnectionNum = connectionNum;
+        /* sqlite soft heap limit http://www.sqlite.org/c3ref/soft_heap_limit64.html
+         * set it to 4 times the default cursor window size.
+         * TODO what is an appropriate value, considring the WAL feature which could burn
+         * a lot of memory with many connections to the database. needs testing to figure out
+         * optimal value for this.
+         */
+        int limit = Resources.getSystem().getInteger(
+                com.android.internal.R.integer.config_cursorWindowSize) * 1024 * 4;
+        native_setSqliteSoftHeapLimit(limit);
     }
 
     /**
@@ -2670,4 +2680,10 @@
      * @param statementId statement to be finzlied by sqlite
      */
     private final native void native_finalize(int statementId);
+
+    /**
+     * set sqlite soft heap limit
+     * http://www.sqlite.org/c3ref/soft_heap_limit64.html
+     */
+    private native void native_setSqliteSoftHeapLimit(int softHeapLimit);
 }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3d685cb..7e809f5 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -213,10 +213,16 @@
      */
     public static final int TYPE_WIMAX       = 6;
 
+    /**
+     * Bluetooth data connection. This is used for Bluetooth reverse tethering.
+     * @hide
+     */
+    public static final int TYPE_BLUETOOTH   = 7;
+
     /** {@hide} */
-    public static final int TYPE_DUMMY       = 7;
+    public static final int TYPE_DUMMY       = 8;
     /** {@hide} TODO: Need to adjust this for WiMAX. */
-    public static final int MAX_RADIO_TYPE   = TYPE_WIFI;
+    public static final int MAX_RADIO_TYPE   = TYPE_DUMMY;
     /** {@hide} TODO: Need to adjust this for WiMAX. */
     public static final int MAX_NETWORK_TYPE = TYPE_DUMMY;
 
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
index cd12249..53db0c5 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -140,6 +140,7 @@
             return null;
         }
     }
+
     /**
      * Overwrite the primary NDEF message
      * @throws IOException
diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java
index 899b95f..222c558 100644
--- a/core/java/android/nfc/technology/NdefFormatable.java
+++ b/core/java/android/nfc/technology/NdefFormatable.java
@@ -45,16 +45,6 @@
     }
 
     /**
-     * Returns whether a tag can be formatted with {@link
-     * NdefFormatable#format(NdefMessage)}
-     */
-    public boolean canBeFormatted() throws IOException {
-        checkConnected();
-
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Formats a tag as NDEF, if possible. You may supply a first
      * NdefMessage to be written on the tag.
      */
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index f0309d6..9d5d742 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -281,7 +281,7 @@
     /**
      * Runs on the UI thread after {@link #doInBackground}. The
      * specified result is the value returned by {@link #doInBackground}
-     * or null if the task was cancelled or an exception occured.
+     * or null if the task was cancelled or an exception occurred.
      *
      * @param result The result of the operation computed by {@link #doInBackground}.
      *
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 5f6c4f0..b6c2ed6 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -153,6 +153,7 @@
     private static native int createPipeNative(FileDescriptor[] outFds);
 
     /**
+     * @deprecated Please use createPipe() or ContentProvider.openPipeHelper().
      * Gets a file descriptor for a read-only copy of the given data.
      *
      * @param data Data to copy.
@@ -161,6 +162,7 @@
      * @return A ParcelFileDescriptor.
      * @throws IOException if there is an error while creating the shared memory area.
      */
+    @Deprecated
     public static ParcelFileDescriptor fromData(byte[] data, String name) throws IOException {
         if (data == null) return null;
         MemoryFile file = new MemoryFile(name, data.length);
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 3b2e254..c04bb52 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -420,12 +420,16 @@
         if (name.equals("Connected")) {
             if (propValues[1].equals("false")) {
                 mBluetoothService.handlePanDeviceStateChange(device,
-                                          BluetoothInputDevice.STATE_DISCONNECTED);
+                                          BluetoothPan.STATE_DISCONNECTED,
+                                          BluetoothPan.LOCAL_PANU_ROLE);
             }
         } else if (name.equals("Interface")) {
             String iface = propValues[1];
-            mBluetoothService.handlePanDeviceStateChange(device, iface,
-                                            BluetoothInputDevice.STATE_CONNECTED);
+            if (!iface.equals("")) {
+                mBluetoothService.handlePanDeviceStateChange(device, iface,
+                                              BluetoothPan.STATE_CONNECTED,
+                                              BluetoothPan.LOCAL_PANU_ROLE);
+            }
         }
     }
 
@@ -751,18 +755,21 @@
             }
             int newState = connected? BluetoothPan.STATE_CONNECTED :
                 BluetoothPan.STATE_DISCONNECTED;
-            mBluetoothService.handlePanDeviceStateChange(device, newState);
+            mBluetoothService.handlePanDeviceStateChange(device, newState,
+                                                  BluetoothPan.LOCAL_PANU_ROLE);
         }
     }
 
     private void onNetworkDeviceDisconnected(String address) {
         BluetoothDevice device = mAdapter.getRemoteDevice(address);
-        mBluetoothService.handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTED);
+        mBluetoothService.handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTED,
+                                                      BluetoothPan.LOCAL_NAP_ROLE);
     }
 
     private void onNetworkDeviceConnected(String address, String iface, int destUuid) {
         BluetoothDevice device = mAdapter.getRemoteDevice(address);
-        mBluetoothService.handlePanDeviceStateChange(device, iface, BluetoothPan.STATE_CONNECTED);
+        mBluetoothService.handlePanDeviceStateChange(device, iface, BluetoothPan.STATE_CONNECTED,
+                                                      BluetoothPan.LOCAL_NAP_ROLE);
     }
 
     private void onRestartRequired() {
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index f91db87..9261ff6 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -34,6 +34,7 @@
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothProfileState;
 import android.bluetooth.BluetoothSocket;
+import android.bluetooth.BluetoothTetheringDataTracker;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetooth;
 import android.bluetooth.IBluetoothCallback;
@@ -54,7 +55,6 @@
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemService;
 import android.provider.Settings;
 import android.util.Log;
 import android.util.Pair;
@@ -79,11 +79,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 public class BluetoothService extends IBluetooth.Stub {
     private static final String TAG = "BluetoothService";
@@ -169,6 +167,8 @@
     private static String mDockAddress;
     private String mDockPin;
 
+    private String mIface;
+
     private int mAdapterConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
 
     private static class RemoteService {
@@ -1513,12 +1513,14 @@
             return false;
         }
 
-        handlePanDeviceStateChange(device, BluetoothPan.STATE_CONNECTING);
+        handlePanDeviceStateChange(device, BluetoothPan.STATE_CONNECTING,
+                                           BluetoothPan.LOCAL_PANU_ROLE);
         if (connectPanDeviceNative(objectPath, "nap")) {
             log ("connecting to PAN");
             return true;
         } else {
-            handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTED);
+            handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTED,
+                                                BluetoothPan.LOCAL_PANU_ROLE);
             log ("could not connect to PAN");
             return false;
         }
@@ -1560,13 +1562,15 @@
         if (getPanDeviceState(device) != BluetoothPan.STATE_CONNECTED) {
             log (device + " already disconnected from PAN");
         }
-        handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTING);
+        handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTING,
+                                    BluetoothPan.LOCAL_PANU_ROLE);
         return disconnectPanDeviceNative(objectPath);
     }
 
     /*package*/ synchronized void handlePanDeviceStateChange(BluetoothDevice device,
                                                              String iface,
-                                                             int state) {
+                                                             int state,
+                                                             int role) {
         int prevState;
         String ifaceAddr = null;
 
@@ -1578,13 +1582,25 @@
         }
         if (prevState == state) return;
 
-        if (state == BluetoothPan.STATE_CONNECTED) {
-            ifaceAddr = enableTethering(iface);
-            if (ifaceAddr == null) Log.e(TAG, "Error seting up tether interface");
-        } else if (state == BluetoothPan.STATE_DISCONNECTED) {
-            if (ifaceAddr != null) {
-                mBluetoothIfaceAddresses.remove(ifaceAddr);
-                ifaceAddr = null;
+        if (role == BluetoothPan.LOCAL_NAP_ROLE) {
+            if (state == BluetoothPan.STATE_CONNECTED) {
+                ifaceAddr = enableTethering(iface);
+                if (ifaceAddr == null) Log.e(TAG, "Error seting up tether interface");
+            } else if (state == BluetoothPan.STATE_DISCONNECTED) {
+                if (ifaceAddr != null) {
+                    mBluetoothIfaceAddresses.remove(ifaceAddr);
+                    ifaceAddr = null;
+                }
+            }
+        } else {
+            // PANU Role = reverse Tether
+            if (state == BluetoothPan.STATE_CONNECTED) {
+                mIface = iface;
+                BluetoothTetheringDataTracker.getInstance().startReverseTether(iface, device);
+            } else if (state == BluetoothPan.STATE_DISCONNECTED &&
+                  (prevState == BluetoothPan.STATE_CONNECTED ||
+                  prevState == BluetoothPan.STATE_DISCONNECTING)) {
+                BluetoothTetheringDataTracker.getInstance().stopReverseTether(mIface);
             }
         }
 
@@ -1595,6 +1611,7 @@
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
         intent.putExtra(BluetoothPan.EXTRA_PREVIOUS_PAN_STATE, prevState);
         intent.putExtra(BluetoothPan.EXTRA_PAN_STATE, state);
+        intent.putExtra(BluetoothPan.EXTRA_LOCAL_ROLE, role);
         mContext.sendBroadcast(intent, BLUETOOTH_PERM);
 
         if (DBG) log("Pan Device state : device: " + device + " State:" + prevState + "->" + state);
@@ -1602,8 +1619,8 @@
     }
 
     /*package*/ synchronized void handlePanDeviceStateChange(BluetoothDevice device,
-                                                             int state) {
-        handlePanDeviceStateChange(device, null, state);
+                                                             int state, int role) {
+        handlePanDeviceStateChange(device, null, state, role);
     }
 
     private String createNewTetheringAddressLocked() {
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index d724320..a61ff13 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -16,6 +16,7 @@
 
 package android.text.method;
 
+import android.graphics.Rect;
 import android.text.Layout;
 import android.text.Selection;
 import android.text.Spannable;
@@ -24,170 +25,185 @@
 import android.view.View;
 import android.widget.TextView;
 
-// XXX this doesn't extend MetaKeyKeyListener because the signatures
-// don't match.  Need to figure that out.  Meanwhile the meta keys
-// won't work in fields that don't take input.
-
-public class ArrowKeyMovementMethod implements MovementMethod {
-    private boolean isCap(Spannable buffer) {
+/**
+ * A movement method that provides cursor movement and selection.
+ * Supports displaying the context menu on DPad Center.
+ */
+public class ArrowKeyMovementMethod extends BaseMovementMethod implements MovementMethod {
+    private static boolean isSelecting(Spannable buffer) {
         return ((MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SHIFT_ON) == 1) ||
                 (MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0));
     }
 
-    private boolean isAlt(Spannable buffer) {
-        return MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_ALT_ON) == 1;
+    private int getCurrentLineTop(Spannable buffer, Layout layout) {
+        return layout.getLineTop(layout.getLineForOffset(Selection.getSelectionEnd(buffer)));
     }
 
-    private boolean up(TextView widget, Spannable buffer) {
-        boolean cap = isCap(buffer);
-        boolean alt = isAlt(buffer);
-        Layout layout = widget.getLayout();
-
-        if (cap) {
-            if (alt) {
-                Selection.extendSelection(buffer, 0);
-                return true;
-            } else {
-                return Selection.extendUp(buffer, layout);
-            }
-        } else {
-            if (alt) {
-                Selection.setSelection(buffer, 0);
-                return true;
-            } else {
-                return Selection.moveUp(buffer, layout);
-            }
-        }
+    private int getPageHeight(TextView widget) {
+        // This calculation does not take into account the view transformations that
+        // may have been applied to the child or its containers.  In case of scaling or
+        // rotation, the calculated page height may be incorrect.
+        final Rect rect = new Rect();
+        return widget.getGlobalVisibleRect(rect) ? rect.height() : 0;
     }
 
-    private boolean down(TextView widget, Spannable buffer) {
-        boolean cap = isCap(buffer);
-        boolean alt = isAlt(buffer);
-        Layout layout = widget.getLayout();
-
-        if (cap) {
-            if (alt) {
-                Selection.extendSelection(buffer, buffer.length());
-                return true;
-            } else {
-                return Selection.extendDown(buffer, layout);
-            }
-        } else {
-            if (alt) {
-                Selection.setSelection(buffer, buffer.length());
-                return true;
-            } else {
-                return Selection.moveDown(buffer, layout);
-            }
-        }
-    }
-
-    private boolean left(TextView widget, Spannable buffer) {
-        boolean cap = isCap(buffer);
-        boolean alt = isAlt(buffer);
-        Layout layout = widget.getLayout();
-
-        if (cap) {
-            if (alt) {
-                return Selection.extendToLeftEdge(buffer, layout);
-            } else {
-                return Selection.extendLeft(buffer, layout);
-            }
-        } else {
-            if (alt) {
-                return Selection.moveToLeftEdge(buffer, layout);
-            } else {
-                return Selection.moveLeft(buffer, layout); 
-            }
-        }
-    }
-
-    private boolean right(TextView widget, Spannable buffer) {
-        boolean cap = isCap(buffer);
-        boolean alt = isAlt(buffer);
-        Layout layout = widget.getLayout();
-
-        if (cap) {
-            if (alt) {
-                return Selection.extendToRightEdge(buffer, layout);
-            } else {
-                return Selection.extendRight(buffer, layout);
-            }
-        } else {
-            if (alt) {
-                return Selection.moveToRightEdge(buffer, layout);
-            } else {
-                return Selection.moveRight(buffer, layout); 
-            }
-        }
-    }
-
-    public boolean onKeyDown(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
-        if (executeDown(widget, buffer, keyCode)) {
-            MetaKeyKeyListener.adjustMetaAfterKeypress(buffer);
-            MetaKeyKeyListener.resetLockedMeta(buffer);
-            return true;
-        }
-
-        return false;
-    }
-
-    private boolean executeDown(TextView widget, Spannable buffer, int keyCode) {
-        boolean handled = false;
-
+    @Override
+    protected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode,
+            int movementMetaState, KeyEvent event) {
         switch (keyCode) {
-        case KeyEvent.KEYCODE_DPAD_UP:
-            handled |= up(widget, buffer);
-            break;
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    if (event.getAction() == KeyEvent.ACTION_DOWN
+                            && event.getRepeatCount() == 0
+                            && MetaKeyKeyListener.getMetaState(buffer,
+                                        MetaKeyKeyListener.META_SELECTING) != 0) {
+                        return widget.showContextMenu();
+                    }
+                }
+                break;
+        }
+        return super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);
+    }
 
-        case KeyEvent.KEYCODE_DPAD_DOWN:
-            handled |= down(widget, buffer);
-            break;
+    @Override
+    protected boolean left(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        if (isSelecting(buffer)) {
+            return Selection.extendLeft(buffer, layout);
+        } else {
+            return Selection.moveLeft(buffer, layout);
+        }
+    }
 
-        case KeyEvent.KEYCODE_DPAD_LEFT:
-            handled |= left(widget, buffer);
-            break;
+    @Override
+    protected boolean right(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        if (isSelecting(buffer)) {
+            return Selection.extendRight(buffer, layout);
+        } else {
+            return Selection.moveRight(buffer, layout);
+        }
+    }
 
-        case KeyEvent.KEYCODE_DPAD_RIGHT:
-            handled |= right(widget, buffer);
-            break;
+    @Override
+    protected boolean up(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        if (isSelecting(buffer)) {
+            return Selection.extendUp(buffer, layout);
+        } else {
+            return Selection.moveUp(buffer, layout);
+        }
+    }
 
-        case KeyEvent.KEYCODE_DPAD_CENTER:
-            if ((MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0) &&
-                (widget.showContextMenu())) {
-                    handled = true;
+    @Override
+    protected boolean down(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        if (isSelecting(buffer)) {
+            return Selection.extendDown(buffer, layout);
+        } else {
+            return Selection.moveDown(buffer, layout);
+        }
+    }
+
+    @Override
+    protected boolean pageUp(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        final boolean selecting = isSelecting(buffer);
+        final int targetY = getCurrentLineTop(buffer, layout) - getPageHeight(widget);
+        boolean handled = false;
+        for (;;) {
+            final int previousSelectionEnd = Selection.getSelectionEnd(buffer);
+            if (selecting) {
+                Selection.extendUp(buffer, layout);
+            } else {
+                Selection.moveUp(buffer, layout);
+            }
+            if (Selection.getSelectionEnd(buffer) == previousSelectionEnd) {
+                break;
+            }
+            handled = true;
+            if (getCurrentLineTop(buffer, layout) <= targetY) {
+                break;
             }
         }
-
-        if (handled) {
-            MetaKeyKeyListener.adjustMetaAfterKeypress(buffer);
-            MetaKeyKeyListener.resetLockedMeta(buffer);
-        }
-
         return handled;
     }
 
-    public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
-        return false;
-    }
-
-    public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
-        int code = event.getKeyCode();
-        if (code != KeyEvent.KEYCODE_UNKNOWN && event.getAction() == KeyEvent.ACTION_MULTIPLE) {
-            int repeat = event.getRepeatCount();
-            boolean handled = false;
-            while ((--repeat) > 0) {
-                handled |= executeDown(view, text, code);
+    @Override
+    protected boolean pageDown(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        final boolean selecting = isSelecting(buffer);
+        final int targetY = getCurrentLineTop(buffer, layout) + getPageHeight(widget);
+        boolean handled = false;
+        for (;;) {
+            final int previousSelectionEnd = Selection.getSelectionEnd(buffer);
+            if (selecting) {
+                Selection.extendDown(buffer, layout);
+            } else {
+                Selection.moveDown(buffer, layout);
             }
-            return handled;
+            if (Selection.getSelectionEnd(buffer) == previousSelectionEnd) {
+                break;
+            }
+            handled = true;
+            if (getCurrentLineTop(buffer, layout) >= targetY) {
+                break;
+            }
         }
-        return false;
+        return handled;
     }
 
-    public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event) {
-        return false;
+    @Override
+    protected boolean top(TextView widget, Spannable buffer) {
+        if (isSelecting(buffer)) {
+            Selection.extendSelection(buffer, 0);
+        } else {
+            Selection.setSelection(buffer, 0);
+        }
+        return true;
     }
 
+    @Override
+    protected boolean bottom(TextView widget, Spannable buffer) {
+        if (isSelecting(buffer)) {
+            Selection.extendSelection(buffer, buffer.length());
+        } else {
+            Selection.setSelection(buffer, buffer.length());
+        }
+        return true;
+    }
+
+    @Override
+    protected boolean lineStart(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        if (isSelecting(buffer)) {
+            return Selection.extendToLeftEdge(buffer, layout);
+        } else {
+            return Selection.moveToLeftEdge(buffer, layout);
+        }
+    }
+
+    @Override
+    protected boolean lineEnd(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        if (isSelecting(buffer)) {
+            return Selection.extendToRightEdge(buffer, layout);
+        } else {
+            return Selection.moveToRightEdge(buffer, layout);
+        }
+    }
+
+    @Override
+    protected boolean home(TextView widget, Spannable buffer) {
+        return lineStart(widget, buffer);
+    }
+
+    @Override
+    protected boolean end(TextView widget, Spannable buffer) {
+        return lineEnd(widget, buffer);
+    }
+
+    @Override
     public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
         int initialScrollX = -1, initialScrollY = -1;
         final int action = event.getAction();
@@ -201,7 +217,7 @@
 
         if (widget.isFocused() && !widget.didTouchFocusSelect()) {
             if (action == MotionEvent.ACTION_DOWN) {
-              boolean cap = isCap(buffer);
+              boolean cap = isSelecting(buffer);
               if (cap) {
                   int offset = widget.getOffset((int) event.getX(), (int) event.getY());
                   
@@ -214,7 +230,7 @@
                   widget.getParent().requestDisallowInterceptTouchEvent(true);
               }
             } else if (action == MotionEvent.ACTION_MOVE) {
-                boolean cap = isCap(buffer);
+                boolean cap = isSelecting(buffer);
 
                 if (cap && handled) {
                     // Before selecting, make sure we've moved out of the "slop".
@@ -245,7 +261,7 @@
                 }
 
                 int offset = widget.getOffset((int) event.getX(), (int) event.getY());
-                if (isCap(buffer)) {
+                if (isSelecting(buffer)) {
                     buffer.removeSpan(LAST_TAP_DOWN);
                     Selection.extendSelection(buffer, offset);
                 } else {
@@ -262,14 +278,17 @@
         return handled;
     }
 
+    @Override
     public boolean canSelectArbitrarily() {
         return true;
     }
 
+    @Override
     public void initialize(TextView widget, Spannable text) {
         Selection.setSelection(text, 0);
     }
 
+    @Override
     public void onTakeFocus(TextView view, Spannable text, int dir) {
         if ((dir & (View.FOCUS_FORWARD | View.FOCUS_DOWN)) != 0) {
             if (view.getLayout() == null) {
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 350c9a8..191c250 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -33,75 +33,116 @@
         implements KeyListener {
     /* package */ static final Object OLD_SEL_START = new NoCopySpan.Concrete();
 
+    private static final int MODIFIER_NONE = 0;
+    private static final int MODIFIER_ALT = 1;
+    private static final int MODIFIER_INVALID = 2;
+
+    private static int getModifier(Editable content, KeyEvent event) {
+        if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
+            return MODIFIER_ALT;
+        }
+        if (!event.hasNoModifiers()) {
+            return MODIFIER_INVALID;
+        }
+        if (getMetaState(content, META_ALT_ON) == 1) {
+            return MODIFIER_ALT;
+        }
+        return MODIFIER_NONE;
+    }
+
     /**
-     * Performs the action that happens when you press the DEL key in
-     * a TextView.  If there is a selection, deletes the selection;
-     * otherwise, DEL alone deletes the character before the cursor,
-     * if any;
-     * ALT+DEL deletes everything on the line the cursor is on.
+     * Performs the action that happens when you press the {@link KeyEvent#KEYCODE_DEL} key in
+     * a {@link TextView}.  If there is a selection, deletes the selection; otherwise,
+     * deletes the character before the cursor, if any; ALT+DEL deletes everything on
+     * the line the cursor is on.
      *
      * @return true if anything was deleted; false otherwise.
      */
-    public boolean backspace(View view, Editable content, int keyCode,
-                             KeyEvent event) {
-        int selStart, selEnd;
-        boolean result = true;
-
-        {
-            int a = Selection.getSelectionStart(content);
-            int b = Selection.getSelectionEnd(content);
-
-            selStart = Math.min(a, b);
-            selEnd = Math.max(a, b);
+    public boolean backspace(View view, Editable content, int keyCode, KeyEvent event) {
+        int modifier = getModifier(content, event);
+        if (modifier == MODIFIER_INVALID) {
+            return false;
         }
 
-        if (selStart != selEnd) {
-            content.delete(selStart, selEnd);
-        } else if (altBackspace(view, content, keyCode, event)) {
-            result = true;
-        } else {
-            int to = TextUtils.getOffsetBefore(content, selEnd);
-
-            if (to != selEnd) {
-                content.delete(Math.min(to, selEnd), Math.max(to, selEnd));
-            }
-            else {
-                result = false;
-            }
+        if (deleteSelection(view, content)) {
+            return true;
         }
 
-        if (result)
-            adjustMetaAfterKeypress(content);
+        if (modifier == MODIFIER_ALT && deleteLine(view, content)) {
+            return true;
+        }
 
-        return result;
+        final int start = Selection.getSelectionEnd(content);
+        final int end = TextUtils.getOffsetBefore(content, start);
+        if (start != end) {
+            content.delete(Math.min(start, end), Math.max(start, end));
+            return true;
+        }
+
+        return false;
     }
 
-    private boolean altBackspace(View view, Editable content, int keyCode,
-                                 KeyEvent event) {
-        if (!event.isAltPressed() && getMetaState(content, META_ALT_ON) != 1) {
+    /**
+     * Performs the action that happens when you press the {@link KeyEvent#KEYCODE_FORWARD_DEL}
+     * key in a {@link TextView}.  If there is a selection, deletes the selection; otherwise,
+     * deletes the character before the cursor, if any; ALT+FORWARD_DEL deletes everything on
+     * the line the cursor is on.
+     *
+     * @return true if anything was deleted; false otherwise.
+     */
+    public boolean forwardDelete(View view, Editable content, int keyCode, KeyEvent event) {
+        int modifier = getModifier(content, event);
+        if (modifier == MODIFIER_INVALID) {
             return false;
         }
 
-        if (!(view instanceof TextView)) {
-            return false;
+        if (deleteSelection(view, content)) {
+            return true;
         }
 
-        Layout layout = ((TextView) view).getLayout();
-
-        if (layout == null) {
-            return false;
+        if (modifier == MODIFIER_ALT && deleteLine(view, content)) {
+            return true;
         }
 
-        int l = layout.getLineForOffset(Selection.getSelectionStart(content));
-        int start = layout.getLineStart(l);
-        int end = layout.getLineEnd(l);
-
-        if (end == start) {
-            return false;
+        final int start = Selection.getSelectionEnd(content);
+        final int end = TextUtils.getOffsetAfter(content, start);
+        if (start != end) {
+            content.delete(Math.min(start, end), Math.max(start, end));
+            return true;
         }
 
-        content.delete(start, end);
-        return true;
+        return false;
+    }
+
+    private boolean deleteSelection(View view, Editable content) {
+        int selectionStart = Selection.getSelectionStart(content);
+        int selectionEnd = Selection.getSelectionEnd(content);
+        if (selectionEnd < selectionStart) {
+            int temp = selectionEnd;
+            selectionEnd = selectionStart;
+            selectionStart = temp;
+        }
+        if (selectionStart != selectionEnd) {
+            content.delete(selectionStart, selectionEnd);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean deleteLine(View view, Editable content) {
+        if (view instanceof TextView) {
+            final Layout layout = ((TextView) view).getLayout();
+            if (layout != null) {
+                final int line = layout.getLineForOffset(Selection.getSelectionStart(content));
+                final int start = layout.getLineStart(line);
+                final int end = layout.getLineEnd(line);
+                if (end != start) {
+                    content.delete(start, end);
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 
     static int makeTextContentType(Capitalize caps, boolean autoText) {
@@ -122,17 +163,29 @@
         }
         return contentType;
     }
-    
+
     public boolean onKeyDown(View view, Editable content,
                              int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_DEL) {
-            backspace(view, content, keyCode, event);
-            return true;
+        boolean handled;
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DEL:
+                handled = backspace(view, content, keyCode, event);
+                break;
+            case KeyEvent.KEYCODE_FORWARD_DEL:
+                handled = forwardDelete(view, content, keyCode, event);
+                break;
+            default:
+                handled = false;
+                break;
         }
-        
+
+        if (handled) {
+            adjustMetaAfterKeypress(content);
+        }
+
         return super.onKeyDown(view, content, keyCode, event);
     }
-    
+
     /**
      * Base implementation handles ACTION_MULTIPLE KEYCODE_UNKNOWN by inserting
      * the event's text into the content.
@@ -143,23 +196,21 @@
             // Not something we are interested in.
             return false;
         }
-        
-        int selStart, selEnd;
 
-        {
-            int a = Selection.getSelectionStart(content);
-            int b = Selection.getSelectionEnd(content);
-
-            selStart = Math.min(a, b);
-            selEnd = Math.max(a, b);
+        int selectionStart = Selection.getSelectionStart(content);
+        int selectionEnd = Selection.getSelectionEnd(content);
+        if (selectionEnd < selectionStart) {
+            int temp = selectionEnd;
+            selectionEnd = selectionStart;
+            selectionStart = temp;
         }
 
         CharSequence text = event.getCharacters();
         if (text == null) {
             return false;
         }
-        
-        content.replace(selStart, selEnd, text);
+
+        content.replace(selectionStart, selectionEnd, text);
         return true;
     }
 }
diff --git a/core/java/android/text/method/BaseMovementMethod.java b/core/java/android/text/method/BaseMovementMethod.java
new file mode 100644
index 0000000..2be18d6
--- /dev/null
+++ b/core/java/android/text/method/BaseMovementMethod.java
@@ -0,0 +1,345 @@
+/*
+ * 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 android.text.method;
+
+import android.text.Layout;
+import android.text.Spannable;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.widget.TextView;
+
+/**
+ * Base classes for movement methods.
+ */
+public class BaseMovementMethod implements MovementMethod {
+    @Override
+    public boolean canSelectArbitrarily() {
+        return false;
+    }
+
+    @Override
+    public void initialize(TextView widget, Spannable text) {
+    }
+
+    @Override
+    public boolean onKeyDown(TextView widget, Spannable text, int keyCode, KeyEvent event) {
+        final int movementMetaState = getMovementMetaState(text, event);
+        boolean handled = handleMovementKey(widget, text, keyCode, movementMetaState, event);
+        if (handled) {
+            MetaKeyKeyListener.adjustMetaAfterKeypress(text);
+            MetaKeyKeyListener.resetLockedMeta(text);
+        }
+        return handled;
+    }
+
+    @Override
+    public boolean onKeyOther(TextView widget, Spannable text, KeyEvent event) {
+        final int movementMetaState = getMovementMetaState(text, event);
+        final int keyCode = event.getKeyCode();
+        if (keyCode != KeyEvent.KEYCODE_UNKNOWN
+                && event.getAction() == KeyEvent.ACTION_MULTIPLE) {
+            final int repeat = event.getRepeatCount();
+            boolean handled = false;
+            for (int i = 0; i < repeat; i++) {
+                if (!handleMovementKey(widget, text, keyCode, movementMetaState, event)) {
+                    break;
+                }
+                handled = true;
+            }
+            if (handled) {
+                MetaKeyKeyListener.adjustMetaAfterKeypress(text);
+                MetaKeyKeyListener.resetLockedMeta(text);
+            }
+            return handled;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onKeyUp(TextView widget, Spannable text, int keyCode, KeyEvent event) {
+        return false;
+    }
+
+    @Override
+    public void onTakeFocus(TextView widget, Spannable text, int direction) {
+    }
+
+    @Override
+    public boolean onTouchEvent(TextView widget, Spannable text, MotionEvent event) {
+        return false;
+    }
+
+    @Override
+    public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event) {
+        return false;
+    }
+
+    /**
+     * Gets the meta state used for movement using the modifiers tracked by the text
+     * buffer as well as those present in the key event.
+     *
+     * The movement meta state excludes the state of locked modifiers or the SHIFT key
+     * since they are not used by movement actions (but they may be used for selection).
+     *
+     * @param buffer The text buffer.
+     * @param event The key event.
+     * @return The keyboard meta states used for movement.
+     */
+    protected int getMovementMetaState(Spannable buffer, KeyEvent event) {
+        // We ignore locked modifiers and SHIFT.
+        int metaState = (event.getMetaState() | MetaKeyKeyListener.getMetaState(buffer))
+                & ~(MetaKeyKeyListener.META_ALT_LOCKED | MetaKeyKeyListener.META_SYM_LOCKED);
+        return KeyEvent.normalizeMetaState(metaState) & ~KeyEvent.META_SHIFT_MASK;
+    }
+
+    /**
+     * Performs a movement key action.
+     * The default implementation decodes the key down and invokes movement actions
+     * such as {@link #down} and {@link #up}.
+     * {@link #onKeyDown(TextView, Spannable, int, KeyEvent)} calls this method once
+     * to handle an {@link KeyEvent#ACTION_DOWN}.
+     * {@link #onKeyOther(TextView, Spannable, KeyEvent)} calls this method repeatedly
+     * to handle each repetition of an {@link KeyEvent#ACTION_MULTIPLE}.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @param event The key event.
+     * @param keyCode The key code.
+     * @param movementMetaState The keyboard meta states used for movement.
+     * @param event The key event.
+     * @return True if the event was handled.
+     */
+    protected boolean handleMovementKey(TextView widget, Spannable buffer,
+            int keyCode, int movementMetaState, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_LEFT:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    return left(widget, buffer);
+                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
+                        KeyEvent.META_ALT_ON)) {
+                    return lineStart(widget, buffer);
+                }
+                break;
+
+            case KeyEvent.KEYCODE_DPAD_RIGHT:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    return right(widget, buffer);
+                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
+                        KeyEvent.META_ALT_ON)) {
+                    return lineEnd(widget, buffer);
+                }
+                break;
+
+            case KeyEvent.KEYCODE_DPAD_UP:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    return up(widget, buffer);
+                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
+                        KeyEvent.META_ALT_ON)) {
+                    return top(widget, buffer);
+                }
+                break;
+
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    return down(widget, buffer);
+                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
+                        KeyEvent.META_ALT_ON)) {
+                    return bottom(widget, buffer);
+                }
+                break;
+
+            case KeyEvent.KEYCODE_PAGE_UP:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    return pageUp(widget, buffer);
+                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
+                        KeyEvent.META_ALT_ON)) {
+                    return top(widget, buffer);
+                }
+                break;
+
+            case KeyEvent.KEYCODE_PAGE_DOWN:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    return pageDown(widget, buffer);
+                } else if (KeyEvent.metaStateHasModifiers(movementMetaState,
+                        KeyEvent.META_ALT_ON)) {
+                    return bottom(widget, buffer);
+                }
+                break;
+
+            case KeyEvent.KEYCODE_MOVE_HOME:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    return home(widget, buffer);
+                }
+                break;
+
+            case KeyEvent.KEYCODE_MOVE_END:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    return end(widget, buffer);
+                }
+                break;
+        }
+        return false;
+    }
+
+    /**
+     * Performs a left movement action.
+     * Moves the cursor or scrolls left by one character.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean left(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs a right movement action.
+     * Moves the cursor or scrolls right by one character.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean right(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs an up movement action.
+     * Moves the cursor or scrolls up by one line.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean up(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs a down movement action.
+     * Moves the cursor or scrolls down by one line.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean down(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs a page-up movement action.
+     * Moves the cursor or scrolls up by one page.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean pageUp(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs a page-down movement action.
+     * Moves the cursor or scrolls down by one page.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean pageDown(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs a top movement action.
+     * Moves the cursor or scrolls to the top of the buffer.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean top(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs a bottom movement action.
+     * Moves the cursor or scrolls to the bottom of the buffer.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean bottom(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs a line-start movement action.
+     * Moves the cursor or scrolls to the start of the line.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean lineStart(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs an line-end movement action.
+     * Moves the cursor or scrolls to the end of the line.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean lineEnd(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs a home movement action.
+     * Moves the cursor or scrolls to the start of the line or to the top of the
+     * document depending on whether the insertion point is being moved or
+     * the document is being scrolled.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean home(TextView widget, Spannable buffer) {
+        return false;
+    }
+
+    /**
+     * Performs an end movement action.
+     * Moves the cursor or scrolls to the start of the line or to the top of the
+     * document depending on whether the insertion point is being moved or
+     * the document is being scrolled.
+     *
+     * @param widget The text view.
+     * @param buffer The text buffer.
+     * @return True if the event was handled.
+     */
+    protected boolean end(TextView widget, Spannable buffer) {
+        return false;
+    }
+}
diff --git a/core/java/android/text/method/LinkMovementMethod.java b/core/java/android/text/method/LinkMovementMethod.java
index 22e9cc6..80c8169 100644
--- a/core/java/android/text/method/LinkMovementMethod.java
+++ b/core/java/android/text/method/LinkMovementMethod.java
@@ -16,8 +16,6 @@
 
 package android.text.method;
 
-import android.content.Intent;
-import android.net.Uri;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.text.*;
@@ -25,28 +23,30 @@
 import android.view.View;
 import android.widget.TextView;
 
-public class
-LinkMovementMethod
-extends ScrollingMovementMethod
-{
+/**
+ * A movement method that traverses links in the text buffer and scrolls if necessary.
+ * Supports clicking on links with DPad Center or Enter.
+ */
+public class LinkMovementMethod extends ScrollingMovementMethod {
     private static final int CLICK = 1;
     private static final int UP = 2;
     private static final int DOWN = 3;
 
     @Override
-    public boolean onKeyDown(TextView widget, Spannable buffer,
-                             int keyCode, KeyEvent event) {
+    protected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode,
+            int movementMetaState, KeyEvent event) {
         switch (keyCode) {
-        case KeyEvent.KEYCODE_DPAD_CENTER:
-        case KeyEvent.KEYCODE_ENTER:
-            if (event.getRepeatCount() == 0) {
-                if (action(CLICK, widget, buffer)) {
-                    return true;
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+            case KeyEvent.KEYCODE_ENTER:
+                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
+                    if (event.getAction() == KeyEvent.ACTION_DOWN
+                            && event.getRepeatCount() == 0) {
+                        return action(CLICK, widget, buffer);
+                    }
                 }
-            }
+                break;
         }
-
-        return super.onKeyDown(widget, buffer, keyCode, event);
+        return super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);
     }
 
     @Override
@@ -86,8 +86,6 @@
     }
 
     private boolean action(int what, TextView widget, Spannable buffer) {
-        boolean handled = false;
-
         Layout layout = widget.getLayout();
 
         int padding = widget.getTotalPaddingTop() +
@@ -184,11 +182,6 @@
         return false;
     }
 
-    public boolean onKeyUp(TextView widget, Spannable buffer,
-                           int keyCode, KeyEvent event) {
-        return false;
-    }
-
     @Override
     public boolean onTouchEvent(TextView widget, Spannable buffer,
                                 MotionEvent event) {
@@ -229,11 +222,13 @@
         return super.onTouchEvent(widget, buffer, event);
     }
 
+    @Override
     public void initialize(TextView widget, Spannable text) {
         Selection.removeSelection(text);
         text.removeSpan(FROM_BELOW);
     }
 
+    @Override
     public void onTakeFocus(TextView view, Spannable text, int dir) {
         Selection.removeSelection(text);
 
diff --git a/core/java/android/text/method/MovementMethod.java b/core/java/android/text/method/MovementMethod.java
index 29f67a1..9167676 100644
--- a/core/java/android/text/method/MovementMethod.java
+++ b/core/java/android/text/method/MovementMethod.java
@@ -21,24 +21,32 @@
 import android.view.MotionEvent;
 import android.text.*;
 
-public interface MovementMethod
-{
+/**
+ * Provides cursor positioning, scrolling and text selection functionality in a {@link TextView}.
+ * <p>
+ * The {@link TextView} delegates handling of key events, trackball motions and touches to
+ * the movement method for purposes of content navigation.  The framework automatically
+ * selects an appropriate movement method based on the content of the {@link TextView}.
+ * </p><p>
+ * This interface is intended for use by the framework; it should not be implemented
+ * directly by applications.
+ * </p>
+ */
+public interface MovementMethod {
     public void initialize(TextView widget, Spannable text);
     public boolean onKeyDown(TextView widget, Spannable text, int keyCode, KeyEvent event);
     public boolean onKeyUp(TextView widget, Spannable text, int keyCode, KeyEvent event);
-    
+
     /**
      * If the key listener wants to other kinds of key events, return true,
      * otherwise return false and the caller (i.e. the widget host)
      * will handle the key.
      */
     public boolean onKeyOther(TextView view, Spannable text, KeyEvent event);
-    
+
     public void onTakeFocus(TextView widget, Spannable text, int direction);
-    public boolean onTrackballEvent(TextView widget, Spannable text,
-                                    MotionEvent event);
-    public boolean onTouchEvent(TextView widget, Spannable text,
-                                MotionEvent event);
+    public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event);
+    public boolean onTouchEvent(TextView widget, Spannable text, MotionEvent event);
 
     /**
      * Returns true if this movement method allows arbitrary selection
diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java
index 09388c0..4c82b81 100644
--- a/core/java/android/text/method/QwertyKeyListener.java
+++ b/core/java/android/text/method/QwertyKeyListener.java
@@ -295,7 +295,9 @@
             }
 
             return true;
-        } else if (keyCode == KeyEvent.KEYCODE_DEL && selStart == selEnd) {
+        } else if (keyCode == KeyEvent.KEYCODE_DEL
+                && (event.hasNoModifiers() || event.hasModifiers(KeyEvent.META_ALT_ON))
+                && selStart == selEnd) {
             // special backspace case for undoing autotext
 
             int consider = 1;
diff --git a/core/java/android/text/method/ScrollingMovementMethod.java b/core/java/android/text/method/ScrollingMovementMethod.java
index 563ceed..194ecc1 100644
--- a/core/java/android/text/method/ScrollingMovementMethod.java
+++ b/core/java/android/text/method/ScrollingMovementMethod.java
@@ -16,201 +16,216 @@
 
 package android.text.method;
 
-import android.util.Log;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.text.*;
 import android.widget.TextView;
 import android.view.View;
 
-public class
-ScrollingMovementMethod
-implements MovementMethod
-{
-    /**
-     * Scrolls the text to the left if possible.
-     */
-    protected boolean left(TextView widget, Spannable buffer) {
-        Layout layout = widget.getLayout();
-        
-        int scrolly = widget.getScrollY();
-        int scr = widget.getScrollX();
-        int em = Math.round(layout.getPaint().getFontSpacing());
+/**
+ * A movement method that interprets movement keys by scrolling the text buffer.
+ */
+public class ScrollingMovementMethod extends BaseMovementMethod implements MovementMethod {
+    private int getTopLine(TextView widget) {
+        return widget.getLayout().getLineForVertical(widget.getScrollY());
+    }
 
-        int padding = widget.getTotalPaddingTop() +
-                      widget.getTotalPaddingBottom();
-        int top = layout.getLineForVertical(scrolly);
-        int bottom = layout.getLineForVertical(scrolly + widget.getHeight() -
-                                               padding);
+    private int getBottomLine(TextView widget) {
+        return widget.getLayout().getLineForVertical(widget.getScrollY() + getInnerHeight(widget));
+    }
+
+    private int getInnerWidth(TextView widget) {
+        return widget.getWidth() - widget.getTotalPaddingLeft() - widget.getTotalPaddingRight();
+    }
+
+    private int getInnerHeight(TextView widget) {
+        return widget.getHeight() - widget.getTotalPaddingTop() - widget.getTotalPaddingBottom();
+    }
+
+    private int getCharacterWidth(TextView widget) {
+        return (int) Math.ceil(widget.getPaint().getFontSpacing());
+    }
+
+    private int getScrollBoundsLeft(TextView widget) {
+        final Layout layout = widget.getLayout();
+        final int topLine = getTopLine(widget);
+        final int bottomLine = getBottomLine(widget);
+        if (topLine > bottomLine) {
+            return 0;
+        }
         int left = Integer.MAX_VALUE;
-
-        for (int i = top; i <= bottom; i++) {
-            left = (int) Math.min(left, layout.getLineLeft(i));
+        for (int line = topLine; line <= bottomLine; line++) {
+            final int lineLeft = (int) Math.floor(layout.getLineLeft(line));
+            if (lineLeft < left) {
+                left = lineLeft;
+            }
         }
+        return left;
+    }
 
-        if (scr > left) {
-            int s = Math.max(scr - em, left);
-            widget.scrollTo(s, widget.getScrollY());
+    private int getScrollBoundsRight(TextView widget) {
+        final Layout layout = widget.getLayout();
+        final int topLine = getTopLine(widget);
+        final int bottomLine = getBottomLine(widget);
+        if (topLine > bottomLine) {
+            return 0;
+        }
+        int right = Integer.MIN_VALUE;
+        for (int line = topLine; line <= bottomLine; line++) {
+            final int lineRight = (int) Math.ceil(layout.getLineRight(line));
+            if (lineRight > right) {
+                right = lineRight;
+            }
+        }
+        return right;
+    }
+
+    @Override
+    protected boolean left(TextView widget, Spannable buffer) {
+        final int minScrollX = getScrollBoundsLeft(widget);
+        int scrollX = widget.getScrollX();
+        if (scrollX > minScrollX) {
+            scrollX = Math.max(scrollX - getCharacterWidth(widget), minScrollX);
+            widget.scrollTo(scrollX, widget.getScrollY());
             return true;
         }
-
         return false;
     }
 
-    /**
-     * Scrolls the text to the right if possible.
-     */
+    @Override
     protected boolean right(TextView widget, Spannable buffer) {
-        Layout layout = widget.getLayout();
-
-        int scrolly = widget.getScrollY();
-        int scr = widget.getScrollX();
-        int em = Math.round(layout.getPaint().getFontSpacing());
-
-        int padding = widget.getTotalPaddingTop() +
-                      widget.getTotalPaddingBottom();
-        int top = layout.getLineForVertical(scrolly);
-        int bottom = layout.getLineForVertical(scrolly + widget.getHeight() -
-                                               padding);
-        int right = 0;
-
-        for (int i = top; i <= bottom; i++) {
-            right = (int) Math.max(right, layout.getLineRight(i));
-        }
-
-        padding = widget.getTotalPaddingLeft() + widget.getTotalPaddingRight();
-        if (scr < right - (widget.getWidth() - padding)) {
-            int s = Math.min(scr + em, right - (widget.getWidth() - padding));
-            widget.scrollTo(s, widget.getScrollY());
+        final int maxScrollX = getScrollBoundsRight(widget) - getInnerWidth(widget);
+        int scrollX = widget.getScrollX();
+        if (scrollX < maxScrollX) {
+            scrollX = Math.min(scrollX + getCharacterWidth(widget), maxScrollX);
+            widget.scrollTo(scrollX, widget.getScrollY());
             return true;
         }
-
         return false;
     }
 
-    /**
-     * Scrolls the text up if possible.
-     */
+    @Override
     protected boolean up(TextView widget, Spannable buffer) {
-        Layout layout = widget.getLayout();
-
-        int areatop = widget.getScrollY();
-        int line = layout.getLineForVertical(areatop);
-        int linetop = layout.getLineTop(line);
-
-        // If the top line is partially visible, bring it all the way
-        // into view; otherwise, bring the previous line into view.
-        if (areatop == linetop)
-            line--;
-
-        if (line >= 0) {
-            Touch.scrollTo(widget, layout,
-                           widget.getScrollX(), layout.getLineTop(line));
+        final Layout layout = widget.getLayout();
+        final int top = widget.getScrollY();
+        int topLine = layout.getLineForVertical(top);
+        if (layout.getLineTop(topLine) == top) {
+            // If the top line is partially visible, bring it all the way
+            // into view; otherwise, bring the previous line into view.
+            topLine -= 1;
+        }
+        if (topLine >= 0) {
+            Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop(topLine));
             return true;
         }
-
         return false;
     }
 
-    /**
-     * Scrolls the text down if possible.
-     */
+    @Override
     protected boolean down(TextView widget, Spannable buffer) {
-        Layout layout = widget.getLayout();
-
-        int padding = widget.getTotalPaddingTop() +
-                      widget.getTotalPaddingBottom();
-
-        int areabot = widget.getScrollY() + widget.getHeight() - padding;
-        int line = layout.getLineForVertical(areabot);
-
-        if (layout.getLineTop(line+1) < areabot + 1) {
+        final Layout layout = widget.getLayout();
+        final int innerHeight = getInnerHeight(widget);
+        final int bottom = widget.getScrollY() + innerHeight;
+        int bottomLine = layout.getLineForVertical(bottom);
+        if (layout.getLineTop(bottomLine + 1) < bottom + 1) {
             // Less than a pixel of this line is out of view,
             // so we must have tried to make it entirely in view
             // and now want the next line to be in view instead.
-
-            line++;
+            bottomLine += 1;
         }
-
-        if (line <= layout.getLineCount() - 1) {
-            widget.scrollTo(widget.getScrollX(), layout.getLineTop(line+1) -
-                            (widget.getHeight() - padding));
-            Touch.scrollTo(widget, layout,
-                                widget.getScrollX(), widget.getScrollY());
+        if (bottomLine <= layout.getLineCount() - 1) {
+            Touch.scrollTo(widget, layout, widget.getScrollX(),
+                    layout.getLineTop(bottomLine + 1) - innerHeight);
             return true;
         }
-
         return false;
     }
 
-    public boolean onKeyDown(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
-        return executeDown(widget, buffer, keyCode);
-    }
-
-    private boolean executeDown(TextView widget, Spannable buffer, int keyCode) {
-        boolean handled = false;
-
-        switch (keyCode) {
-        case KeyEvent.KEYCODE_DPAD_LEFT:
-            handled |= left(widget, buffer);
-            break;
-
-        case KeyEvent.KEYCODE_DPAD_RIGHT:
-            handled |= right(widget, buffer);
-            break;
-
-        case KeyEvent.KEYCODE_DPAD_UP:
-            handled |= up(widget, buffer);
-            break;
-
-        case KeyEvent.KEYCODE_DPAD_DOWN:
-            handled |= down(widget, buffer);
-            break;
-        }
-
-        return handled;
-    }
-
-    public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode, KeyEvent event) {
-        return false;
-    }
-
-    public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
-        int code = event.getKeyCode();
-        if (code != KeyEvent.KEYCODE_UNKNOWN
-                && event.getAction() == KeyEvent.ACTION_MULTIPLE) {
-            int repeat = event.getRepeatCount();
-            boolean first = true;
-            boolean handled = false;
-            while ((--repeat) > 0) {
-                if (first && executeDown(view, text, code)) {
-                    handled = true;
-                    MetaKeyKeyListener.adjustMetaAfterKeypress(text);
-                    MetaKeyKeyListener.resetLockedMeta(text);
-                }
-                first = false;
-            }
-            return handled;
+    @Override
+    protected boolean pageUp(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        final int top = widget.getScrollY() - getInnerHeight(widget);
+        int topLine = layout.getLineForVertical(top);
+        if (topLine >= 0) {
+            Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop(topLine));
+            return true;
         }
         return false;
     }
-    
-    public boolean onTrackballEvent(TextView widget, Spannable text,
-            MotionEvent event) {
+
+    @Override
+    protected boolean pageDown(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        final int innerHeight = getInnerHeight(widget);
+        final int bottom = widget.getScrollY() + innerHeight + innerHeight;
+        int bottomLine = layout.getLineForVertical(bottom);
+        if (bottomLine <= layout.getLineCount() - 1) {
+            Touch.scrollTo(widget, layout, widget.getScrollX(),
+                    layout.getLineTop(bottomLine + 1) - innerHeight);
+            return true;
+        }
         return false;
     }
-    
-    public boolean onTouchEvent(TextView widget, Spannable buffer,
-                                 MotionEvent event) {
+
+    @Override
+    protected boolean top(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        if (getTopLine(widget) >= 0) {
+            Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop(0));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected boolean bottom(TextView widget, Spannable buffer) {
+        final Layout layout = widget.getLayout();
+        final int lineCount = layout.getLineCount();
+        if (getBottomLine(widget) <= lineCount - 1) {
+            Touch.scrollTo(widget, layout, widget.getScrollX(),
+                    layout.getLineTop(lineCount) - getInnerHeight(widget));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected boolean lineStart(TextView widget, Spannable buffer) {
+        final int minScrollX = getScrollBoundsLeft(widget);
+        int scrollX = widget.getScrollX();
+        if (scrollX > minScrollX) {
+            widget.scrollTo(minScrollX, widget.getScrollY());
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected boolean lineEnd(TextView widget, Spannable buffer) {
+        final int maxScrollX = getScrollBoundsRight(widget) - getInnerWidth(widget);
+        int scrollX = widget.getScrollX();
+        if (scrollX < maxScrollX) {
+            widget.scrollTo(maxScrollX, widget.getScrollY());
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected boolean home(TextView widget, Spannable buffer) {
+        return top(widget, buffer);
+    }
+
+    @Override
+    protected boolean end(TextView widget, Spannable buffer) {
+        return bottom(widget, buffer);
+    }
+
+    @Override
+    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
         return Touch.onTouchEvent(widget, buffer, event);
     }
 
-    public void initialize(TextView widget, Spannable text) { }
-
-    public boolean canSelectArbitrarily() {
-        return false;
-    }
-
+    @Override
     public void onTakeFocus(TextView widget, Spannable text, int dir) {
         Layout layout = widget.getLayout();
 
diff --git a/core/java/android/util/DebugUtils.java b/core/java/android/util/DebugUtils.java
index 56f389c..65fc35c 100644
--- a/core/java/android/util/DebugUtils.java
+++ b/core/java/android/util/DebugUtils.java
@@ -101,4 +101,23 @@
         return match;
     }
 
+    /** @hide */
+    public static void buildShortClassTag(Object cls, StringBuilder out) {
+        if (cls == null) {
+            out.append("null");
+        } else {
+            String simpleName = cls.getClass().getSimpleName();
+            if (simpleName == null || simpleName.isEmpty()) {
+                simpleName = cls.getClass().getName();
+                int end = simpleName.lastIndexOf('.');
+                if (end > 0) {
+                    simpleName = simpleName.substring(end+1);
+                }
+            }
+            out.append(simpleName);
+            out.append('{');
+            out.append(Integer.toHexString(System.identityHashCode(cls)));
+        }
+    }
+
 }
diff --git a/core/java/android/util/Finalizers.java b/core/java/android/util/Finalizers.java
deleted file mode 100644
index 671f2d4..0000000
--- a/core/java/android/util/Finalizers.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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 android.util;
-
-import java.lang.ref.PhantomReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-
-/**
- * This class can be used to implement reliable finalizers.
- * 
- * @hide
- */
-public final class Finalizers {
-    private static final String LOG_TAG = "Finalizers";
-    
-    private static final Object[] sLock = new Object[0];
-    private static boolean sInit;
-    private static Reclaimer sReclaimer;
-
-    /**
-     * Subclass of PhantomReference used to reclaim resources.
-     */
-    public static abstract class ReclaimableReference<T> extends PhantomReference<T> {
-        public ReclaimableReference(T r, ReferenceQueue<Object> q) {
-            super(r, q);
-        }
-        
-        public abstract void reclaim();
-    }
-
-    /**
-     * Returns the queue used to reclaim ReclaimableReferences.
-     * 
-     * @return A reference queue or null before initialization
-     */
-    public static ReferenceQueue<Object> getQueue() {
-        synchronized (sLock) {
-            if (!sInit) {
-                return null;
-            }
-            if (!sReclaimer.isRunning()) {
-                sReclaimer = new Reclaimer(sReclaimer.mQueue);
-                sReclaimer.start();
-            }
-            return sReclaimer.mQueue;
-        }
-    }
-
-    /**
-     * Invoked by Zygote. Don't touch!
-     */
-    public static void init() {
-        synchronized (sLock) {
-            if (!sInit && sReclaimer == null) {
-                sReclaimer = new Reclaimer();
-                sReclaimer.start();
-                sInit = true;
-            }
-        }
-    }
-    
-    private static class Reclaimer extends Thread {
-        ReferenceQueue<Object> mQueue;
-
-        private volatile boolean mRunning = false;
-
-        Reclaimer() {
-            this(new ReferenceQueue<Object>());
-        }
-
-        Reclaimer(ReferenceQueue<Object> queue) {
-            super("Reclaimer");
-            setDaemon(true);
-            mQueue = queue;            
-        }
-
-        @Override
-        public void start() {
-            mRunning = true;
-            super.start();
-        }
-
-        boolean isRunning() {
-            return mRunning;
-        }
-
-        @SuppressWarnings({"InfiniteLoopStatement"})
-        @Override
-        public void run() {
-            try {
-                while (true) {
-                    try {
-                        cleanUp(mQueue.remove());
-                    } catch (InterruptedException e) {
-                        // Ignore
-                    }
-                }
-            } catch (Exception e) {
-                Log.e(LOG_TAG, "Reclaimer thread exiting: ", e);
-            } finally {
-                mRunning = false;
-            }
-        }
-
-        private void cleanUp(Reference<?> reference) {
-            do {
-                reference.clear();
-                ((ReclaimableReference<?>) reference).reclaim();
-            } while ((reference = mQueue.poll()) != null);
-        }
-    }
-}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 773d734..f0bb40d 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -34,11 +34,6 @@
 import android.text.SpannableString;
 import android.text.SpannedString;
 import android.text.TextUtils;
-import android.util.Finalizers;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * An implementation of Canvas on top of OpenGL ES 2.0.
@@ -46,7 +41,11 @@
 class GLES20Canvas extends HardwareCanvas {
     private final boolean mOpaque;
     private int mRenderer;
-    
+
+    // The native renderer will be destroyed when this object dies.
+    // DO NOT overwrite this reference once it is set.
+    private CanvasFinalizer mFinalizer;
+
     private int mWidth;
     private int mHeight;
     
@@ -78,7 +77,7 @@
         this(false, translucent);
     }
     
-    GLES20Canvas(boolean record, boolean translucent) {
+    protected GLES20Canvas(boolean record, boolean translucent) {
         mOpaque = !translucent;
 
         if (record) {
@@ -90,7 +89,7 @@
         if (mRenderer == 0) {
             throw new IllegalStateException("Could not create GLES20Canvas renderer");
         } else {
-            new CanvasFinalizer(this);
+            mFinalizer = new CanvasFinalizer(mRenderer);
         }
     }
 
@@ -99,22 +98,16 @@
 
     private static native void nDestroyRenderer(int renderer);
 
-    private static class CanvasFinalizer extends Finalizers.ReclaimableReference<GLES20Canvas> {
-        private static final Set<CanvasFinalizer> sFinalizers = Collections.synchronizedSet(
-                new HashSet<CanvasFinalizer>());
+    private static class CanvasFinalizer {
+        final int mRenderer;
 
-        private int mRenderer;
-
-        CanvasFinalizer(GLES20Canvas canvas) {
-            super(canvas, Finalizers.getQueue());
-            mRenderer = canvas.mRenderer;
-            sFinalizers.add(this);
+        CanvasFinalizer(int renderer) {
+            mRenderer = renderer;
         }
 
         @Override
-        public void reclaim() {
+        protected void finalize() throws Throwable {
             nDestroyRenderer(mRenderer);
-            sFinalizers.remove(this);
         }
     }
 
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index 11e6d30..adf08ea 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -16,12 +16,6 @@
 
 package android.view;
 
-import android.util.Finalizers;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
 /**
  * An implementation of display list for OpenGL ES 2.0.
  */
@@ -33,13 +27,18 @@
 
     int mNativeDisplayList;
 
+    // The native display list will be destroyed when this object dies.
+    // DO NOT overwrite this reference once it is set.
+    @SuppressWarnings("unused")
+    private DisplayListFinalizer mFinalizer;
+
     @Override
     HardwareCanvas start() {
         if (mStarted) {
             throw new IllegalStateException("Recording has already started");
         }
 
-        mCanvas = new GLES20Canvas(true, true);
+        mCanvas = new GLES20RecordingCanvas(true);
         mStarted = true;
         mRecorded = false;
 
@@ -53,7 +52,7 @@
             mRecorded = true;
 
             mNativeDisplayList = mCanvas.getDisplayList();
-            new DisplayListFinalizer(this);
+            mFinalizer = new DisplayListFinalizer(mNativeDisplayList);
         }
     }
 
@@ -62,22 +61,16 @@
         return !mStarted && mRecorded;
     }
 
-    private static class DisplayListFinalizer extends Finalizers.ReclaimableReference<DisplayList> {
-        private static final Set<DisplayListFinalizer> sFinalizers = Collections.synchronizedSet(
-                new HashSet<DisplayListFinalizer>());
+    private static class DisplayListFinalizer {
+        int mNativeDisplayList;
 
-        private int mNativeDisplayList;
-
-        DisplayListFinalizer(GLES20DisplayList displayList) {
-            super(displayList, Finalizers.getQueue());
-            mNativeDisplayList = displayList.mNativeDisplayList;
-            sFinalizers.add(this);
+        DisplayListFinalizer(int nativeDisplayList) {
+            mNativeDisplayList = nativeDisplayList;
         }
 
         @Override
-        public void reclaim() {
+        protected void finalize() throws Throwable {
             GLES20Canvas.destroyDisplayList(mNativeDisplayList);
-            sFinalizers.remove(this);
         }
     }
 }
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
new file mode 100644
index 0000000..bd14286
--- /dev/null
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -0,0 +1,273 @@
+/*
+ * 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 android.view;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Shader;
+
+import java.util.HashSet;
+
+/**
+ * An implementation of a GL canvas that records drawing operations.
+ * This is intended for use with a DisplayList. This class keeps a list of all the Paint and
+ * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
+ * the DisplayList is still holding a native reference to the memory.
+ */
+class GLES20RecordingCanvas extends GLES20Canvas {
+    // These lists ensure that any Bitmaps recorded by a DisplayList are kept alive as long
+    // as the DisplayList is alive.
+    private HashSet<Bitmap> mBitmaps = new HashSet<Bitmap>();
+
+    GLES20RecordingCanvas(boolean translucent) {
+        super(true, translucent);
+    }
+
+    private void recordShaderBitmap(Paint paint) {
+        if (paint != null) {
+            final Shader shader = paint.getShader();
+            if (shader instanceof BitmapShader) {
+                mBitmaps.add(((BitmapShader) shader).mBitmap);
+            }
+        }
+    }
+
+    @Override
+    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
+            Paint paint) {
+        super.drawArc(oval, startAngle, sweepAngle, useCenter, paint);
+    }
+
+    @Override
+    public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
+        super.drawPatch(bitmap, chunks, dst, paint);
+        mBitmaps.add(bitmap);
+        // Shaders in the Paint are ignored when drawing a Bitmap
+    }
+
+    @Override
+    public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
+        super.drawBitmap(bitmap, left, top, paint);
+        mBitmaps.add(bitmap);
+        // Shaders in the Paint are ignored when drawing a Bitmap
+    }
+
+    @Override
+    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
+        super.drawBitmap(bitmap, matrix, paint);
+        mBitmaps.add(bitmap);
+        // Shaders in the Paint are ignored when drawing a Bitmap
+    }
+
+    @Override
+    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
+        super.drawBitmap(bitmap, src, dst, paint);
+        mBitmaps.add(bitmap);
+        // Shaders in the Paint are ignored when drawing a Bitmap
+    }
+
+    @Override
+    public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
+        super.drawBitmap(bitmap, src, dst, paint);
+        mBitmaps.add(bitmap);
+        // Shaders in the Paint are ignored when drawing a Bitmap
+    }
+
+    @Override
+    public void drawBitmap(int[] colors, int offset, int stride, float x, float y, int width,
+            int height, boolean hasAlpha, Paint paint) {
+        super.drawBitmap(colors, offset, stride, x, y, width, height, hasAlpha, paint);
+        // Shaders in the Paint are ignored when drawing a Bitmap
+    }
+
+    @Override
+    public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width,
+            int height, boolean hasAlpha, Paint paint) {
+        super.drawBitmap(colors, offset, stride, x, y, width, height, hasAlpha, paint);
+        // Shaders in the Paint are ignored when drawing a Bitmap
+    }
+
+    @Override
+    public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
+            int vertOffset, int[] colors, int colorOffset, Paint paint) {
+        super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset,
+                paint);
+        mBitmaps.add(bitmap);
+        // Shaders in the Paint are ignored when drawing a Bitmap
+    }
+
+    @Override
+    public void drawCircle(float cx, float cy, float radius, Paint paint) {
+        super.drawCircle(cx, cy, radius, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
+        super.drawLine(startX, startY, stopX, stopY, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawLines(float[] pts, int offset, int count, Paint paint) {
+        super.drawLines(pts, offset, count, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawLines(float[] pts, Paint paint) {
+        super.drawLines(pts, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawOval(RectF oval, Paint paint) {
+        super.drawOval(oval, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawPaint(Paint paint) {
+        super.drawPaint(paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawPath(Path path, Paint paint) {
+        super.drawPath(path, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawPoint(float x, float y, Paint paint) {
+        super.drawPoint(x, y, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawPoints(float[] pts, int offset, int count, Paint paint) {
+        super.drawPoints(pts, offset, count, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawPoints(float[] pts, Paint paint) {
+        super.drawPoints(pts, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
+        super.drawPosText(text, index, count, pos, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawPosText(String text, float[] pos, Paint paint) {
+        super.drawPosText(text, pos, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
+        super.drawRect(left, top, right, bottom, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawRect(Rect r, Paint paint) {
+        super.drawRect(r, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawRect(RectF r, Paint paint) {
+        super.drawRect(r, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
+        super.drawRoundRect(rect, rx, ry, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
+        super.drawText(text, index, count, x, y, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
+        super.drawText(text, start, end, x, y, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawText(String text, int start, int end, float x, float y, Paint paint) {
+        super.drawText(text, start, end, x, y, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawText(String text, float x, float y, Paint paint) {
+        super.drawText(text, x, y, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
+            float vOffset, Paint paint) {
+        super.drawTextOnPath(text, index, count, path, hOffset, vOffset, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
+        super.drawTextOnPath(text, path, hOffset, vOffset, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
+            float x, float y, int dir, Paint paint) {
+        super.drawTextRun(text, index, count, contextIndex, contextCount, x, y, dir, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawTextRun(CharSequence text, int start, int end, int contextStart,
+            int contextEnd, float x, float y, int dir, Paint paint) {
+        super.drawTextRun(text, start, end, contextStart, contextEnd, x, y, dir, paint);
+        recordShaderBitmap(paint);
+    }
+
+    @Override
+    public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
+            float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
+            int indexOffset, int indexCount, Paint paint) {
+        super.drawVertices(mode, vertexCount, verts, vertOffset, texs, texOffset, colors,
+                colorOffset, indices, indexOffset, indexCount, paint);
+        recordShaderBitmap(paint);
+    }
+}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 97d7ad5..3a3d1d8 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -990,6 +990,22 @@
      */
     public static final int META_SCROLL_LOCK_ON = 0x400000;
 
+    /** {@hide} */
+    public static final int META_SHIFT_MASK = META_SHIFT_ON
+            | META_SHIFT_LEFT_ON | META_SHIFT_RIGHT_ON;
+
+    /** {@hide} */
+    public static final int META_ALT_MASK = META_ALT_ON
+            | META_ALT_LEFT_ON | META_ALT_RIGHT_ON;
+
+    /** {@hide} */
+    public static final int META_CTRL_MASK = META_CTRL_ON
+            | META_CTRL_LEFT_ON | META_CTRL_RIGHT_ON;
+
+    /** {@hide} */
+    public static final int META_META_MASK = META_ALT_ON
+            | META_META_LEFT_ON | META_META_RIGHT_ON;
+
     /**
      * This mask is set if the device woke because of this key event.
      */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 71d07c6..a4ad97b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5830,6 +5830,7 @@
                 mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
                 invalidate();
             }
+            mBackgroundSizeChanged = true;
         }
     }
 
@@ -5882,6 +5883,7 @@
                 mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
                 invalidate();
             }
+            mBackgroundSizeChanged = true;
         }
     }
 
@@ -5937,7 +5939,7 @@
                 mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
                 invalidate();
             }
-
+            mBackgroundSizeChanged = true;
         }
     }
 
@@ -5990,6 +5992,7 @@
                 mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
                 invalidate();
             }
+            mBackgroundSizeChanged = true;
         }
     }
 
@@ -7430,6 +7433,7 @@
             initialAwakenScrollBars();
             mPrivateFlags &= ~AWAKEN_SCROLL_BARS_ON_ATTACH;
         }
+        jumpDrawablesToCurrentState();
     }
 
     /**
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 281dd27..5d81702 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2626,6 +2626,16 @@
             return;
         }
 
+        // If the Control modifier is held, try to interpret the key as a shortcut.
+        if (event.getAction() == KeyEvent.ACTION_UP
+                && event.isCtrlPressed()
+                && !KeyEvent.isModifierKey(event.getKeyCode())) {
+            if (mView.dispatchKeyShortcutEvent(event)) {
+                finishKeyEvent(event, sendDone, true);
+                return;
+            }
+        }
+
         // Apply the fallback event policy.
         if (mFallbackEventHandler.dispatchKeyEvent(event)) {
             finishKeyEvent(event, sendDone, true);
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 867bb83..d310237 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -506,9 +506,10 @@
         }
     }
 
-    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi) {
+    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi,
+            boolean allowsImplicitlySelectedSubtypes) {
         try {
-            return mService.getEnabledInputMethodSubtypeList(imi);
+            return mService.getEnabledInputMethodSubtypeList(imi, allowsImplicitlySelectedSubtypes);
         } catch (RemoteException e) {
             throw new RuntimeException(e);
         }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9718443..8e4852a 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1013,14 +1013,15 @@
 
     private static void handleProxyBroadcast(Intent intent) {
         ProxyProperties proxyProperties = (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
-        if (proxyProperties == null) {
+        if (proxyProperties == null || proxyProperties.getHost() == null) {
             WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, "");
             return;
         }
 
         String host = proxyProperties.getHost();
         int port = proxyProperties.getPort();
-        host += ": " + port;
+        if (port != 0)
+            host += ": " + port;
 
         // TODO: Handle exclusion list
         // The plan is to make an AndroidProxyResolver, and handle the blacklist
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index e98c0bd..668490d 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -104,6 +104,14 @@
             }
         };
 
+        // mini-month day-picker
+        mMiniMonthDayPicker = (DayPicker) findViewById(R.id.mini_month_day_picker);
+        mMiniMonthDayPicker.setOnDateChangeListener(new DayPicker.OnSelectedDayChangeListener() {
+            public void onSelectedDayChange(DayPicker view, int year, int month, int monthDay) {
+                updateDateUnchecked(year, month, monthDay);
+            }
+        });
+
         // day
         mDayPicker = (NumberPicker) findViewById(R.id.day);
         mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
@@ -121,24 +129,11 @@
         mYearPicker.setOnLongPressUpdateInterval(100);
         mYearPicker.setOnChangeListener(onChangeListener);
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker);
-        int mStartYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
-        int mEndYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
-        mYearPicker.setRange(mStartYear, mEndYear);
+        int startYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
+        int endYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
+        setRange(startYear, endYear);
         a.recycle();
 
-        // mini-month day-picker
-        mMiniMonthDayPicker = (DayPicker) findViewById(R.id.mini_month_day_picker);
-        mTempCalendar.clear();
-        mTempCalendar.set(mStartYear, 0, 1);
-        Calendar endRangeDate = (Calendar) mTempCalendar.clone();
-        endRangeDate.set(mEndYear, 11, 31);
-        mMiniMonthDayPicker.setRange(mTempCalendar, endRangeDate);
-        mMiniMonthDayPicker.setOnDateChangeListener(new DayPicker.OnSelectedDayChangeListener() {
-            public void onSelectedDayChange(DayPicker view, int year, int month, int monthDay) {
-                updateDateUnchecked(year, month, monthDay);
-            }
-        });
-        
         // initialize to current date
         mTempCalendar.setTimeInMillis(System.currentTimeMillis());
         init(mTempCalendar.get(Calendar.YEAR), mTempCalendar.get(Calendar.MONTH),
@@ -148,6 +143,40 @@
         reorderPickers();
     }
 
+    /**
+     * Sets the range of years in which dates can be selected.
+     * <p>
+     * Note: If the range is set to a value that does not include the currently
+     * selected date the value of this picker will be updated to the closest
+     * date in the range.
+     * </p>
+     *
+     * @param startYear The start year of the range.
+     * @param endYear The end year of the range.
+     */
+    public void setRange(int startYear, int endYear) {
+        // set ranges of the widgets
+        mYearPicker.setRange(startYear, endYear);
+        mTempCalendar.clear();
+        Calendar startRangeDate = (Calendar) mTempCalendar.clone();
+        startRangeDate.set(startYear, 0, 1);
+        Calendar endRangeDate = (Calendar) mTempCalendar.clone();
+        endRangeDate.set(endYear, 11, 31);
+        mMiniMonthDayPicker.setRange(startRangeDate, endRangeDate);
+
+        // update state if current date is outside of the range
+        mTempCalendar.set(Calendar.YEAR, getYear());
+        mTempCalendar.set(Calendar.MONTH, getMonth());
+        mTempCalendar.set(Calendar.DAY_OF_MONTH, getDayOfMonth());
+        if (mTempCalendar.before(startRangeDate)) {
+            updateDate(startRangeDate.get(Calendar.YEAR), startRangeDate.get(Calendar.MONTH),
+                    startRangeDate.get(Calendar.DAY_OF_MONTH));
+        } else if (mTempCalendar.after(endRangeDate)) {
+            updateDate(endRangeDate.get(Calendar.YEAR), endRangeDate.get(Calendar.MONTH),
+                    endRangeDate.get(Calendar.DAY_OF_MONTH));
+        }
+    }
+
     @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
diff --git a/core/java/android/widget/DayPicker.java b/core/java/android/widget/DayPicker.java
index cdf51f7..02805be 100644
--- a/core/java/android/widget/DayPicker.java
+++ b/core/java/android/widget/DayPicker.java
@@ -366,22 +366,38 @@
      * @param endRangeDate The end date.
      */
     public void setRange(Calendar startRangeDate, Calendar endRangeDate) {
-        boolean doSetupAdapter = false;
+        boolean rangeChanged = false;
         if (mRangeStartDate.get(Calendar.DAY_OF_YEAR) != startRangeDate.get(Calendar.DAY_OF_YEAR)
                 || mRangeStartDate.get(Calendar.YEAR) != startRangeDate.get(Calendar.YEAR)) {
             mRangeStartDate.setTimeInMillis(startRangeDate.getTimeInMillis());
             mRangeStartDate.setTimeZone(startRangeDate.getTimeZone());
-            doSetupAdapter = true;
+            rangeChanged = true;
         }
         if (mRangeEndDate.get(Calendar.DAY_OF_YEAR) != endRangeDate.get(Calendar.DAY_OF_YEAR)
                 || mRangeEndDate.get(Calendar.YEAR) != endRangeDate.get(Calendar.YEAR)) {
             mRangeEndDate.setTimeInMillis(endRangeDate.getTimeInMillis());
             mRangeEndDate.setTimeZone(endRangeDate.getTimeZone());
-            doSetupAdapter = true;
-            
+            rangeChanged = true;
         }
-        if (doSetupAdapter) {
-            setUpAdapter();
+
+        if (!rangeChanged) {
+            return;
+        }
+
+        // now recreate the adapter since we have a new range to handle
+        mAdapter = null;
+        setUpAdapter();
+
+        // set the current date to today if in the range
+        // otherwise to the closest end of the range
+        mTempCalendar.clear();
+        mTempCalendar.setTimeInMillis(System.currentTimeMillis());
+        if (mTempCalendar.before(mRangeStartDate)) {
+            goTo(mRangeStartDate, false, true, true);
+        } else if (mTempCalendar.after(mRangeEndDate)) {
+            goTo(mRangeEndDate, false, true, true);
+        } else {
+            goTo(mTempCalendar, false, true, true);
         }
     }
 
@@ -629,7 +645,6 @@
         }
 
         // Figure out where we are
-        int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
         long currScroll = view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
 
         // If we have moved since our last call update the direction
@@ -645,6 +660,7 @@
         // causes the month to transition when two full weeks of a month are
         // visible when scrolling up, and when the first day in a month reaches
         // the top of the screen when scrolling down.
+        int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
         if (mIsScrollingUp) {
             child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset);
         } else if (offset != 0) {
@@ -712,8 +728,9 @@
             throw new IllegalArgumentException("fromDate: " + mRangeStartDate.getTime()
                     + " does not precede toDate: " + toDate.getTime());
         }
+
         int fromDateDayOfWeek = mRangeStartDate.get(Calendar.DAY_OF_WEEK);
-        long diff = (fromDateDayOfWeek - toDate.getFirstDayOfWeek()) * MILLIS_IN_DAY;
+        long diff = (fromDateDayOfWeek - mFirstDayOfWeek) * MILLIS_IN_DAY;
         if (diff < 0) {
             diff = diff + MILLIS_IN_WEEK;
         }
@@ -874,7 +891,16 @@
         protected void init() {
             mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
             mSelectedWeek = getWeeksDelta(mSelectedDay);
-            mTotalWeekCount = getWeeksDelta(mRangeEndDate);
+
+            // make adjustment to fit the range last week with needed overflow
+            mTempCalendar.setTimeInMillis(mRangeEndDate.getTimeInMillis());
+            mTempCalendar.setTimeZone(mRangeEndDate.getTimeZone());
+            int diff = mFirstDayOfWeek - mRangeEndDate.get(Calendar.DAY_OF_WEEK);
+            if (diff < 0) {
+                diff += DAYS_PER_WEEK;
+            }
+            mTempCalendar.add(Calendar.DAY_OF_WEEK, diff);
+            mTotalWeekCount = getWeeksDelta(mTempCalendar);
         }
 
         /**
@@ -892,7 +918,6 @@
             mSelectedWeek = getWeeksDelta(mSelectedDay);
             mFocusMonth = mSelectedDay.get(Calendar.MONTH);
             notifyDataSetChanged();
-            invalidate();  // Test
         }
 
         /**
@@ -1004,9 +1029,12 @@
             if (mGestureDetector.onTouchEvent(event)) {
                 WeekView weekView = (WeekView) v;
                 weekView.getDayFromLocation(event.getX(), mTempCalendar);
-                if (mTempCalendar.get(Calendar.YEAR) != 0) {
-                    onDayTapped(mTempCalendar);
+                // it is possible that the touched day is outside the valid range
+                // we draw whole weeks but range end can fall not on the week end
+                if (mTempCalendar.before(mRangeStartDate) || mTempCalendar.after(mRangeEndDate)) {
+                    return true;
                 }
+                onDayTapped(mTempCalendar);
                 return true;
             }
             return false;
@@ -1019,6 +1047,7 @@
          */
         protected void onDayTapped(Calendar day) {
             setSelectedDay(day);
+            setMonthDisplayed(day);
         }
 
         /**
@@ -1244,8 +1273,8 @@
                 mNumCells = mShowWeekNumber ? mWeekDayCount + 1 : mWeekDayCount;
             }
             mWeek = ((int[]) params.get(VIEW_PARAMS_WEEK))[0];
-            mTempCalendar.clear();
-            mTempCalendar.set(1900, 0, 1);
+            mTempCalendar.setTimeInMillis(mRangeStartDate.getTimeInMillis());
+            mTempCalendar.setTimeZone(mRangeStartDate.getTimeZone());
             mTempCalendar.add(Calendar.WEEK_OF_YEAR, mWeek);
             if (params.containsKey(VIEW_PARAMS_WEEK_START)) {
                 mTempCalendar.setFirstDayOfWeek(((int[]) params.get(VIEW_PARAMS_WEEK_START))[0]);
@@ -1277,7 +1306,12 @@
 
             for (; i < mNumCells; i++) {
                 mFocusDay[i] = (mTempCalendar.get(Calendar.MONTH) == focusMonth);
-                mDayNumbers[i] = Integer.toString(mTempCalendar.get(Calendar.DAY_OF_MONTH));
+                // do not draw dates outside the valid range to avoid user confusion
+                if (mTempCalendar.before(mRangeStartDate) || mTempCalendar.after(mRangeEndDate)) {
+                    mDayNumbers[i] = "";
+                } else {
+                    mDayNumbers[i] = Integer.toString(mTempCalendar.get(Calendar.DAY_OF_MONTH));
+                }
                 mTempCalendar.add(Calendar.DAY_OF_MONTH, 1);
             }
             // We do one extra add at the end of the loop, if that pushed us to
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 8c22f97..a236d27 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1189,9 +1189,9 @@
      */
     private int getWrappedSelectorIndex(int selectorIndex) {
         if (selectorIndex > mEnd) {
-            return mStart + (selectorIndex - mEnd) % (mEnd - mStart);
+            return mStart + (selectorIndex - mEnd) % (mEnd - mStart) - 1;
         } else if (selectorIndex < mStart) {
-            return mEnd - (mStart - selectorIndex) % (mEnd - mStart);
+            return mEnd - (mStart - selectorIndex) % (mEnd - mStart) + 1;
         }
         return selectorIndex;
     }
diff --git a/core/java/android/widget/SimpleCursorAdapter.java b/core/java/android/widget/SimpleCursorAdapter.java
index 497610c..3d2a252 100644
--- a/core/java/android/widget/SimpleCursorAdapter.java
+++ b/core/java/android/widget/SimpleCursorAdapter.java
@@ -337,10 +337,11 @@
     }
 
     @Override
-    public void changeCursor(Cursor c) {
-        super.changeCursor(c);
+    public Cursor swapCursor(Cursor c) {
+        Cursor res = super.swapCursor(c);
         // rescan columns in case cursor layout is different
         findColumns(mOriginalFrom);
+        return res;
     }
     
     /**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 052760f..aa2e68f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -81,6 +81,7 @@
 import android.text.method.TextKeyListener;
 import android.text.method.TimeKeyListener;
 import android.text.method.TransformationMethod;
+import android.text.style.ClickableSpan;
 import android.text.style.ParagraphStyle;
 import android.text.style.URLSpan;
 import android.text.style.UpdateAppearance;
@@ -7238,6 +7239,19 @@
                 handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
             }
 
+            if (mLinksClickable && mAutoLinkMask != 0 && mTextIsSelectable &&
+                    action == MotionEvent.ACTION_UP && !mIgnoreActionUpEvent && isFocused()) {
+                // The LinkMovementMethod which should handle taps on links has not been installed
+                // to support text selection. We reproduce its behavior here to open links.
+                ClickableSpan[] links = ((Spannable) mText).getSpans(getSelectionStart(),
+                        getSelectionEnd(), ClickableSpan.class);
+
+                if (links.length != 0) {
+                    links[0].onClick(this);
+                    handled = true;
+                }
+            }
+
             if (isTextEditable() || mTextIsSelectable) {
                 if (mScrollX != oldScrollX || mScrollY != oldScrollY) {
                     // Hide insertion anchor while scrolling. Leave selection.
@@ -7516,36 +7530,31 @@
 
     @Override
     public boolean onKeyShortcut(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-        case KeyEvent.KEYCODE_A:
-            if (canSelectText()) {
-                return onTextContextMenuItem(ID_SELECT_ALL);
+        final int filteredMetaState = event.getMetaState() & ~KeyEvent.META_CTRL_MASK;
+        if (KeyEvent.metaStateHasNoModifiers(filteredMetaState)) {
+            switch (keyCode) {
+            case KeyEvent.KEYCODE_A:
+                if (canSelectText()) {
+                    return onTextContextMenuItem(ID_SELECT_ALL);
+                }
+                break;
+            case KeyEvent.KEYCODE_X:
+                if (canCut()) {
+                    return onTextContextMenuItem(ID_CUT);
+                }
+                break;
+            case KeyEvent.KEYCODE_C:
+                if (canCopy()) {
+                    return onTextContextMenuItem(ID_COPY);
+                }
+                break;
+            case KeyEvent.KEYCODE_V:
+                if (canPaste()) {
+                    return onTextContextMenuItem(ID_PASTE);
+                }
+                break;
             }
-
-            break;
-
-        case KeyEvent.KEYCODE_X:
-            if (canCut()) {
-                return onTextContextMenuItem(ID_CUT);
-            }
-
-            break;
-
-        case KeyEvent.KEYCODE_C:
-            if (canCopy()) {
-                return onTextContextMenuItem(ID_COPY);
-            }
-
-            break;
-
-        case KeyEvent.KEYCODE_V:
-            if (canPaste()) {
-                return onTextContextMenuItem(ID_PASTE);
-            }
-
-            break;
         }
-
         return super.onKeyShortcut(keyCode, event);
     }
 
@@ -7875,7 +7884,9 @@
 
     /**
      * Called when a context menu option for the text view is selected.  Currently
-     * this will be {@link android.R.id#copyUrl} or {@link android.R.id#selectTextMode}.
+     * this will be {@link android.R.id#copyUrl}, {@link android.R.id#selectTextMode},
+     * {@link android.R.id#selectAll}, {@link android.R.id#paste}, {@link android.R.id#cut}
+     * or {@link android.R.id#copy}.
      */
     public boolean onTextContextMenuItem(int id) {
         int min = 0;
@@ -7920,8 +7931,32 @@
                     startSelectionActionMode();
                 }
                 return true;
-            }
 
+            case ID_SELECT_ALL:
+                selectAll();
+                // Update controller positions after selection change.
+                if (hasSelectionController()) {
+                    getSelectionController().show();
+                }
+                return true;
+
+            case ID_PASTE:
+                paste(min, max);
+                return true;
+
+            case ID_CUT:
+                setPrimaryClip(ClipData.newPlainText(null, null,
+                        mTransformed.subSequence(min, max)));
+                ((Editable) mText).delete(min, max);
+                stopSelectionActionMode();
+                return true;
+
+            case ID_COPY:
+                setPrimaryClip(ClipData.newPlainText(null, null,
+                        mTransformed.subSequence(min, max)));
+                stopSelectionActionMode();
+                return true;
+        }
         return false;
     }
 
@@ -8278,49 +8313,7 @@
                  mCustomSelectionActionModeCallback.onActionItemClicked(mode, item)) {
                 return true;
             }
-
-            final int itemId = item.getItemId();
-
-            if (itemId == ID_SELECT_ALL) {
-                selectAll();
-                // Update controller positions after selection change.
-                if (hasSelectionController()) {
-                    getSelectionController().show();
-                }
-                return true;
-            }
-
-            int min = 0;
-            int max = mText.length();
-
-            if (isFocused()) {
-                final int selStart = getSelectionStart();
-                final int selEnd = getSelectionEnd();
-
-                min = Math.max(0, Math.min(selStart, selEnd));
-                max = Math.max(0, Math.max(selStart, selEnd));
-            }
-
-            switch (item.getItemId()) {
-                case ID_PASTE:
-                    paste(min, max);
-                    return true;
-
-                case ID_CUT:
-                    setPrimaryClip(ClipData.newPlainText(null, null,
-                            mTransformed.subSequence(min, max)));
-                    ((Editable) mText).delete(min, max);
-                    stopSelectionActionMode();
-                    return true;
-
-                case ID_COPY:
-                    setPrimaryClip(ClipData.newPlainText(null, null,
-                            mTransformed.subSequence(min, max)));
-                    stopSelectionActionMode();
-                    return true;
-            }
-
-            return false;
+            return onTextContextMenuItem(item.getItemId());
         }
 
         @Override
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 18e1b45..f58f261 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -24,7 +24,6 @@
 import android.os.Process;
 import android.os.SystemProperties;
 import android.util.Config;
-import android.util.Finalizers;
 import android.util.Log;
 import android.util.Slog;
 
@@ -142,12 +141,6 @@
             Debug.enableEmulatorTraceOutput();
         }
 
-        /**
-         * Initialize the thread used to reclaim resources without
-         * going through finalizers.
-         */
-        Finalizers.init();
-
         initialized = true;
     }
 
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 215809f..b2fbd3a7 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -31,7 +31,8 @@
 interface IInputMethodManager {
     List<InputMethodInfo> getInputMethodList();
     List<InputMethodInfo> getEnabledInputMethodList();
-    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in InputMethodInfo imi);
+    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in InputMethodInfo imi,
+            boolean allowsImplicitlySelectedSubtypes);
     // TODO: We should change the return type from List to List<Parcelable>
     // Currently there is a bug that aidl doesn't accept List<Parcelable>
     List getShortcutInputMethodsAndSubtypes();
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index fad9539..c4cd2a6 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -50,13 +50,14 @@
     return GET_WINDOW(env, javaWindow);
 }
 
-static void native_init_empty(JNIEnv * env, jobject object, jboolean localOnly)
+static void native_init_empty(JNIEnv * env, jobject object, jint cursorWindowSize,
+        jboolean localOnly)
 {
     uint8_t * data;
     size_t size;
     CursorWindow * window;
 
-    window = new CursorWindow(MAX_WINDOW_SIZE);
+    window = new CursorWindow(cursorWindowSize);
     if (!window) {
         jniThrowException(env, "java/lang/RuntimeException", "No memory for native window object");
         return;
@@ -614,7 +615,7 @@
 static JNINativeMethod sMethods[] =
 {
      /* name, signature, funcPtr */
-    {"native_init", "(Z)V", (void *)native_init_empty},
+    {"native_init", "(IZ)V", (void *)native_init_empty},
     {"native_init", "(Landroid/os/IBinder;)V", (void *)native_init_memory},
     {"native_getBinder", "()Landroid/os/IBinder;", (void *)native_getBinder},
     {"native_clear", "()V", (void *)native_clear},
diff --git a/core/jni/android_database_SQLiteDatabase.cpp b/core/jni/android_database_SQLiteDatabase.cpp
index 7aeed98..a5878a9 100644
--- a/core/jni/android_database_SQLiteDatabase.cpp
+++ b/core/jni/android_database_SQLiteDatabase.cpp
@@ -46,7 +46,6 @@
 
 #define UTF16_STORAGE 0
 #define INVALID_VERSION -1
-#define SQLITE_SOFT_HEAP_LIMIT (4 * 1024 * 1024)
 #define ANDROID_TABLE "android_metadata"
 /* uncomment the next line to force-enable logging of all statements */
 // #define DB_LOG_STATEMENTS
@@ -66,6 +65,7 @@
 static jfieldID offset_db_handle;
 static jmethodID method_custom_function_callback;
 static jclass string_class = NULL;
+static jint sSqliteSoftHeapLimit = 0;
 
 static char *createStr(const char *path, short extra) {
     int len = strlen(path) + extra;
@@ -129,7 +129,7 @@
     // The soft heap limit prevents the page cache allocations from growing
     // beyond the given limit, no matter what the max page cache sizes are
     // set to. The limit does not, as of 3.5.0, affect any other allocations.
-    sqlite3_soft_heap_limit(SQLITE_SOFT_HEAP_LIMIT);
+    sqlite3_soft_heap_limit(sSqliteSoftHeapLimit);
 
     // Set the default busy handler to retry for 1000ms and then return SQLITE_BUSY
     err = sqlite3_busy_timeout(handle, 1000 /* ms */);
@@ -379,10 +379,14 @@
     if (meta != NULL) sqlite3_free_table(meta);
 }
 
+static void native_setSqliteSoftHeapLimit(JNIEnv* env, jobject clazz, jint limit) {
+    sSqliteSoftHeapLimit = limit;
+}
+
 static jint native_releaseMemory(JNIEnv *env, jobject clazz)
 {
     // Attempt to release as much memory from the
-    return sqlite3_release_memory(SQLITE_SOFT_HEAP_LIMIT);
+    return sqlite3_release_memory(sSqliteSoftHeapLimit);
 }
 
 static void native_finalize(JNIEnv* env, jobject object, jint statementId)
@@ -466,6 +470,7 @@
     {"enableSqlProfiling", "(Ljava/lang/String;S)V", (void *)enableSqlProfiling},
     {"native_setLocale", "(Ljava/lang/String;I)V", (void *)native_setLocale},
     {"native_getDbLookaside", "()I", (void *)native_getDbLookaside},
+    {"native_setSqliteSoftHeapLimit", "(I)V", (void *)native_setSqliteSoftHeapLimit},
     {"releaseMemory", "()I", (void *)native_releaseMemory},
     {"native_finalize", "(I)V", (void *)native_finalize},
     {"native_addCustomFunction",
diff --git a/core/res/assets/webkit/youtube.html b/core/res/assets/webkit/youtube.html
index 289f8cf..d808bcf 100644
--- a/core/res/assets/webkit/youtube.html
+++ b/core/res/assets/webkit/youtube.html
@@ -38,19 +38,29 @@
                 // All images are loaded, so display them.
                 // (Note that the images are loaded from javascript, so might load
                 // after document.onload fires)
-                ctx.drawImage(background, 0, 0, width, height);
+
                 playWidth = play.width;
                 playHeight = play.height;
                 logoWidth = logo.width;
                 logoHeight = logo.height;
                 var ratio = 1;
                 // If the page is smaller than it 'should' be in either dimension
-                // we scale the play button and logo according to the dimension that
-                // has been shrunk the most.
+                // we scale the background, play button and logo according to the
+                // dimension that has been shrunk the most.
                 if (width / height > defWidth / defHeight && height < defHeight) {
                     ratio = height / defHeight;
+                    // Stretch the background in this dimension only.
+                    backgroundHeight = background.height / ratio;
+                    ctx.drawImage(background, 0, 0, background.width, background.height,
+                        0, (height - backgroundHeight) / 2, width, backgroundHeight);
                 } else if (width / height < defWidth / defHeight && width < defWidth) {
                     ratio = width / defWidth;
+                    backgroundWidth = background.width / ratio;
+                    ctx.drawImage(background, 0, 0, background.width, background.height,
+                        (width - backgroundWidth) / 2, 0, backgroundWidth, height);
+                } else {
+                    // In this case stretch the background in both dimensions to fill the space.
+                    ctx.drawImage(background, 0, 0, width, height);
                 }
                 playWidth *= ratio;
                 playHeight *= ratio;
diff --git a/core/res/res/layout-xlarge/preference_list_content_single.xml b/core/res/res/layout-xlarge/preference_list_content_single.xml
index 6899ed0..6725996 100644
--- a/core/res/res/layout-xlarge/preference_list_content_single.xml
+++ b/core/res/res/layout-xlarge/preference_list_content_single.xml
@@ -30,18 +30,14 @@
 
         <LinearLayout
             android:id="@+id/headers"
+            style="?attr/preferencePanelStyle"
             android:orientation="vertical"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_marginRight="@dimen/preference_screen_side_margin"
-            android:layout_marginLeft="@dimen/preference_screen_side_margin"
-            android:layout_marginTop="48dp"
-            android:layout_marginBottom="48dp"
             android:paddingLeft="32dip"
             android:paddingRight="32dip"
             android:paddingTop="32dip"
-            android:paddingBottom="32dip"
-            android:background="?attr/preferencePanelBackground">
+            android:paddingBottom="32dip" >
 
             <ListView android:id="@android:id/list"
                 android:layout_width="match_parent"
diff --git a/core/res/res/values-large/themes.xml b/core/res/res/values-large/themes.xml
index 12257a1..f5c35f6 100644
--- a/core/res/res/values-large/themes.xml
+++ b/core/res/res/values-large/themes.xml
@@ -19,9 +19,11 @@
 <resources>
     <style name="Theme.Holo.DialogWhenLarge"
             parent="@android:style/Theme.Holo.Dialog">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
     </style>
     <style name="Theme.Holo.DialogWhenLarge.NoActionBar"
             parent="@android:style/Theme.Holo.Dialog.NoActionBar">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
     </style>
     <style name="Theme.Holo.Light.DialogWhenLarge"
             parent="@android:style/Theme.Holo.Light.Dialog">
diff --git a/core/res/res/values-xlarge/styles.xml b/core/res/res/values-xlarge/styles.xml
index 095a83d..489e530 100644
--- a/core/res/res/values-xlarge/styles.xml
+++ b/core/res/res/values-xlarge/styles.xml
@@ -34,5 +34,13 @@
     <style name="TextAppearance.StatusBar.EventContent.Title">
         <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
+
+    <style name="PreferencePanel">
+        <item name="android:layout_marginLeft">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginRight">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginTop">48dip</item>
+        <item name="android:layout_marginBottom">48dip</item>
+        <item name="android:background">?attr/preferencePanelBackground</item>
+    </style>
 </resources>
 
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9598f96..36830ce 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -606,6 +606,8 @@
         <attr name="preferenceLayoutChild" format="reference" />
         <!-- Preference panel background -->
         <attr name="preferencePanelBackground" format="reference" />
+        <!-- Preference panel style -->
+        <attr name="preferencePanelStyle" format="reference" />
 
         <!-- ============================ -->
         <!-- Text selection handle styles -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0d2d42f..8edea0d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -214,6 +214,14 @@
          rotations as the default behavior. -->
     <bool name="config_allowAllRotations">true</bool>
 
+    <!-- If true, the direction rotation is applied to get to an application's requested
+         orientation is reversed.  Normally, the model is that landscape is
+         clockwise from portrait; thus on a portrait device an app requesting
+         landscape will cause a clockwise rotation, and on a landscape device an
+         app requesting portrait will cause a counter-clockwise rotation.  Setting
+         true here reverses that logic. -->
+    <bool name="config_reverseDefaultRotation">false</bool>
+
     <!-- The number of degrees to rotate the display when the keyboard is open. -->
     <integer name="config_lidOpenRotation">90</integer>
 
@@ -515,4 +523,7 @@
          Build.MODEL. The format string shall not be escaped. -->
     <string name="config_useragentprofile_url"></string>
 
+    <!-- When a database query is executed, the results retuned are paginated
+         in pages of size (in KB) indicated by this value -->
+    <integer name="config_cursorWindowSize">2048</integer>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 9e21111..9c28922 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -915,6 +915,20 @@
         <item name="android:widgetLayout">@android:layout/preference_dialog</item>
     </style>
 
+    <!-- No margins or background by default. Could be different for x-large screens -->
+    <style name="PreferencePanel">
+    </style>
+
+    <!-- The attributes are overridden here because the x-large or large resources may have
+         changed the margins and background in the parent PreferencePanel style. -->
+    <style name="PreferencePanel.Dialog">
+        <item name="android:layout_marginLeft">0dip</item>
+        <item name="android:layout_marginRight">0dip</item>
+        <item name="android:layout_marginTop">0dip</item>
+        <item name="android:layout_marginBottom">0dip</item>
+        <item name="android:background">@null</item>
+    </style>
+
     <!-- Other Misc Styles -->
     <eat-comment />
 
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 87029ef..1bbe22e 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -234,6 +234,7 @@
         <item name="editTextPreferenceStyle">@android:style/Preference.DialogPreference.EditTextPreference</item>
         <item name="ringtonePreferenceStyle">@android:style/Preference.RingtonePreference</item>
         <item name="preferenceLayoutChild">@android:layout/preference_child</item>
+        <item name="preferencePanelStyle">@style/PreferencePanel</item>
         <item name="preferencePanelBackground">@android:drawable/panel_bg_holo_dark</item>
 
         <!-- Search widget styles -->
@@ -1306,7 +1307,7 @@
          (large, xlarge). -->
     <style name="Theme.Holo.DialogWhenLarge.NoActionBar" parent="@android:style/Theme.Holo.NoActionBar">
     </style>
-    
+
     <!-- Light holo dialog themes -->
 
     <!-- Holo light theme for dialog windows and activities, which is used by the
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index af74c6f..3d5588c 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -22,6 +22,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Bundle;
+import android.os.IPowerManager;
+import android.os.PowerManager;
+import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -460,6 +464,26 @@
         return mWifiManager.setWifiEnabled(true);
     }
 
+    // Turn screen off
+    public void turnScreenOff() {
+        log("Turn screen off");
+        PowerManager pm =
+            (PowerManager) getSystemService(Context.POWER_SERVICE);
+        pm.goToSleep(SystemClock.uptimeMillis() + 100);
+    }
+
+    // Turn screen on
+    public void turnScreenOn() {
+        log("Turn screen on");
+        IPowerManager mPowerManagerService = IPowerManager.Stub.asInterface(
+                ServiceManager.getService("power"));;
+        try {
+            mPowerManagerService.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
+        } catch (Exception e) {
+            log(e.toString());
+        }
+    }
+
     /**
      * Associate the device to given SSID
      * If the device is already associated with a WiFi, disconnect and forget it,
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 2ac7265..ea79f8c 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -26,7 +26,10 @@
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
 import android.net.wifi.WifiManager;
 import android.os.Environment;
+import android.os.IPowerManager;
 import android.os.PowerManager;
+import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
@@ -46,7 +49,6 @@
     private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
     private ConnectivityManagerTestActivity mAct;
     private int iterations;
-    private PowerManager.WakeLock mWakelock = null;
     private BufferedWriter mOutputWriter = null;
     private int mLastIteration = 0;
 
@@ -61,17 +63,11 @@
         ConnectivityManagerStressTestRunner mRunner =
             (ConnectivityManagerStressTestRunner)getInstrumentation();
         iterations = mRunner.mSoftapIterations;
-        PowerManager pm =
-            (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
-        mWakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "wifiApStress");
-        mWakelock.acquire();
+        mAct.turnScreenOn();
     }
 
     @Override
     public void tearDown() throws Exception {
-        if (mWakelock != null) {
-            mWakelock.release();
-        }
         // write the total number of iterations into output file
         mOutputWriter = new BufferedWriter(new FileWriter(new File(
                 Environment.getExternalStorageDirectory(), OUTPUT_FILE)));
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 7914417..ae009ca 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -30,7 +30,9 @@
 import android.net.wifi.WifiManager;
 import android.os.Environment;
 import android.os.PowerManager;
+import android.os.IPowerManager;
 import android.os.SystemClock;
+import android.os.ServiceManager;
 import android.provider.Settings;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
@@ -57,7 +59,7 @@
     /**
      * Wi-Fi idle time for default sleep policy
      */
-    private final static long WIFI_IDLE_MS = 5 * 1000;
+    private final static long WIFI_IDLE_MS = 60 * 1000;
 
     /**
      * The delay for Wi-Fi to get into idle, after screen off + WIFI_IDEL_MS + WIFI_IDLE_DELAY
@@ -73,7 +75,6 @@
     private String mSsid;
     private String mPassword;
     private ConnectivityManagerStressTestRunner mRunner;
-    private PowerManager.WakeLock wl = null;
     private BufferedWriter mOutputWriter = null;
 
     public WifiStressTest() {
@@ -90,10 +91,11 @@
         mPassword = mRunner.mReconnectPassword;
         mScanIterations = mRunner.mScanIterations;
         mWifiSleepTime = mRunner.mSleepTime;
-        wl = null;
         mOutputWriter = new BufferedWriter(new FileWriter(new File(
                 Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
+        mAct.turnScreenOn();
         if (!mAct.mWifiManager.isWifiEnabled()) {
+            log("Enable wi-fi before stress tests.");
             if (!mAct.enableWifi()) {
                 tearDown();
                 fail("enable wifi failed.");
@@ -106,9 +108,6 @@
     @Override
     public void tearDown() throws Exception {
         log("tearDown()");
-        if ((wl != null) && wl.isHeld()) {
-            wl.release();
-        }
         if (mOutputWriter != null) {
             mOutputWriter.close();
         }
@@ -129,26 +128,6 @@
         }
     }
 
-    private void turnScreenOff() {
-        log("Turn screen off");
-        if (wl != null) {
-            log("release wake lock");
-            wl.release();
-        }
-        PowerManager pm =
-            (PowerManager) mRunner.getContext().getSystemService(Context.POWER_SERVICE);
-        pm.goToSleep(SystemClock.uptimeMillis() + 50);
-    }
-
-    private void turnScreenOn() {
-        log("Turn screen on");
-        PowerManager pm =
-            (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
-        wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
-                "wifiStressTest");
-        wl.acquire();
-    }
-
     public void log(String message) {
         Log.v(TAG, message);
     }
@@ -247,7 +226,6 @@
                 Settings.Secure.WIFI_IDLE_MS, WIFI_IDLE_MS);
 
         // Connect to a Wi-Fi network
-        turnScreenOn();
         WifiConfiguration config = new WifiConfiguration();
         config.SSID = mSsid;
         config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
@@ -267,26 +245,34 @@
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
         int i;
         for (i = 0; i < mReconnectIterations; i++) {
-            // 1. Put device into sleep
-            // 2. Wait for the device to sleep for sometime, very 3G is connected
-            // 3. Wake up the device
+            // 1. Put device into sleep mode
+            // 2. Wait for the device to sleep for sometime, verify wi-fi is off and mobile is on.
+            // 3. Maintain the sleep mode for some time,
+            // 4. Verify the Wi-Fi is still off, and data is on
+            // 5. Wake up the device, verify Wi-Fi is enabled and connected.
             writeOutput(String.format("iteration %d out of %d",
                     i, mReconnectIterations));
             log("iteration: " + i);
-            turnScreenOff();
+            mAct.turnScreenOff();
             PowerManager pm =
                 (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
             assertFalse(pm.isScreenOn());
-            sleep(WIFI_IDLE_MS + WIFI_IDLE_DELAY, "Interruped while wait for wifi to be idle");
+            sleep(WIFI_IDLE_MS, "Interruped while wait for wifi to be idle");
             assertTrue("Wait for Wi-Fi to idle timeout",
                     mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
-                    ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+                    6 * ConnectivityManagerTestActivity.SHORT_TIMEOUT));
+            // use long timeout as the pppd startup may take several retries.
             assertTrue("Wait for cellular connection timeout",
                     mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
                     ConnectivityManagerTestActivity.LONG_TIMEOUT));
             sleep(mWifiSleepTime + WIFI_IDLE_DELAY, "Interrupted while device is in sleep mode");
+            // Verify the wi-fi is still off and data connection is on
+            assertEquals("Wi-Fi is reconnected", State.DISCONNECTED,
+                    mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
+            assertEquals("Cellular connection is down", State.CONNECTED,
+                    mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
             // Turn screen on again
-            turnScreenOn();
+            mAct.turnScreenOn();
             assertTrue("Wait for Wi-Fi enable timeout after wake up",
                     mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                     ConnectivityManagerTestActivity.SHORT_TIMEOUT));
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index f2857fa..72120a8 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -4,9 +4,9 @@
      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.
@@ -117,7 +117,7 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.focus.FocusAfterRemoval" android:label="FocusAfterRemoval">
@@ -145,28 +145,28 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.focus.ListOfEditTexts" android:label="ListOfEditTexts">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.focus.ListOfInternalSelectionViews" android:label="ListOfInternalSelectionViews">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>                        
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.focus.ListWithFooterViewAndNewLabels" android:label="FocusListWithFooter">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.focus.ListWithMailMessages" android:label="ListWithMailMessages">
@@ -180,7 +180,7 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.focus.VerticalFocusSearch" android:label="VerticalFocusSearch">
@@ -257,7 +257,7 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.layout.linear.LLOfButtons1" android:label="LLOfButtons1">
@@ -285,7 +285,7 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.layout.linear.Weight" android:label="Weight">
@@ -483,7 +483,7 @@
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.view.PreDrawListener" android:label="PreDrawListener">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -518,7 +518,7 @@
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.listview.ListScrollListener" android:label="ListScrollListener">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -532,21 +532,21 @@
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.listview.ListTakeFocusFromSide" android:label="ListTakeFocusFromSide">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.listview.ListBottomGravity" android:label="ListBottomGravity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.listview.ListBottomGravityMany" android:label="ListBottomGravityMany">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -568,19 +568,19 @@
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.listview.ListTopGravityMany" android:label="ListTopGravityMany">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.listview.ListEndingWithMultipleSeparators" android:label="ListEndingWithMultipleSeparators">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>                        
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListGetSelectedView" android:label="ListGetSelectedView">
@@ -615,21 +615,21 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListOfItemsTallerThanScreen" android:label="ListOfItemsTallerThanScreen">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListOfThinItems" android:label="ListOfThinItems">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>                        
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListOfShortTallShort" android:label="ListOfShortTallShort">
@@ -643,14 +643,14 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListWithOffScreenNextSelectable" android:label="ListWithOffScreenNextSelectable">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>                                    
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListWithFirstScreenUnSelectable" android:label="ListWithFirstScreenUnSelectable">
@@ -665,7 +665,7 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListWithHeaders" android:label="ListWithHeaders">
@@ -686,14 +686,14 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListWithScreenOfNoSelectables" android:label="ListWithScreenOfNoSelectables">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListItemFocusablesFarApart" android:label="ListItemFocusablesFarApart">
@@ -721,21 +721,21 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListItemsExpandOnSelection" android:label="ListItemsExpandOnSelection">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListWithOnItemSelectedAction" android:label="ListWithOnItemSelectedAction">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
 
         <activity android:name="android.widget.listview.ListItemISVAndButton" android:label="ListItemISVAndButton">
@@ -770,30 +770,30 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
-       
+
 	    <activity android:name="android.widget.listview.ListManagedCursor" android:label="ListManagedCursor">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-       
+
 	    <activity android:name="android.widget.listview.ListWithEmptyView" android:label="ListWithEmptyView">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.gridview.GridInHorizontal" android:label="GridInHorizontal">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.gridview.GridPadding" android:label="GridPadding">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -884,21 +884,21 @@
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.gridview.GridVerticalSpacingStackFromBottom" android:label="GridVerticalSpacingStackFromBottom">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.gridview.GridSingleColumn" android:label="GridSingleColumn">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.view.menu.ListContextMenu" android:label="ListContextMenu">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1012,7 +1012,7 @@
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
-        
+
         <activity android:name="android.widget.AutoCompleteTextViewSimple"
                   android:label="AutoCompleteTextViewSimple">
             <intent-filter>
@@ -1037,9 +1037,9 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>            
+            </intent-filter>
         </activity>
-        
+
 
 
         <!-- Activity-level metadata -->
@@ -1052,13 +1052,6 @@
         <meta-data android:name="com.android.frameworks.coretests.reference"
                    android:resource="@xml/metadata_app" />
 
-        <activity android:name="AndroidPerformanceTests" android:label="Android Performance Tests">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.UNIT_TEST" />
-            </intent-filter>
-        </activity>
-
         <!-- Application components used for activity tests -->
 
         <activity android:name="android.app.activity.TestedActivity"
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index 4ba679b..f74d0ef 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -23,9 +23,10 @@
 public class BitmapShader extends Shader {
     /**
      * Prevent garbage collection.
+     * @hide
      */
     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
-    private final Bitmap mBitmap;
+    public final Bitmap mBitmap;
 
     /**
      * Call this to create a new shader that will draw with a bitmap.
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 3ff483d..0dbc204 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -102,12 +102,6 @@
         mRS.nAllocationSyncAll(getID(), srcLocation);
     }
 
-    public void uploadToBufferObject() {
-        mRS.validate();
-        mRS.nAllocationUploadToBufferObject(getID());
-    }
-
-
     public void copyFrom(BaseObj[] d) {
         mRS.validate();
         if (d.length != mType.getCount()) {
@@ -516,19 +510,6 @@
                                         USAGE_GRAPHICS_TEXTURE);
     }
 
-/*
-    static public Allocation createFromBitmapResource(RenderScript rs,
-                                                      Resources res,
-                                                      int id,
-                                                      Element dstFmt,
-                                                      boolean genMips) {
-        MipmapControl mc = MipmapControl.MIPMAP_NONE;
-        if (genMips) {
-            mc = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
-        }
-        return createFromBitmapResource(rs, res, id, mc, USAGE_GRAPHICS_TEXTURE);
-    }
-*/
     static public Allocation createFromString(RenderScript rs,
                                               String str,
                                               int usage) {
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index ed16451..2a585fd 100644
--- a/graphics/java/android/renderscript/FieldPacker.java
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -248,27 +248,6 @@
         addU32(v.w);
     }
 
-    // to be removed on cleanup
-    public void addObj(Matrix4f v) {
-        for (int i=0; i < v.mMat.length; i++) {
-            addF32(v.mMat[i]);
-        }
-    }
-
-    // to be removed on cleanup
-    public void addObj(Matrix3f v) {
-        for (int i=0; i < v.mMat.length; i++) {
-            addF32(v.mMat[i]);
-        }
-    }
-
-    // to be removed on cleanup
-    public void addObj(Matrix2f v) {
-        for (int i=0; i < v.mMat.length; i++) {
-            addF32(v.mMat[i]);
-        }
-    }
-
     public void addMatrix(Matrix4f v) {
         for (int i=0; i < v.mMat.length; i++) {
             addF32(v.mMat[i]);
diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java
index 4654c48..6ce8379 100644
--- a/graphics/java/android/renderscript/Matrix2f.java
+++ b/graphics/java/android/renderscript/Matrix2f.java
@@ -57,7 +57,7 @@
     }
 
     public void load(Matrix2f src) {
-        System.arraycopy(mMat, 0, src, 0, 4);
+        System.arraycopy(mMat, 0, src.getArray(), 0, 4);
     }
 
     public void loadRotate(float rot) {
diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java
index 15e5ce6..b44d8fa 100644
--- a/graphics/java/android/renderscript/Matrix3f.java
+++ b/graphics/java/android/renderscript/Matrix3f.java
@@ -63,7 +63,7 @@
     }
 
     public void load(Matrix3f src) {
-        System.arraycopy(mMat, 0, src, 0, 9);
+        System.arraycopy(mMat, 0, src.getArray(), 0, 9);
     }
 
     public void loadRotate(float rot, float x, float y, float z) {
diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java
index ea97509..219d93b 100644
--- a/graphics/java/android/renderscript/Matrix4f.java
+++ b/graphics/java/android/renderscript/Matrix4f.java
@@ -71,7 +71,7 @@
     }
 
     public void load(Matrix4f src) {
-        System.arraycopy(mMat, 0, src, 0, 16);
+        System.arraycopy(mMat, 0, src.getArray(), 0, 16);
     }
 
     public void loadRotate(float rot, float x, float y, float z) {
@@ -180,6 +180,32 @@
         loadFrustum(left, right, bottom, top, near, far);
     }
 
+    public void loadProjectionNormalized(int w, int h) {
+        // range -1,1 in the narrow axis at z = 0.
+        Matrix4f m1 = new Matrix4f();
+        Matrix4f m2 = new Matrix4f();
+
+        if(w > h) {
+            float aspect = ((float)w) / h;
+            m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
+        } else {
+            float aspect = ((float)h) / w;
+            m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
+        }
+
+        m2.loadRotate(180, 0, 1, 0);
+        m1.loadMultiply(m1, m2);
+
+        m2.loadScale(-2, 2, 1);
+        m1.loadMultiply(m1, m2);
+
+        m2.loadTranslate(0, 0, 2);
+        m1.loadMultiply(m1, m2);
+
+        load(m1);
+    }
+
+
     public void multiply(Matrix4f rhs) {
         Matrix4f tmp = new Matrix4f();
         tmp.loadMultiply(this, rhs);
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index b103af4..59e3dd9 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -27,6 +27,20 @@
  **/
 public class Mesh extends BaseObj {
 
+    public enum Primitive {
+        POINT (0),
+        LINE (1),
+        LINE_STRIP (2),
+        TRIANGLE (3),
+        TRIANGLE_STRIP (4),
+        TRIANGLE_FAN (5);
+
+        int mID;
+        Primitive(int id) {
+            mID = id;
+        }
+    }
+
     Allocation[] mVertexBuffers;
     Allocation[] mIndexBuffers;
     Primitive[] mPrimitives;
@@ -51,7 +65,7 @@
         }
         return mIndexBuffers.length;
     }
-    public Allocation getIndexAllocation(int slot) {
+    public Allocation getIndexSetAllocation(int slot) {
         return mIndexBuffers[slot];
     }
     public Primitive getPrimitive(int slot) {
@@ -93,83 +107,89 @@
 
     public static class Builder {
         RenderScript mRS;
+        int mUsage;
 
         class Entry {
             Type t;
             Element e;
             int size;
             Primitive prim;
+            int usage;
         }
 
         int mVertexTypeCount;
         Entry[] mVertexTypes;
         Vector mIndexTypes;
 
-        public Builder(RenderScript rs) {
+        public Builder(RenderScript rs, int usage) {
             mRS = rs;
+            mUsage = usage;
             mVertexTypeCount = 0;
             mVertexTypes = new Entry[16];
             mIndexTypes = new Vector();
         }
 
-        public int addVertexType(Type t) throws IllegalStateException {
+        public int getCurrentVertexTypeIndex() {
+            return mVertexTypeCount - 1;
+        }
+
+        public int getCurrentIndexSetIndex() {
+            return mIndexTypes.size() - 1;
+        }
+
+        public Builder addVertexType(Type t) throws IllegalStateException {
             if (mVertexTypeCount >= mVertexTypes.length) {
                 throw new IllegalStateException("Max vertex types exceeded.");
             }
 
-            int addedIndex = mVertexTypeCount;
             mVertexTypes[mVertexTypeCount] = new Entry();
             mVertexTypes[mVertexTypeCount].t = t;
             mVertexTypes[mVertexTypeCount].e = null;
             mVertexTypeCount++;
-            return addedIndex;
+            return this;
         }
 
-        public int addVertexType(Element e, int size) throws IllegalStateException {
+        public Builder addVertexType(Element e, int size) throws IllegalStateException {
             if (mVertexTypeCount >= mVertexTypes.length) {
                 throw new IllegalStateException("Max vertex types exceeded.");
             }
 
-            int addedIndex = mVertexTypeCount;
             mVertexTypes[mVertexTypeCount] = new Entry();
             mVertexTypes[mVertexTypeCount].t = null;
             mVertexTypes[mVertexTypeCount].e = e;
             mVertexTypes[mVertexTypeCount].size = size;
             mVertexTypeCount++;
-            return addedIndex;
+            return this;
         }
 
-        public int addIndexType(Type t, Primitive p) {
-            int addedIndex  = mIndexTypes.size();
+        public Builder addIndexSetType(Type t, Primitive p) {
             Entry indexType = new Entry();
             indexType.t = t;
             indexType.e = null;
             indexType.size = 0;
             indexType.prim = p;
             mIndexTypes.addElement(indexType);
-            return addedIndex;
+            return this;
         }
 
-        public int addIndexType(Primitive p) {
-            int addedIndex  = mIndexTypes.size();
+        public Builder addIndexSetType(Primitive p) {
             Entry indexType = new Entry();
             indexType.t = null;
             indexType.e = null;
             indexType.size = 0;
             indexType.prim = p;
             mIndexTypes.addElement(indexType);
-            return addedIndex;
+            return this;
         }
 
-        public int addIndexType(Element e, int size, Primitive p) {
-            int addedIndex  = mIndexTypes.size();
+        public Builder addIndexSetType(Element e, int size, Primitive p) {
             Entry indexType = new Entry();
             indexType.t = null;
             indexType.e = e;
             indexType.size = size;
             indexType.prim = p;
             mIndexTypes.addElement(indexType);
-            return addedIndex;
+            return this;
         }
 
         Type newType(Element e, int size) {
@@ -190,10 +210,10 @@
                 Allocation alloc = null;
                 Entry entry = (Entry)b.mIndexTypes.elementAt(ct);
                 if (entry.t != null) {
-                    alloc = Allocation.createTyped(rs, entry.t);
+                    alloc = Allocation.createTyped(rs, entry.t, b.mUsage);
                 }
                 else if(entry.e != null) {
-                    alloc = Allocation.createSized(rs, entry.e, entry.size);
+                    alloc = Allocation.createSized(rs, entry.e, entry.size, b.mUsage);
                 }
                 int allocID = (alloc == null) ? 0 : alloc.getID();
                 rs.nMeshBindIndex(id, allocID, entry.prim.mID, ct);
@@ -205,9 +225,9 @@
                 Allocation alloc = null;
                 Entry entry = b.mVertexTypes[ct];
                 if (entry.t != null) {
-                    alloc = Allocation.createTyped(rs, entry.t);
+                    alloc = Allocation.createTyped(rs, entry.t, b.mUsage);
                 } else if(entry.e != null) {
-                    alloc = Allocation.createSized(rs, entry.e, entry.size);
+                    alloc = Allocation.createSized(rs, entry.e, entry.size, b.mUsage);
                 }
                 rs.nMeshBindVertex(id, alloc.getID(), ct);
                 newMesh.mVertexBuffers[ct] = alloc;
@@ -244,34 +264,39 @@
             mIndexTypes = new Vector();
         }
 
-        public int addVertexAllocation(Allocation a) throws IllegalStateException {
+        public int getCurrentVertexTypeIndex() {
+            return mVertexTypeCount - 1;
+        }
+
+        public int getCurrentIndexSetIndex() {
+            return mIndexTypes.size() - 1;
+        }
+
+        public AllocationBuilder addVertexAllocation(Allocation a) throws IllegalStateException {
             if (mVertexTypeCount >= mVertexTypes.length) {
                 throw new IllegalStateException("Max vertex types exceeded.");
             }
 
-            int addedIndex = mVertexTypeCount;
             mVertexTypes[mVertexTypeCount] = new Entry();
             mVertexTypes[mVertexTypeCount].a = a;
             mVertexTypeCount++;
-            return addedIndex;
+            return this;
         }
 
-        public int addIndexAllocation(Allocation a, Primitive p) {
-            int addedIndex  = mIndexTypes.size();
+        public AllocationBuilder addIndexSetAllocation(Allocation a, Primitive p) {
             Entry indexType = new Entry();
             indexType.a = a;
             indexType.prim = p;
             mIndexTypes.addElement(indexType);
-            return addedIndex;
+            return this;
         }
 
-        public int addIndexType(Primitive p) {
-            int addedIndex  = mIndexTypes.size();
+        public AllocationBuilder addIndexSetType(Primitive p) {
             Entry indexType = new Entry();
             indexType.a = null;
             indexType.prim = p;
             mIndexTypes.addElement(indexType);
-            return addedIndex;
+            return this;
         }
 
         static synchronized Mesh internalCreate(RenderScript rs, AllocationBuilder b) {
@@ -376,7 +401,7 @@
             }
         }
 
-        public void addVertex(float x, float y) {
+        public TriangleMeshBuilder addVertex(float x, float y) {
             if (mVtxSize != 2) {
                 throw new IllegalStateException("add mistmatch with declared components.");
             }
@@ -384,9 +409,10 @@
             mVtxData[mVtxCount++] = x;
             mVtxData[mVtxCount++] = y;
             latch();
+            return this;
         }
 
-        public void addVertex(float x, float y, float z) {
+        public TriangleMeshBuilder addVertex(float x, float y, float z) {
             if (mVtxSize != 3) {
                 throw new IllegalStateException("add mistmatch with declared components.");
             }
@@ -395,26 +421,29 @@
             mVtxData[mVtxCount++] = y;
             mVtxData[mVtxCount++] = z;
             latch();
+            return this;
         }
 
-        public void setTexture(float s, float t) {
+        public TriangleMeshBuilder setTexture(float s, float t) {
             if ((mFlags & TEXTURE_0) == 0) {
                 throw new IllegalStateException("add mistmatch with declared components.");
             }
             mS0 = s;
             mT0 = t;
+            return this;
         }
 
-        public void setNormal(float x, float y, float z) {
+        public TriangleMeshBuilder setNormal(float x, float y, float z) {
             if ((mFlags & NORMAL) == 0) {
                 throw new IllegalStateException("add mistmatch with declared components.");
             }
             mNX = x;
             mNY = y;
             mNZ = z;
+            return this;
         }
 
-        public void setColor(float r, float g, float b, float a) {
+        public TriangleMeshBuilder setColor(float r, float g, float b, float a) {
             if ((mFlags & COLOR) == 0) {
                 throw new IllegalStateException("add mistmatch with declared components.");
             }
@@ -422,9 +451,10 @@
             mG = g;
             mB = b;
             mA = a;
+            return this;
         }
 
-        public void addTriangle(int idx1, int idx2, int idx3) {
+        public TriangleMeshBuilder addTriangle(int idx1, int idx2, int idx3) {
             if((idx1 >= mVtxCount) || (idx1 < 0) ||
                (idx2 >= mVtxCount) || (idx2 < 0) ||
                (idx3 >= mVtxCount) || (idx3 < 0)) {
@@ -438,6 +468,7 @@
             mIndexData[mIndexCount++] = (short)idx1;
             mIndexData[mIndexCount++] = (short)idx2;
             mIndexData[mIndexCount++] = (short)idx3;
+            return this;
         }
 
         public Mesh create(boolean uploadToBufferObject) {
@@ -460,19 +491,28 @@
             }
             mElement = b.create();
 
-            Builder smb = new Builder(mRS);
+            int usage = Allocation.USAGE_SCRIPT;
+            if (uploadToBufferObject) {
+                usage |= Allocation.USAGE_GRAPHICS_VERTEX;
+            }
+
+            Builder smb = new Builder(mRS, usage);
             smb.addVertexType(mElement, mVtxCount / floatCount);
-            smb.addIndexType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE);
+            smb.addIndexSetType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE);
 
             Mesh sm = smb.create();
 
             sm.getVertexAllocation(0).copyFrom(mVtxData);
             if(uploadToBufferObject) {
-                sm.getVertexAllocation(0).uploadToBufferObject();
+                if (uploadToBufferObject) {
+                    sm.getVertexAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
+                }
             }
 
-            sm.getIndexAllocation(0).copyFrom(mIndexData);
-            sm.getIndexAllocation(0).uploadToBufferObject();
+            sm.getIndexSetAllocation(0).copyFrom(mIndexData);
+            if (uploadToBufferObject) {
+                sm.getIndexSetAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
+            }
 
             return sm;
         }
diff --git a/graphics/java/android/renderscript/Primitive.java b/graphics/java/android/renderscript/Primitive.java
deleted file mode 100644
index 7925cac..0000000
--- a/graphics/java/android/renderscript/Primitive.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.renderscript;
-
-/**
- * @hide
- **/
-public enum Primitive {
-    POINT (0),
-    LINE (1),
-    LINE_STRIP (2),
-    TRIANGLE (3),
-    TRIANGLE_STRIP (4),
-    TRIANGLE_FAN (5);
-
-    int mID;
-    Primitive(int id) {
-        mID = id;
-    }
-}
-
-
-
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index c3536c3..a9eaec3 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -177,36 +177,15 @@
             return this;
         }
 
-        public void addInput(Element e) throws IllegalStateException {
-            // Should check for consistant and non-conflicting names...
-            if(mInputCount >= MAX_INPUT) {
-                throw new RSIllegalArgumentException("Max input count exceeded.");
-            }
-            if (e.isComplex()) {
-                throw new RSIllegalArgumentException("Complex elements not allowed.");
-            }
-            mInputs[mInputCount++] = e;
+        public int getCurrentConstantIndex() {
+            return mConstantCount - 1;
         }
 
-        public void addOutput(Element e) throws IllegalStateException {
-            // Should check for consistant and non-conflicting names...
-            if(mOutputCount >= MAX_OUTPUT) {
-                throw new RSIllegalArgumentException("Max output count exceeded.");
-            }
-            if (e.isComplex()) {
-                throw new RSIllegalArgumentException("Complex elements not allowed.");
-            }
-            mOutputs[mOutputCount++] = e;
+        public int getCurrentTextureIndex() {
+            return mTextureCount - 1;
         }
 
-        void resetConstant() {
-            mConstantCount = 0;
-            for(int i = 0; i < MAX_CONSTANT; i ++) {
-                mConstants[i] = null;
-            }
-        }
-
-        public int addConstant(Type t) throws IllegalStateException {
+        public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
             // Should check for consistant and non-conflicting names...
             if(mConstantCount >= MAX_CONSTANT) {
                 throw new RSIllegalArgumentException("Max input count exceeded.");
@@ -215,18 +194,7 @@
                 throw new RSIllegalArgumentException("Complex elements not allowed.");
             }
             mConstants[mConstantCount] = t;
-            return mConstantCount++;
-        }
-
-        public BaseProgramBuilder setTextureCount(int count) throws IllegalArgumentException {
-            // Should check for consistant and non-conflicting names...
-            if(count >= MAX_TEXTURE) {
-                throw new IllegalArgumentException("Max texture count exceeded.");
-            }
-            mTextureCount = count;
-            for (int i = 0; i < mTextureCount; i ++) {
-                mTextureTypes[i] = TextureType.TEXTURE_2D;
-            }
+            mConstantCount++;
             return this;
         }
 
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index 074c393..59d4967 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -30,8 +30,8 @@
         super(id, rs);
     }
 
-    public static class ShaderBuilder extends BaseProgramBuilder {
-        public ShaderBuilder(RenderScript rs) {
+    public static class Builder extends BaseProgramBuilder {
+        public Builder(RenderScript rs) {
             super(rs);
         }
 
@@ -63,169 +63,6 @@
             return pf;
         }
     }
-
-    public static class Builder extends ShaderBuilder {
-        public static final int MAX_TEXTURE = 2;
-        int mNumTextures;
-        boolean mPointSpriteEnable;
-        boolean mVaryingColorEnable;
-
-        public enum EnvMode {
-            REPLACE (1),
-            MODULATE (2),
-            DECAL (3);
-
-            int mID;
-            EnvMode(int id) {
-                mID = id;
-            }
-        }
-
-        public enum Format {
-            ALPHA (1),
-            LUMINANCE_ALPHA (2),
-            RGB (3),
-            RGBA (4);
-
-            int mID;
-            Format(int id) {
-                mID = id;
-            }
-        }
-
-        private class Slot {
-            EnvMode env;
-            Format format;
-            Slot(EnvMode _env, Format _fmt) {
-                env = _env;
-                format = _fmt;
-            }
-        }
-        Slot[] mSlots;
-
-        private void buildShaderString() {
-            mShader  = "//rs_shader_internal\n";
-            mShader += "varying lowp vec4 varColor;\n";
-            mShader += "varying vec2 varTex0;\n";
-
-            mShader += "void main() {\n";
-            if (mVaryingColorEnable) {
-                mShader += "  lowp vec4 col = varColor;\n";
-            } else {
-                mShader += "  lowp vec4 col = UNI_Color;\n";
-            }
-
-            if (mNumTextures != 0) {
-                if (mPointSpriteEnable) {
-                    mShader += "  vec2 t0 = gl_PointCoord;\n";
-                } else {
-                    mShader += "  vec2 t0 = varTex0.xy;\n";
-                }
-            }
-
-            for(int i = 0; i < mNumTextures; i ++) {
-                switch(mSlots[i].env) {
-                case REPLACE:
-                    switch (mSlots[i].format) {
-                    case ALPHA:
-                        mShader += "  col.a = texture2D(UNI_Tex0, t0).a;\n";
-                        break;
-                    case LUMINANCE_ALPHA:
-                        mShader += "  col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
-                        break;
-                    case RGB:
-                        mShader += "  col.rgb = texture2D(UNI_Tex0, t0).rgb;\n";
-                        break;
-                    case RGBA:
-                        mShader += "  col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
-                        break;
-                    }
-                    break;
-                case MODULATE:
-                    switch (mSlots[i].format) {
-                    case ALPHA:
-                        mShader += "  col.a *= texture2D(UNI_Tex0, t0).a;\n";
-                        break;
-                    case LUMINANCE_ALPHA:
-                        mShader += "  col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
-                        break;
-                    case RGB:
-                        mShader += "  col.rgb *= texture2D(UNI_Tex0, t0).rgb;\n";
-                        break;
-                    case RGBA:
-                        mShader += "  col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
-                        break;
-                    }
-                    break;
-                case DECAL:
-                    mShader += "  col = texture2D(UNI_Tex0, t0);\n";
-                    break;
-                }
-            }
-
-            mShader += "  gl_FragColor = col;\n";
-            mShader += "}\n";
-        }
-
-        public Builder(RenderScript rs) {
-            super(rs);
-            mRS = rs;
-            mSlots = new Slot[MAX_TEXTURE];
-            mPointSpriteEnable = false;
-        }
-
-        public Builder setTexture(EnvMode env, Format fmt, int slot)
-            throws IllegalArgumentException {
-            if((slot < 0) || (slot >= MAX_TEXTURE)) {
-                throw new IllegalArgumentException("MAX_TEXTURE exceeded.");
-            }
-            mSlots[slot] = new Slot(env, fmt);
-            return this;
-        }
-
-        public Builder setPointSpriteTexCoordinateReplacement(boolean enable) {
-            mPointSpriteEnable = enable;
-            return this;
-        }
-
-        public Builder setVaryingColor(boolean enable) {
-            mVaryingColorEnable = enable;
-            return this;
-        }
-
-        @Override
-        public ProgramFragment create() {
-            mNumTextures = 0;
-            for(int i = 0; i < MAX_TEXTURE; i ++) {
-                if(mSlots[i] != null) {
-                    mNumTextures ++;
-                }
-            }
-            resetConstant();
-            buildShaderString();
-            Type constType = null;
-            if (!mVaryingColorEnable) {
-                Element.Builder b = new Element.Builder(mRS);
-                b.add(Element.F32_4(mRS), "Color");
-                Type.Builder typeBuilder = new Type.Builder(mRS, b.create());
-                typeBuilder.setX(1);
-                constType = typeBuilder.create();
-                addConstant(constType);
-            }
-            setTextureCount(mNumTextures);
-
-            ProgramFragment pf = super.create();
-            pf.mTextureCount = MAX_TEXTURE;
-            if (!mVaryingColorEnable) {
-                Allocation constantData = Allocation.createTyped(mRS,constType);
-                float[] data = new float[4];
-                data[0] = data[1] = data[2] = data[3] = 1.0f;
-                constantData.copyFrom(data);
-                pf.bindConstants(constantData, 0);
-            }
-            return pf;
-        }
-    }
 }
 
 
diff --git a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
new file mode 100644
index 0000000..d011219
--- /dev/null
+++ b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2008 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 android.renderscript;
+
+
+import android.util.Config;
+import android.util.Log;
+
+
+/**
+ * @hide
+ *
+ **/
+public class ProgramFragmentFixedFunction extends ProgramFragment {
+    ProgramFragmentFixedFunction(int id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    static class InternalBuilder extends BaseProgramBuilder {
+        public InternalBuilder(RenderScript rs) {
+            super(rs);
+        }
+
+        public ProgramFragmentFixedFunction create() {
+            mRS.validate();
+            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
+            int idx = 0;
+
+            for (int i=0; i < mInputCount; i++) {
+                tmp[idx++] = ProgramParam.INPUT.mID;
+                tmp[idx++] = mInputs[i].getID();
+            }
+            for (int i=0; i < mOutputCount; i++) {
+                tmp[idx++] = ProgramParam.OUTPUT.mID;
+                tmp[idx++] = mOutputs[i].getID();
+            }
+            for (int i=0; i < mConstantCount; i++) {
+                tmp[idx++] = ProgramParam.CONSTANT.mID;
+                tmp[idx++] = mConstants[i].getID();
+            }
+            for (int i=0; i < mTextureCount; i++) {
+                tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
+                tmp[idx++] = mTextureTypes[i].mID;
+            }
+
+            int id = mRS.nProgramFragmentCreate(mShader, tmp);
+            ProgramFragmentFixedFunction pf = new ProgramFragmentFixedFunction(id, mRS);
+            initProgram(pf);
+            return pf;
+        }
+    }
+
+    public static class Builder {
+        public static final int MAX_TEXTURE = 2;
+        int mNumTextures;
+        boolean mPointSpriteEnable;
+        boolean mVaryingColorEnable;
+        String mShader;
+        RenderScript mRS;
+
+        public enum EnvMode {
+            REPLACE (1),
+            MODULATE (2),
+            DECAL (3);
+
+            int mID;
+            EnvMode(int id) {
+                mID = id;
+            }
+        }
+
+        public enum Format {
+            ALPHA (1),
+            LUMINANCE_ALPHA (2),
+            RGB (3),
+            RGBA (4);
+
+            int mID;
+            Format(int id) {
+                mID = id;
+            }
+        }
+
+        private class Slot {
+            EnvMode env;
+            Format format;
+            Slot(EnvMode _env, Format _fmt) {
+                env = _env;
+                format = _fmt;
+            }
+        }
+        Slot[] mSlots;
+
+        private void buildShaderString() {
+            mShader  = "//rs_shader_internal\n";
+            mShader += "varying lowp vec4 varColor;\n";
+            mShader += "varying vec2 varTex0;\n";
+
+            mShader += "void main() {\n";
+            if (mVaryingColorEnable) {
+                mShader += "  lowp vec4 col = varColor;\n";
+            } else {
+                mShader += "  lowp vec4 col = UNI_Color;\n";
+            }
+
+            if (mNumTextures != 0) {
+                if (mPointSpriteEnable) {
+                    mShader += "  vec2 t0 = gl_PointCoord;\n";
+                } else {
+                    mShader += "  vec2 t0 = varTex0.xy;\n";
+                }
+            }
+
+            for(int i = 0; i < mNumTextures; i ++) {
+                switch(mSlots[i].env) {
+                case REPLACE:
+                    switch (mSlots[i].format) {
+                    case ALPHA:
+                        mShader += "  col.a = texture2D(UNI_Tex0, t0).a;\n";
+                        break;
+                    case LUMINANCE_ALPHA:
+                        mShader += "  col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
+                        break;
+                    case RGB:
+                        mShader += "  col.rgb = texture2D(UNI_Tex0, t0).rgb;\n";
+                        break;
+                    case RGBA:
+                        mShader += "  col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
+                        break;
+                    }
+                    break;
+                case MODULATE:
+                    switch (mSlots[i].format) {
+                    case ALPHA:
+                        mShader += "  col.a *= texture2D(UNI_Tex0, t0).a;\n";
+                        break;
+                    case LUMINANCE_ALPHA:
+                        mShader += "  col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
+                        break;
+                    case RGB:
+                        mShader += "  col.rgb *= texture2D(UNI_Tex0, t0).rgb;\n";
+                        break;
+                    case RGBA:
+                        mShader += "  col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
+                        break;
+                    }
+                    break;
+                case DECAL:
+                    mShader += "  col = texture2D(UNI_Tex0, t0);\n";
+                    break;
+                }
+            }
+
+            mShader += "  gl_FragColor = col;\n";
+            mShader += "}\n";
+        }
+
+        public Builder(RenderScript rs) {
+            mRS = rs;
+            mSlots = new Slot[MAX_TEXTURE];
+            mPointSpriteEnable = false;
+        }
+
+        public Builder setTexture(EnvMode env, Format fmt, int slot)
+            throws IllegalArgumentException {
+            if((slot < 0) || (slot >= MAX_TEXTURE)) {
+                throw new IllegalArgumentException("MAX_TEXTURE exceeded.");
+            }
+            mSlots[slot] = new Slot(env, fmt);
+            return this;
+        }
+
+        public Builder setPointSpriteTexCoordinateReplacement(boolean enable) {
+            mPointSpriteEnable = enable;
+            return this;
+        }
+
+        public Builder setVaryingColor(boolean enable) {
+            mVaryingColorEnable = enable;
+            return this;
+        }
+
+        public ProgramFragmentFixedFunction create() {
+            InternalBuilder sb = new InternalBuilder(mRS);
+            mNumTextures = 0;
+            for(int i = 0; i < MAX_TEXTURE; i ++) {
+                if(mSlots[i] != null) {
+                    mNumTextures ++;
+                }
+            }
+            buildShaderString();
+            sb.setShader(mShader);
+
+            Type constType = null;
+            if (!mVaryingColorEnable) {
+                Element.Builder b = new Element.Builder(mRS);
+                b.add(Element.F32_4(mRS), "Color");
+                Type.Builder typeBuilder = new Type.Builder(mRS, b.create());
+                typeBuilder.setX(1);
+                constType = typeBuilder.create();
+                sb.addConstant(constType);
+            }
+            for (int i = 0; i < mNumTextures; i ++) {
+                sb.addTexture(TextureType.TEXTURE_2D);
+            }
+
+            ProgramFragmentFixedFunction pf = sb.create();
+            pf.mTextureCount = MAX_TEXTURE;
+            if (!mVaryingColorEnable) {
+                Allocation constantData = Allocation.createTyped(mRS,constType);
+                float[] data = new float[4];
+                data[0] = data[1] = data[2] = data[3] = 1.0f;
+                constantData.copyFrom(data);
+                pf.bindConstants(constantData, 0);
+            }
+            return pf;
+        }
+    }
+}
+
+
+
+
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index 5b55015..3bdd71d 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -109,21 +109,11 @@
             mCullMode = CullMode.BACK;
         }
 
-        public Builder setPointSpriteEnable(boolean enable) {
+        public Builder setPointSpriteEnabled(boolean enable) {
             mPointSprite = enable;
             return this;
         }
 
-        public Builder setPointSmoothEnable(boolean enable) {
-            mPointSmooth = enable;
-            return this;
-        }
-
-        public Builder setLineSmoothEnable(boolean enable) {
-            mLineSmooth = enable;
-            return this;
-        }
-
         public Builder setCullMode(CullMode m) {
             mCullMode = m;
             return this;
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index d191b06..2d2b162 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -26,14 +26,14 @@
  *
  **/
 public class ProgramStore extends BaseObj {
-        public enum DepthFunc {
+    public enum DepthFunc {
         ALWAYS (0),
         LESS (1),
-        LEQUAL (2),
+        LESS_OR_EQUAL (2),
         GREATER (3),
-        GEQUAL (4),
+        GREATER_OR_EQUAL (4),
         EQUAL (5),
-        NOTEQUAL (6);
+        NOT_EQUAL (6);
 
         int mID;
         DepthFunc(int id) {
@@ -84,140 +84,49 @@
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(true);
+            builder.setDitherEnabled(false);
+            builder.setDepthMaskEnabled(true);
             rs.mProgramStore_BLEND_NONE_DEPTH_TEST = builder.create();
         }
         return rs.mProgramStore_BLEND_NONE_DEPTH_TEST;
     }
-    public static ProgramStore BLEND_NONE_DEPTH_NO_DEPTH(RenderScript rs) {
+    public static ProgramStore BLEND_NONE_DEPTH_NONE(RenderScript rs) {
         if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(false);
+            builder.setDitherEnabled(false);
+            builder.setDepthMaskEnabled(false);
             rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH = builder.create();
         }
         return rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
     }
-    public static ProgramStore BLEND_NONE_DEPTH_NO_TEST(RenderScript rs) {
-        if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_TEST == null) {
-            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-            builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-            builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(true);
-            rs.mProgramStore_BLEND_NONE_DEPTH_NO_TEST = builder.create();
-        }
-        return rs.mProgramStore_BLEND_NONE_DEPTH_NO_TEST;
-    }
-    public static ProgramStore BLEND_NONE_DEPTH_NO_WRITE(RenderScript rs) {
-        if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_WRITE == null) {
-            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-            builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
-            builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(false);
-            rs.mProgramStore_BLEND_NONE_DEPTH_NO_WRITE = builder.create();
-        }
-        return rs.mProgramStore_BLEND_NONE_DEPTH_NO_WRITE;
-    }
 
     public static ProgramStore BLEND_ALPHA_DEPTH_TEST(RenderScript rs) {
         if(rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
             builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(true);
+            builder.setDitherEnabled(false);
+            builder.setDepthMaskEnabled(true);
             rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST = builder.create();
         }
         return rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST;
     }
-    public static ProgramStore BLEND_ALPHA_DEPTH_NO_DEPTH(RenderScript rs) {
+    public static ProgramStore BLEND_ALPHA_DEPTH_NONE(RenderScript rs) {
         if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH == null) {
             ProgramStore.Builder builder = new ProgramStore.Builder(rs);
             builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(false);
+            builder.setDitherEnabled(false);
+            builder.setDepthMaskEnabled(false);
             rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH = builder.create();
         }
         return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
     }
-    public static ProgramStore BLEND_ALPHA_DEPTH_NO_TEST(RenderScript rs) {
-        if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST == null) {
-            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-            builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-            builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(true);
-            rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST = builder.create();
-        }
-        return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST;
-    }
-    public static ProgramStore BLEND_ALPHA_DEPTH_NO_WRITE(RenderScript rs) {
-        if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE == null) {
-            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-            builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
-            builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(false);
-            rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE = builder.create();
-        }
-        return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE;
-    }
-
-    public static ProgramStore BLEND_ADD_DEPTH_TEST(RenderScript rs) {
-        if(rs.mProgramStore_BLEND_ADD_DEPTH_TEST == null) {
-            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-            builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
-            builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(true);
-            rs.mProgramStore_BLEND_ADD_DEPTH_TEST = builder.create();
-        }
-        return rs.mProgramStore_BLEND_ADD_DEPTH_TEST;
-    }
-    public static ProgramStore BLEND_ADD_DEPTH_NO_DEPTH(RenderScript rs) {
-        if(rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH == null) {
-            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-            builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-            builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(false);
-            rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH = builder.create();
-        }
-        return rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH;
-    }
-    public static ProgramStore BLEND_ADD_DEPTH_NO_TEST(RenderScript rs) {
-        if(rs.mProgramStore_BLEND_ADD_DEPTH_NO_TEST == null) {
-            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-            builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-            builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(true);
-            rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH = builder.create();
-        }
-        return rs.mProgramStore_BLEND_ADD_DEPTH_NO_TEST;
-    }
-    public static ProgramStore BLEND_ADD_DEPTH_NO_WRITE(RenderScript rs) {
-        if(rs.mProgramStore_BLEND_ADD_DEPTH_NO_WRITE == null) {
-            ProgramStore.Builder builder = new ProgramStore.Builder(rs);
-            builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
-            builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
-            builder.setDitherEnable(false);
-            builder.setDepthMask(false);
-            rs.mProgramStore_BLEND_ADD_DEPTH_NO_WRITE = builder.create();
-        }
-        return rs.mProgramStore_BLEND_ADD_DEPTH_NO_WRITE;
-    }
 
     public static class Builder {
         RenderScript mRS;
-        Element mIn;
-        Element mOut;
         DepthFunc mDepthFunc;
         boolean mDepthMask;
         boolean mColorMaskR;
@@ -228,26 +137,8 @@
         BlendDstFunc mBlendDst;
         boolean mDither;
 
-
-
-        public Builder(RenderScript rs, Element in, Element out) {
-            mRS = rs;
-            mIn = in;
-            mOut = out;
-            mDepthFunc = DepthFunc.ALWAYS;
-            mDepthMask = false;
-            mColorMaskR = true;
-            mColorMaskG = true;
-            mColorMaskB = true;
-            mColorMaskA = true;
-            mBlendSrc = BlendSrcFunc.ONE;
-            mBlendDst = BlendDstFunc.ZERO;
-        }
-
         public Builder(RenderScript rs) {
             mRS = rs;
-            mIn = null;
-            mOut = null;
             mDepthFunc = DepthFunc.ALWAYS;
             mDepthMask = false;
             mColorMaskR = true;
@@ -263,12 +154,12 @@
             return this;
         }
 
-        public Builder setDepthMask(boolean enable) {
+        public Builder setDepthMaskEnabled(boolean enable) {
             mDepthMask = enable;
             return this;
         }
 
-        public Builder setColorMask(boolean r, boolean g, boolean b, boolean a) {
+        public Builder setColorMaskEnabled(boolean r, boolean g, boolean b, boolean a) {
             mColorMaskR = r;
             mColorMaskG = g;
             mColorMaskB = b;
@@ -282,7 +173,7 @@
             return this;
         }
 
-        public Builder setDitherEnable(boolean enable) {
+        public Builder setDitherEnabled(boolean enable) {
             mDither = enable;
             return this;
         }
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 5d41f63..954ac9a 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -27,23 +27,28 @@
  *
  **/
 public class ProgramVertex extends Program {
-    public static final int MAX_LIGHT = 8;
-
 
     ProgramVertex(int id, RenderScript rs) {
         super(id, rs);
     }
 
-    public void bindAllocation(MatrixAllocation va) {
-        mRS.validate();
-        bindConstants(va.mAlloc, 0);
-    }
-
-    public static class ShaderBuilder extends BaseProgramBuilder {
-        public ShaderBuilder(RenderScript rs) {
+    public static class Builder extends BaseProgramBuilder {
+        public Builder(RenderScript rs) {
             super(rs);
         }
 
+        public Builder addInput(Element e) throws IllegalStateException {
+            // Should check for consistant and non-conflicting names...
+            if(mInputCount >= MAX_INPUT) {
+                throw new RSIllegalArgumentException("Max input count exceeded.");
+            }
+            if (e.isComplex()) {
+                throw new RSIllegalArgumentException("Complex elements not allowed.");
+            }
+            mInputs[mInputCount++] = e;
+            return this;
+        }
+
         public ProgramVertex create() {
             mRS.validate();
             int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
@@ -73,165 +78,4 @@
         }
     }
 
-    public static class Builder extends ShaderBuilder {
-        boolean mTextureMatrixEnable;
-
-        public Builder(RenderScript rs, Element in, Element out) {
-            super(rs);
-        }
-        public Builder(RenderScript rs) {
-            super(rs);
-        }
-
-        public Builder setTextureMatrixEnable(boolean enable) {
-            mTextureMatrixEnable = enable;
-            return this;
-        }
-        static Type getConstantInputType(RenderScript rs) {
-            Element.Builder b = new Element.Builder(rs);
-            b.add(Element.MATRIX4X4(rs), "MV");
-            b.add(Element.MATRIX4X4(rs), "P");
-            b.add(Element.MATRIX4X4(rs), "TexMatrix");
-            b.add(Element.MATRIX4X4(rs), "MVP");
-
-            Type.Builder typeBuilder = new Type.Builder(rs, b.create());
-            typeBuilder.setX(1);
-            return typeBuilder.create();
-        }
-
-        private void buildShaderString() {
-
-            mShader  = "//rs_shader_internal\n";
-            mShader += "varying vec4 varColor;\n";
-            mShader += "varying vec2 varTex0;\n";
-
-            mShader += "void main() {\n";
-            mShader += "  gl_Position = UNI_MVP * ATTRIB_position;\n";
-            mShader += "  gl_PointSize = 1.0;\n";
-
-            mShader += "  varColor = ATTRIB_color;\n";
-            if (mTextureMatrixEnable) {
-                mShader += "  varTex0 = (UNI_TexMatrix * vec4(ATTRIB_texture0, 0.0, 1.0)).xy;\n";
-            } else {
-                mShader += "  varTex0 = ATTRIB_texture0;\n";
-            }
-            mShader += "}\n";
-        }
-
-        @Override
-        public ProgramVertex create() {
-            buildShaderString();
-
-            addConstant(getConstantInputType(mRS));
-
-            Element.Builder b = new Element.Builder(mRS);
-            b.add(Element.F32_4(mRS), "position");
-            b.add(Element.F32_4(mRS), "color");
-            b.add(Element.F32_3(mRS), "normal");
-            b.add(Element.F32_2(mRS), "texture0");
-            addInput(b.create());
-
-            return super.create();
-        }
-    }
-
-
-
-    public static class MatrixAllocation {
-        static final int MODELVIEW_OFFSET = 0;
-        static final int PROJECTION_OFFSET = 16;
-        static final int TEXTURE_OFFSET = 32;
-
-        Matrix4f mModel;
-        Matrix4f mProjection;
-        Matrix4f mTexture;
-
-        public Allocation mAlloc;
-        private FieldPacker mIOBuffer;
-
-        public MatrixAllocation(RenderScript rs) {
-            Type constInputType = ProgramVertex.Builder.getConstantInputType(rs);
-            mAlloc = Allocation.createTyped(rs, constInputType);
-            int bufferSize = constInputType.getElement().getSizeBytes()*
-                             constInputType.getCount();
-            mIOBuffer = new FieldPacker(bufferSize);
-            loadModelview(new Matrix4f());
-            loadProjection(new Matrix4f());
-            loadTexture(new Matrix4f());
-        }
-
-        public void destroy() {
-            mAlloc.destroy();
-            mAlloc = null;
-        }
-
-        private void addToBuffer(int offset, Matrix4f m) {
-            mIOBuffer.reset(offset);
-            for(int i = 0; i < 16; i ++) {
-                mIOBuffer.addF32(m.mMat[i]);
-            }
-            mAlloc.copyFrom(mIOBuffer.getData());
-        }
-
-        public void loadModelview(Matrix4f m) {
-            mModel = m;
-            addToBuffer(MODELVIEW_OFFSET*4, m);
-        }
-
-        public void loadProjection(Matrix4f m) {
-            mProjection = m;
-            addToBuffer(PROJECTION_OFFSET*4, m);
-        }
-
-        public void loadTexture(Matrix4f m) {
-            mTexture = m;
-            addToBuffer(TEXTURE_OFFSET*4, m);
-        }
-
-        public void setupOrthoWindow(int w, int h) {
-            mProjection.loadOrtho(0,w, h,0, -1,1);
-            addToBuffer(PROJECTION_OFFSET*4, mProjection);
-        }
-
-        public void setupOrthoNormalized(int w, int h) {
-            // range -1,1 in the narrow axis.
-            if(w > h) {
-                float aspect = ((float)w) / h;
-                mProjection.loadOrtho(-aspect,aspect,  -1,1,  -1,1);
-            } else {
-                float aspect = ((float)h) / w;
-                mProjection.loadOrtho(-1,1, -aspect,aspect,  -1,1);
-            }
-            addToBuffer(PROJECTION_OFFSET*4, mProjection);
-        }
-
-        public void setupProjectionNormalized(int w, int h) {
-            // range -1,1 in the narrow axis at z = 0.
-            Matrix4f m1 = new Matrix4f();
-            Matrix4f m2 = new Matrix4f();
-
-            if(w > h) {
-                float aspect = ((float)w) / h;
-                m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
-            } else {
-                float aspect = ((float)h) / w;
-                m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
-            }
-
-            m2.loadRotate(180, 0, 1, 0);
-            m1.loadMultiply(m1, m2);
-
-            m2.loadScale(-2, 2, 1);
-            m1.loadMultiply(m1, m2);
-
-            m2.loadTranslate(0, 0, 2);
-            m1.loadMultiply(m1, m2);
-
-            mProjection = m1;
-            addToBuffer(PROJECTION_OFFSET*4, mProjection);
-        }
-
-    }
-
 }
-
diff --git a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
new file mode 100644
index 0000000..2240dd7
--- /dev/null
+++ b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2008 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 android.renderscript;
+
+
+import android.graphics.Matrix;
+import android.util.Config;
+import android.util.Log;
+
+
+/**
+ * @hide
+ *
+ **/
+public class ProgramVertexFixedFunction extends ProgramVertex {
+
+    ProgramVertexFixedFunction(int id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    public void bindConstants(Constants va) {
+        mRS.validate();
+        bindConstants(va.getAllocation(), 0);
+    }
+
+    static class InternalBuilder extends BaseProgramBuilder {
+        public InternalBuilder(RenderScript rs) {
+            super(rs);
+        }
+
+        public InternalBuilder addInput(Element e) throws IllegalStateException {
+            // Should check for consistant and non-conflicting names...
+            if(mInputCount >= MAX_INPUT) {
+                throw new RSIllegalArgumentException("Max input count exceeded.");
+            }
+            if (e.isComplex()) {
+                throw new RSIllegalArgumentException("Complex elements not allowed.");
+            }
+            mInputs[mInputCount++] = e;
+            return this;
+        }
+
+        public ProgramVertexFixedFunction create() {
+            mRS.validate();
+            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
+            int idx = 0;
+
+            for (int i=0; i < mInputCount; i++) {
+                tmp[idx++] = ProgramParam.INPUT.mID;
+                tmp[idx++] = mInputs[i].getID();
+            }
+            for (int i=0; i < mOutputCount; i++) {
+                tmp[idx++] = ProgramParam.OUTPUT.mID;
+                tmp[idx++] = mOutputs[i].getID();
+            }
+            for (int i=0; i < mConstantCount; i++) {
+                tmp[idx++] = ProgramParam.CONSTANT.mID;
+                tmp[idx++] = mConstants[i].getID();
+            }
+            for (int i=0; i < mTextureCount; i++) {
+                tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
+                tmp[idx++] = mTextureTypes[i].mID;
+            }
+
+            int id = mRS.nProgramVertexCreate(mShader, tmp);
+            ProgramVertexFixedFunction pv = new ProgramVertexFixedFunction(id, mRS);
+            initProgram(pv);
+            return pv;
+        }
+    }
+
+    public static class Builder {
+        boolean mTextureMatrixEnable;
+        String mShader;
+        RenderScript mRS;
+
+        public Builder(RenderScript rs) {
+            mRS = rs;
+        }
+
+        public Builder setTextureMatrixEnable(boolean enable) {
+            mTextureMatrixEnable = enable;
+            return this;
+        }
+        static Type getConstantInputType(RenderScript rs) {
+            Element.Builder b = new Element.Builder(rs);
+            b.add(Element.MATRIX4X4(rs), "MV");
+            b.add(Element.MATRIX4X4(rs), "P");
+            b.add(Element.MATRIX4X4(rs), "TexMatrix");
+            b.add(Element.MATRIX4X4(rs), "MVP");
+
+            Type.Builder typeBuilder = new Type.Builder(rs, b.create());
+            typeBuilder.setX(1);
+            return typeBuilder.create();
+        }
+
+        private void buildShaderString() {
+
+            mShader  = "//rs_shader_internal\n";
+            mShader += "varying vec4 varColor;\n";
+            mShader += "varying vec2 varTex0;\n";
+
+            mShader += "void main() {\n";
+            mShader += "  gl_Position = UNI_MVP * ATTRIB_position;\n";
+            mShader += "  gl_PointSize = 1.0;\n";
+
+            mShader += "  varColor = ATTRIB_color;\n";
+            if (mTextureMatrixEnable) {
+                mShader += "  varTex0 = (UNI_TexMatrix * vec4(ATTRIB_texture0, 0.0, 1.0)).xy;\n";
+            } else {
+                mShader += "  varTex0 = ATTRIB_texture0;\n";
+            }
+            mShader += "}\n";
+        }
+
+        public ProgramVertexFixedFunction create() {
+            buildShaderString();
+
+            InternalBuilder sb = new InternalBuilder(mRS);
+            sb.setShader(mShader);
+            sb.addConstant(getConstantInputType(mRS));
+
+            Element.Builder b = new Element.Builder(mRS);
+            b.add(Element.F32_4(mRS), "position");
+            b.add(Element.F32_4(mRS), "color");
+            b.add(Element.F32_3(mRS), "normal");
+            b.add(Element.F32_2(mRS), "texture0");
+            sb.addInput(b.create());
+
+            return sb.create();
+        }
+    }
+
+    public static class Constants {
+        static final int MODELVIEW_OFFSET = 0;
+        static final int PROJECTION_OFFSET = 16;
+        static final int TEXTURE_OFFSET = 32;
+
+        Matrix4f mModel;
+        Matrix4f mProjection;
+        Matrix4f mTexture;
+
+        Allocation mAlloc;
+        Allocation getAllocation() {
+            return mAlloc;
+        }
+        private FieldPacker mIOBuffer;
+
+        public Constants(RenderScript rs) {
+            Type constInputType = ProgramVertexFixedFunction.Builder.getConstantInputType(rs);
+            mAlloc = Allocation.createTyped(rs, constInputType);
+            int bufferSize = constInputType.getElement().getSizeBytes()*
+                             constInputType.getCount();
+            mIOBuffer = new FieldPacker(bufferSize);
+            mModel = new Matrix4f();
+            mProjection = new Matrix4f();
+            mTexture = new Matrix4f();
+            setModelview(new Matrix4f());
+            setProjection(new Matrix4f());
+            setTexture(new Matrix4f());
+        }
+
+        public void destroy() {
+            mAlloc.destroy();
+            mAlloc = null;
+        }
+
+        private void addToBuffer(int offset, Matrix4f m) {
+            mIOBuffer.reset(offset);
+            for(int i = 0; i < 16; i ++) {
+                mIOBuffer.addF32(m.mMat[i]);
+            }
+            mAlloc.copyFrom(mIOBuffer.getData());
+        }
+
+        public void setModelview(Matrix4f m) {
+            mModel.load(m);
+            addToBuffer(MODELVIEW_OFFSET*4, m);
+        }
+
+        public void setProjection(Matrix4f m) {
+            mProjection.load(m);
+            addToBuffer(PROJECTION_OFFSET*4, m);
+        }
+
+        public void setTexture(Matrix4f m) {
+            mTexture.load(m);
+            addToBuffer(TEXTURE_OFFSET*4, m);
+        }
+    }
+}
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 16ad55a..2d16e32 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -589,16 +589,8 @@
 
     ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST;
     ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
-    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_TEST;
-    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_WRITE;
     ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST;
     ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
-    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST;
-    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE;
-    ProgramStore mProgramStore_BLEND_ADD_DEPTH_TEST;
-    ProgramStore mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH;
-    ProgramStore mProgramStore_BLEND_ADD_DEPTH_NO_TEST;
-    ProgramStore mProgramStore_BLEND_ADD_DEPTH_NO_WRITE;
 
     ProgramRaster mProgramRaster_CULL_BACK;
     ProgramRaster mProgramRaster_CULL_FRONT;
diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java
index 45a3949..6faa206 100644
--- a/graphics/java/android/renderscript/Sampler.java
+++ b/graphics/java/android/renderscript/Sampler.java
@@ -65,8 +65,8 @@
     public static Sampler CLAMP_NEAREST(RenderScript rs) {
         if(rs.mSampler_CLAMP_NEAREST == null) {
             Builder b = new Builder(rs);
-            b.setMin(Value.NEAREST);
-            b.setMag(Value.NEAREST);
+            b.setMinification(Value.NEAREST);
+            b.setMagnification(Value.NEAREST);
             b.setWrapS(Value.CLAMP);
             b.setWrapT(Value.CLAMP);
             rs.mSampler_CLAMP_NEAREST = b.create();
@@ -85,8 +85,8 @@
     public static Sampler CLAMP_LINEAR(RenderScript rs) {
         if(rs.mSampler_CLAMP_LINEAR == null) {
             Builder b = new Builder(rs);
-            b.setMin(Value.LINEAR);
-            b.setMag(Value.LINEAR);
+            b.setMinification(Value.LINEAR);
+            b.setMagnification(Value.LINEAR);
             b.setWrapS(Value.CLAMP);
             b.setWrapT(Value.CLAMP);
             rs.mSampler_CLAMP_LINEAR = b.create();
@@ -105,8 +105,8 @@
     public static Sampler CLAMP_LINEAR_MIP_LINEAR(RenderScript rs) {
         if(rs.mSampler_CLAMP_LINEAR_MIP_LINEAR == null) {
             Builder b = new Builder(rs);
-            b.setMin(Value.LINEAR_MIP_LINEAR);
-            b.setMag(Value.LINEAR);
+            b.setMinification(Value.LINEAR_MIP_LINEAR);
+            b.setMagnification(Value.LINEAR);
             b.setWrapS(Value.CLAMP);
             b.setWrapT(Value.CLAMP);
             rs.mSampler_CLAMP_LINEAR_MIP_LINEAR = b.create();
@@ -125,8 +125,8 @@
     public static Sampler WRAP_NEAREST(RenderScript rs) {
         if(rs.mSampler_WRAP_NEAREST == null) {
             Builder b = new Builder(rs);
-            b.setMin(Value.NEAREST);
-            b.setMag(Value.NEAREST);
+            b.setMinification(Value.NEAREST);
+            b.setMagnification(Value.NEAREST);
             b.setWrapS(Value.WRAP);
             b.setWrapT(Value.WRAP);
             rs.mSampler_WRAP_NEAREST = b.create();
@@ -145,8 +145,8 @@
     public static Sampler WRAP_LINEAR(RenderScript rs) {
         if(rs.mSampler_WRAP_LINEAR == null) {
             Builder b = new Builder(rs);
-            b.setMin(Value.LINEAR);
-            b.setMag(Value.LINEAR);
+            b.setMinification(Value.LINEAR);
+            b.setMagnification(Value.LINEAR);
             b.setWrapS(Value.WRAP);
             b.setWrapT(Value.WRAP);
             rs.mSampler_WRAP_LINEAR = b.create();
@@ -165,8 +165,8 @@
     public static Sampler WRAP_LINEAR_MIP_LINEAR(RenderScript rs) {
         if(rs.mSampler_WRAP_LINEAR_MIP_LINEAR == null) {
             Builder b = new Builder(rs);
-            b.setMin(Value.LINEAR_MIP_LINEAR);
-            b.setMag(Value.LINEAR);
+            b.setMinification(Value.LINEAR_MIP_LINEAR);
+            b.setMagnification(Value.LINEAR);
             b.setWrapS(Value.WRAP);
             b.setWrapT(Value.WRAP);
             rs.mSampler_WRAP_LINEAR_MIP_LINEAR = b.create();
@@ -199,7 +199,7 @@
             mAniso = 1.0f;
         }
 
-        public void setMin(Value v) {
+        public void setMinification(Value v) {
             if (v == Value.NEAREST ||
                 v == Value.LINEAR ||
                 v == Value.LINEAR_MIP_LINEAR ||
@@ -210,7 +210,7 @@
             }
         }
 
-        public void setMag(Value v) {
+        public void setMagnification(Value v) {
             if (v == Value.NEAREST || v == Value.LINEAR) {
                 mMag = v;
             } else {
@@ -234,14 +234,6 @@
             }
         }
 
-        public void setWrapR(Value v) {
-            if (v == Value.WRAP || v == Value.CLAMP) {
-                mWrapR = v;
-            } else {
-                throw new IllegalArgumentException("Invalid value");
-            }
-        }
-
         public void setAnisotropy(float v) {
             if(v >= 0.0f) {
                 mAniso = v;
diff --git a/include/binder/CursorWindow.h b/include/binder/CursorWindow.h
index 4fbff2a..f0b2909 100644
--- a/include/binder/CursorWindow.h
+++ b/include/binder/CursorWindow.h
@@ -25,7 +25,6 @@
 #include <utils/RefBase.h>
 
 #define DEFAULT_WINDOW_SIZE 4096
-#define MAX_WINDOW_SIZE (1024 * 1024)
 #define WINDOW_ALLOCATION_SIZE 4096
 
 #define ROW_SLOT_CHUNK_NUM_ROWS 16
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 1c93ea6..00de39b 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -60,9 +60,7 @@
 }
 
 void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
-    SkPixelRef* pixref = bitmapResource->pixelRef();
-    if (pixref) pixref->globalRef();
-
+    bitmapResource->pixelRef()->safeRef();
     bitmapResource->getColorTable()->safeRef();
     incrementRefcount((void*)bitmapResource, kBitmap);
 }
@@ -91,9 +89,7 @@
 }
 
 void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
-    SkPixelRef* pixref = bitmapResource->pixelRef();
-    if (pixref) pixref->globalUnref();
-
+    bitmapResource->pixelRef()->safeUnref();
     bitmapResource->getColorTable()->safeUnref();
     decrementRefcount((void*)bitmapResource);
 }
diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
index 0a06394..50ee921 100644
--- a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
+++ b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
@@ -50,7 +50,7 @@
     private void createProgramVertex() {
         updateProjectionMatrices();
 
-        ProgramVertex.ShaderBuilder sb = new ProgramVertex.ShaderBuilder(mRS);
+        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
         String t =  "varying vec4 varColor;\n" +
                     "void main() {\n" +
                     "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
@@ -75,18 +75,27 @@
         return allocation;
     }
 
+    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
+        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+        builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
+        builder.setDitherEnabled(false);
+        builder.setDepthMaskEnabled(false);
+        return builder.create();
+    }
+
     public void init(RenderScriptGL rs, Resources res, int width, int height) {
         mRS = rs;
         mRes = res;
 
-        ProgramFragment.Builder pfb = new ProgramFragment.Builder(rs);
+        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
         pfb.setPointSpriteTexCoordinateReplacement(true);
-        pfb.setTexture(ProgramFragment.Builder.EnvMode.MODULATE,
-                           ProgramFragment.Builder.Format.RGBA, 0);
+        pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
+                           ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
         pfb.setVaryingColor(true);
         mPFPoints = pfb.create();
 
-        pfb = new ProgramFragment.Builder(rs);
+        pfb = new ProgramFragmentFixedFunction.Builder(rs);
         pfb.setVaryingColor(true);
         mPFLines = pfb.create();
 
@@ -97,7 +106,7 @@
 
         Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
         smb.addVertexAllocation(mPoints.getAllocation());
-        smb.addIndexType(Primitive.POINT);
+        smb.addIndexSetType(Mesh.Primitive.POINT);
         Mesh smP = smb.create();
 
         mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics);
@@ -113,7 +122,7 @@
         mScript.set_gPFPoints(mPFPoints);
         createProgramVertex();
 
-        mRS.bindProgramStore(ProgramStore.BLEND_ADD_DEPTH_NO_DEPTH(mRS));
+        mRS.bindProgramStore(BLEND_ADD_DEPTH_NONE(mRS));
 
         mPhysicsScript.set_gMinPos(new Float2(5, 5));
         mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5));
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
index a5d06e9..be2f9ca 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -34,7 +34,7 @@
         mRS = rs;
         mRes = res;
 
-        ProgramFragment.Builder pfb = new ProgramFragment.Builder(rs);
+        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
         pfb.setVaryingColor(true);
         rs.bindProgramFragment(pfb.create());
 
@@ -43,7 +43,7 @@
 
         Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
         smb.addVertexAllocation(points.getAllocation());
-        smb.addIndexType(Primitive.POINT);
+        smb.addIndexSetType(Mesh.Primitive.POINT);
         Mesh sm = smb.create();
 
         mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
index 7d99686..f91f31e 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
@@ -54,7 +54,7 @@
     private ProgramStore mPSBackground;
     private ProgramFragment mPFBackground;
     private ProgramVertex mPVBackground;
-    private ProgramVertex.MatrixAllocation mPVA;
+    private ProgramVertexFixedFunction.Constants mPVA;
 
     private Allocation mGridImage;
     private Allocation mAllocPV;
@@ -94,8 +94,8 @@
         ProgramStore.Builder b = new ProgramStore.Builder(mRS);
 
         b.setDepthFunc(ProgramStore.DepthFunc.LESS);
-        b.setDitherEnable(false);
-        b.setDepthMask(true);
+        b.setDitherEnabled(false);
+        b.setDepthMaskEnabled(true);
         mPSBackground = b.create();
 
         mScript.set_gPFSBackground(mPSBackground);
@@ -103,15 +103,15 @@
 
     private void initPF() {
         Sampler.Builder bs = new Sampler.Builder(mRS);
-        bs.setMin(Sampler.Value.LINEAR);
-        bs.setMag(Sampler.Value.LINEAR);
+        bs.setMinification(Sampler.Value.LINEAR);
+        bs.setMagnification(Sampler.Value.LINEAR);
         bs.setWrapS(Sampler.Value.CLAMP);
         bs.setWrapT(Sampler.Value.CLAMP);
         mSampler = bs.create();
 
-        ProgramFragment.Builder b = new ProgramFragment.Builder(mRS);
-        b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
-                     ProgramFragment.Builder.Format.RGBA, 0);
+        ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
+        b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                     ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
         mPFBackground = b.create();
         mPFBackground.bindSampler(mSampler, 0);
 
@@ -119,11 +119,11 @@
     }
 
     private void initPV() {
-        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS);
+        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
         mPVBackground = pvb.create();
 
-        mPVA = new ProgramVertex.MatrixAllocation(mRS);
-        mPVBackground.bindAllocation(mPVA);
+        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
+        ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA);
 
         mScript.set_gPVBackground(mPVBackground);
     }
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
index 5451ca1..b18a327 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
@@ -50,7 +50,7 @@
     private ProgramStore mPSBackground;
     private ProgramFragment mPFBackground;
     private ProgramVertex mPVBackground;
-    private ProgramVertex.MatrixAllocation mPVA;
+    private ProgramVertexFixedFunction.Constants mPVA;
 
     private Allocation mGridImage;
     private Allocation mAllocPV;
@@ -89,8 +89,8 @@
         ProgramStore.Builder b = new ProgramStore.Builder(mRS);
 
         b.setDepthFunc(ProgramStore.DepthFunc.LESS);
-        b.setDitherEnable(false);
-        b.setDepthMask(true);
+        b.setDitherEnabled(false);
+        b.setDepthMaskEnabled(true);
         mPSBackground = b.create();
 
         mScript.set_gPFSBackground(mPSBackground);
@@ -98,15 +98,15 @@
 
     private void initPF() {
         Sampler.Builder bs = new Sampler.Builder(mRS);
-        bs.setMin(Sampler.Value.LINEAR);
-        bs.setMag(Sampler.Value.LINEAR);
+        bs.setMinification(Sampler.Value.LINEAR);
+        bs.setMagnification(Sampler.Value.LINEAR);
         bs.setWrapS(Sampler.Value.CLAMP);
         bs.setWrapT(Sampler.Value.CLAMP);
         mSampler = bs.create();
 
-        ProgramFragment.Builder b = new ProgramFragment.Builder(mRS);
-        b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
-                     ProgramFragment.Builder.Format.RGBA, 0);
+        ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
+        b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                     ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
         mPFBackground = b.create();
         mPFBackground.bindSampler(mSampler, 0);
 
@@ -114,11 +114,11 @@
     }
 
     private void initPV() {
-        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS);
+        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
         mPVBackground = pvb.create();
 
-        mPVA = new ProgramVertex.MatrixAllocation(mRS);
-        mPVBackground.bindAllocation(mPVA);
+        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
+        ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA);
 
         mScript.set_gPVBackground(mPVBackground);
     }
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
index b3e8026..5430a13 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
@@ -26,6 +26,8 @@
 import android.renderscript.Allocation.MipmapControl;
 import android.renderscript.Program.TextureType;
 import android.renderscript.ProgramStore.DepthFunc;
+import android.renderscript.ProgramStore.BlendSrcFunc;
+import android.renderscript.ProgramStore.BlendDstFunc;
 import android.renderscript.Sampler.Value;
 import android.util.Log;
 
@@ -69,7 +71,7 @@
     private ProgramFragment mProgFragmentColor;
 
     private ProgramVertex mProgVertex;
-    private ProgramVertex.MatrixAllocation mPVA;
+    private ProgramVertexFixedFunction.Constants mPVA;
 
     // Custom shaders
     private ProgramVertex mProgVertexCustom;
@@ -122,6 +124,15 @@
         mScript.set_gDisplayMode(mMode);
     }
 
+    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
+        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+        builder.setDitherEnabled(false);
+        builder.setDepthMaskEnabled(false);
+        return builder.create();
+    }
+
     private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
 
         Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
@@ -155,18 +166,18 @@
     private void initProgramStore() {
         // Use stock the stock program store object
         mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
-        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NO_DEPTH(mRS);
+        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
 
         // Create a custom program store
         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
         builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
         builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
                              ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-        builder.setDitherEnable(false);
-        builder.setDepthMask(false);
+        builder.setDitherEnabled(false);
+        builder.setDepthMaskEnabled(false);
         mProgStoreBlendAlpha = builder.create();
 
-        mProgStoreBlendAdd = ProgramStore.BLEND_ADD_DEPTH_NO_DEPTH(mRS);
+        mProgStoreBlendAdd = BLEND_ADD_DEPTH_NONE(mRS);
 
         mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
         mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
@@ -176,13 +187,13 @@
 
     private void initProgramFragment() {
 
-        ProgramFragment.Builder texBuilder = new ProgramFragment.Builder(mRS);
-        texBuilder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
-                              ProgramFragment.Builder.Format.RGBA, 0);
+        ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
+        texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                              ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
         mProgFragmentTexture = texBuilder.create();
         mProgFragmentTexture.bindSampler(mLinearClamp, 0);
 
-        ProgramFragment.Builder colBuilder = new ProgramFragment.Builder(mRS);
+        ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
         colBuilder.setVaryingColor(false);
         mProgFragmentColor = colBuilder.create();
 
@@ -191,12 +202,14 @@
     }
 
     private void initProgramVertex() {
-        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS);
+        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
         mProgVertex = pvb.create();
 
-        mPVA = new ProgramVertex.MatrixAllocation(mRS);
-        mProgVertex.bindAllocation(mPVA);
-        mPVA.setupOrthoWindow(mWidth, mHeight);
+        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
+        ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
+        Matrix4f proj = new Matrix4f();
+        proj.loadOrthoWindow(mWidth, mHeight);
+        mPVA.setProjection(proj);
 
         mScript.set_gProgVertex(mProgVertex);
     }
@@ -213,7 +226,7 @@
         mScript.bind_gFSConstPixel(mFSConstPixel);
 
         // Initialize the shader builder
-        ProgramVertex.ShaderBuilder pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS);
         // Specify the resource that contains the shader string
         pvbCustom.setShader(mRes, R.raw.shaderv);
         // Use a script field to specify the input layout
@@ -224,7 +237,7 @@
         // Bind the source of constant data
         mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0);
 
-        ProgramFragment.ShaderBuilder pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS);
         // Specify the resource that contains the shader string
         pfbCustom.setShader(mRes, R.raw.shaderf);
         // Tell the builder how many textures we have
@@ -236,42 +249,44 @@
         mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
 
         // Cubemap test shaders
-        pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        pvbCustom = new ProgramVertex.Builder(mRS);
         pvbCustom.setShader(mRes, R.raw.shadercubev);
         pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
         pvbCustom.addConstant(mVSConst.getAllocation().getType());
         mProgVertexCube = pvbCustom.create();
         mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
 
-        pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        pfbCustom = new ProgramFragment.Builder(mRS);
         pfbCustom.setShader(mRes, R.raw.shadercubef);
         pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
         mProgFragmentCube = pfbCustom.create();
 
-        pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        pvbCustom = new ProgramVertex.Builder(mRS);
         pvbCustom.setShader(mRes, R.raw.shader2v);
         pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
         pvbCustom.addConstant(mVSConstPixel.getAllocation().getType());
         mProgVertexPixelLight = pvbCustom.create();
         mProgVertexPixelLight.bindConstants(mVSConstPixel.getAllocation(), 0);
 
-        pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        pvbCustom = new ProgramVertex.Builder(mRS);
         pvbCustom.setShader(mRes, R.raw.shader2movev);
         pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
         pvbCustom.addConstant(mVSConstPixel.getAllocation().getType());
         mProgVertexPixelLightMove = pvbCustom.create();
         mProgVertexPixelLightMove.bindConstants(mVSConstPixel.getAllocation(), 0);
 
-        pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        pfbCustom = new ProgramFragment.Builder(mRS);
         pfbCustom.setShader(mRes, R.raw.shader2f);
         pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
         pfbCustom.addConstant(mFSConstPixel.getAllocation().getType());
         mProgFragmentPixelLight = pfbCustom.create();
         mProgFragmentPixelLight.bindConstants(mFSConstPixel.getAllocation(), 0);
 
-        pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        pfbCustom = new ProgramFragment.Builder(mRS);
         pfbCustom.setShader(mRes, R.raw.multitexf);
-        pfbCustom.setTextureCount(3);
+        for (int texCount = 0; texCount < 3; texCount ++) {
+            pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
+        }
         mProgFragmentMultitex = pfbCustom.create();
 
         mScript.set_gProgVertexCustom(mProgVertexCustom);
@@ -354,8 +369,8 @@
 
     private void initSamplers() {
         Sampler.Builder bs = new Sampler.Builder(mRS);
-        bs.setMin(Sampler.Value.LINEAR);
-        bs.setMag(Sampler.Value.LINEAR);
+        bs.setMinification(Sampler.Value.LINEAR);
+        bs.setMagnification(Sampler.Value.LINEAR);
         bs.setWrapS(Sampler.Value.WRAP);
         bs.setWrapT(Sampler.Value.WRAP);
         mLinearWrap = bs.create();
@@ -365,8 +380,8 @@
         mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
 
         bs = new Sampler.Builder(mRS);
-        bs.setMin(Sampler.Value.LINEAR_MIP_LINEAR);
-        bs.setMag(Sampler.Value.LINEAR);
+        bs.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
+        bs.setMagnification(Sampler.Value.LINEAR);
         bs.setWrapS(Sampler.Value.WRAP);
         bs.setWrapT(Sampler.Value.WRAP);
         bs.setAnisotropy(8.0f);
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
index 636a486..cac105a 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
@@ -26,6 +26,8 @@
 import android.renderscript.Font.Style;
 import android.renderscript.Program.TextureType;
 import android.renderscript.ProgramStore.DepthFunc;
+import android.renderscript.ProgramStore.BlendSrcFunc;
+import android.renderscript.ProgramStore.BlendDstFunc;
 import android.renderscript.Sampler.Value;
 import android.util.Log;
 
@@ -69,7 +71,7 @@
     private ProgramFragment mProgFragmentColor;
 
     private ProgramVertex mProgVertex;
-    private ProgramVertex.MatrixAllocation mPVA;
+    private ProgramVertexFixedFunction.Constants mPVA;
 
     // Custom shaders
     private ProgramVertex mProgVertexCustom;
@@ -120,6 +122,15 @@
         mScript.set_gDisplayMode(mMode);
     }
 
+    ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
+        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+        builder.setDitherEnabled(false);
+        builder.setDepthMaskEnabled(false);
+        return builder.create();
+    }
+
     private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
 
         Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
@@ -153,18 +164,18 @@
     private void initProgramStore() {
         // Use stock the stock program store object
         mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
-        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NO_DEPTH(mRS);
+        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
 
         // Create a custom program store
         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
         builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
         builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
                              ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-        builder.setDitherEnable(false);
-        builder.setDepthMask(false);
+        builder.setDitherEnabled(false);
+        builder.setDepthMaskEnabled(false);
         mProgStoreBlendAlpha = builder.create();
 
-        mProgStoreBlendAdd = ProgramStore.BLEND_ADD_DEPTH_NO_DEPTH(mRS);
+        mProgStoreBlendAdd = BLEND_ADD_DEPTH_NONE(mRS);
 
         mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
         mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
@@ -174,13 +185,13 @@
 
     private void initProgramFragment() {
 
-        ProgramFragment.Builder texBuilder = new ProgramFragment.Builder(mRS);
-        texBuilder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
-                              ProgramFragment.Builder.Format.RGBA, 0);
+        ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
+        texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                              ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
         mProgFragmentTexture = texBuilder.create();
         mProgFragmentTexture.bindSampler(mLinearClamp, 0);
 
-        ProgramFragment.Builder colBuilder = new ProgramFragment.Builder(mRS);
+        ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
         colBuilder.setVaryingColor(false);
         mProgFragmentColor = colBuilder.create();
 
@@ -189,12 +200,14 @@
     }
 
     private void initProgramVertex() {
-        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS);
+        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
         mProgVertex = pvb.create();
 
-        mPVA = new ProgramVertex.MatrixAllocation(mRS);
-        mProgVertex.bindAllocation(mPVA);
-        mPVA.setupOrthoWindow(mWidth, mHeight);
+        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
+        ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
+        Matrix4f proj = new Matrix4f();
+        proj.loadOrthoWindow(mWidth, mHeight);
+        mPVA.setProjection(proj);
 
         mScript.set_gProgVertex(mProgVertex);
     }
@@ -211,7 +224,7 @@
         mScript.bind_gFSConstants2(mFSConst2);
 
         // Initialize the shader builder
-        ProgramVertex.ShaderBuilder pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS);
         // Specify the resource that contains the shader string
         pvbCustom.setShader(mRes, R.raw.shaderv);
         // Use a script field to spcify the input layout
@@ -222,47 +235,49 @@
         // Bind the source of constant data
         mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0);
 
-        ProgramFragment.ShaderBuilder pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS);
         // Specify the resource that contains the shader string
         pfbCustom.setShader(mRes, R.raw.shaderf);
         //Tell the builder how many textures we have
-        pfbCustom.setTextureCount(1);
+        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
         // Define the constant input layout
         pfbCustom.addConstant(mFSConst.getAllocation().getType());
         mProgFragmentCustom = pfbCustom.create();
         // Bind the source of constant data
         mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
 
-        pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        pvbCustom = new ProgramVertex.Builder(mRS);
         pvbCustom.setShader(mRes, R.raw.shaderarrayv);
         pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
         pvbCustom.addConstant(mVSConst2.getAllocation().getType());
         mProgVertexCustom2 = pvbCustom.create();
         mProgVertexCustom2.bindConstants(mVSConst2.getAllocation(), 0);
 
-        pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        pfbCustom = new ProgramFragment.Builder(mRS);
         pfbCustom.setShader(mRes, R.raw.shaderarrayf);
-        pfbCustom.setTextureCount(1);
+        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
         pfbCustom.addConstant(mFSConst2.getAllocation().getType());
         mProgFragmentCustom2 = pfbCustom.create();
         mProgFragmentCustom2.bindConstants(mFSConst2.getAllocation(), 0);
 
         // Cubemap test shaders
-        pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        pvbCustom = new ProgramVertex.Builder(mRS);
         pvbCustom.setShader(mRes, R.raw.shadercubev);
         pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
         pvbCustom.addConstant(mVSConst.getAllocation().getType());
         mProgVertexCube = pvbCustom.create();
         mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
 
-        pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        pfbCustom = new ProgramFragment.Builder(mRS);
         pfbCustom.setShader(mRes, R.raw.shadercubef);
         pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
         mProgFragmentCube = pfbCustom.create();
 
-        pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        pfbCustom = new ProgramFragment.Builder(mRS);
         pfbCustom.setShader(mRes, R.raw.multitexf);
-        pfbCustom.setTextureCount(3);
+        for (int texCount = 0; texCount < 3; texCount ++) {
+            pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
+        }
         mProgFragmentMultitex = pfbCustom.create();
 
         mScript.set_gProgVertexCustom(mProgVertexCustom);
@@ -340,8 +355,8 @@
 
     private void initSamplers() {
         Sampler.Builder bs = new Sampler.Builder(mRS);
-        bs.setMin(Sampler.Value.LINEAR);
-        bs.setMag(Sampler.Value.LINEAR);
+        bs.setMinification(Sampler.Value.LINEAR);
+        bs.setMagnification(Sampler.Value.LINEAR);
         bs.setWrapS(Sampler.Value.WRAP);
         bs.setWrapT(Sampler.Value.WRAP);
         mLinearWrap = bs.create();
@@ -351,8 +366,8 @@
         mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
 
         bs = new Sampler.Builder(mRS);
-        bs.setMin(Sampler.Value.LINEAR_MIP_LINEAR);
-        bs.setMag(Sampler.Value.LINEAR);
+        bs.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
+        bs.setMagnification(Sampler.Value.LINEAR);
         bs.setWrapS(Sampler.Value.WRAP);
         bs.setWrapT(Sampler.Value.WRAP);
         bs.setAnisotropy(8.0f);
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index fb5980a..48a0969 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -287,24 +287,6 @@
     static_cast<Allocation *>(va)->syncAll(rsc, source);
 }
 
-static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
-}
-
-static void SC_uploadToTexture(RsAllocation va) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    rsi_AllocationUploadToTexture(rsc, va, false, 0);
-}
-
-static void SC_uploadToBufferObject(RsAllocation va) {
-    CHECK_OBJ(va);
-    GET_TLS();
-    rsi_AllocationUploadToBufferObject(rsc, va);
-}
-
 static void SC_ClearColor(float r, float g, float b, float a) {
     GET_TLS();
     rsc->setupProgramStore();
@@ -439,10 +421,6 @@
 
     { "_Z20rsgAllocationSyncAll13rs_allocation", (void *)&SC_allocationSyncAll, false },
 
-    { "_Z18rsgUploadToTexture13rs_allocationj", (void *)&SC_uploadToTexture2, false },
-    { "_Z18rsgUploadToTexture13rs_allocation", (void *)&SC_uploadToTexture, false },
-    { "_Z23rsgUploadToBufferObject13rs_allocation", (void *)&SC_uploadToBufferObject, false },
-
     { "_Z11rsgDrawRectfffff", (void *)&SC_drawRect, false },
     { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_drawQuad, false },
     { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_drawQuadTexCoords, false },
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index 3e708aa..3868f24 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -38,13 +38,6 @@
     rsgAllocationSyncAll(rs_allocation);
 
 extern void __attribute__((overloadable))
-    rsgUploadToTexture(rs_allocation);
-extern void __attribute__((overloadable))
-    rsgUploadToTexture(rs_allocation, uint mipLevel);
-extern void __attribute__((overloadable))
-    rsgUploadToBufferObject(rs_allocation);
-
-extern void __attribute__((overloadable))
     rsgDrawRect(float x1, float y1, float x2, float y2, float z);
 extern void __attribute__((overloadable))
     rsgDrawQuad(float x1, float y1, float z1,
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 39c4a28..db308c7 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -188,11 +188,12 @@
 
         /** The following formats are audio only .aac or .amr formats **/
         /** @deprecated  Deprecated in favor of AMR_NB */
-        /** TODO: change link when AMR_NB is exposed. Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB */
+        /** Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB */
+        /** AMR NB file format */
         public static final int RAW_AMR = 3;
-        /** @hide AMR NB file format */
+        /** AMR NB file format */
         public static final int AMR_NB = 3;
-        /** @hide AMR WB file format */
+        /** AMR WB file format */
         public static final int AMR_WB = 4;
         /** @hide AAC ADIF file format */
         public static final int AAC_ADIF = 5;
@@ -218,9 +219,9 @@
         public static final int DEFAULT = 0;
         /** AMR (Narrowband) audio codec */
         public static final int AMR_NB = 1;
-        /** @hide AMR (Wideband) audio codec */
+        /** AMR (Wideband) audio codec */
         public static final int AMR_WB = 2;
-        /** @hide AAC audio codec */
+        /** AAC audio codec */
         public static final int AAC = 3;
         /** @hide enhanced AAC audio codec */
         public static final int AAC_PLUS = 4;
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 9662817..4ccdd9a 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -22,6 +22,20 @@
 #include <utils/Log.h>
 #include <utils/threads.h>
 #include <core/SkBitmap.h>
+
+// Please do not enable "USE_PRIVATE_NATIVE_BITMAP_CONSTUCTOR"
+// This mode will be removed and it is kept here for
+// convenient comparsion just in case. Will be removed soon.
+// Tests show that this mode is also ~30ms slower,
+// when rotation is involved.
+#define USE_PRIVATE_NATIVE_BITMAP_CONSTUCTOR 0
+
+#if (!USE_PRIVATE_NATIVE_BITMAP_CONSTUCTOR)
+#include <core/SkCanvas.h>
+#include <core/SkDevice.h>
+#include <core/SkScalar.h>
+#endif
+
 #include <media/mediametadataretriever.h>
 #include <private/media/VideoFrame.h>
 
@@ -35,8 +49,15 @@
 struct fields_t {
     jfieldID context;
     jclass bitmapClazz;
+#if USE_PRIVATE_NATIVE_BITMAP_CONSTUCTOR
     jmethodID bitmapConstructor;
+    jmethodID createBitmapRotationMethod;
+#else
+    jfieldID nativeBitmap;
     jmethodID createBitmapMethod;
+    jclass configClazz;
+    jmethodID createConfigMethod;
+#endif
 };
 
 static fields_t fields;
@@ -162,6 +183,12 @@
         return NULL;
     }
 
+    LOGV("Dimension = %dx%d and bytes = %d",
+            videoFrame->mDisplayWidth,
+            videoFrame->mDisplayHeight,
+            videoFrame->mSize);
+
+#if USE_PRIVATE_NATIVE_BITMAP_CONSTUCTOR
     jobject matrix = NULL;
     if (videoFrame->mRotationAngle != 0) {
         LOGD("Create a rotation matrix: %d degrees", videoFrame->mRotationAngle);
@@ -217,9 +244,9 @@
     jobject jSrcBitmap = env->NewObject(fields.bitmapClazz,
             fields.bitmapConstructor, (int) bitmap, NULL, true, NULL, -1);
 
-    LOGV("Return a new bitmap constructed with the rotation matrix");
-    return env->CallStaticObjectMethod(
-                fields.bitmapClazz, fields.createBitmapMethod,
+    jobject jBitmap = env->CallStaticObjectMethod(
+                fields.bitmapClazz,
+                fields.createBitmapRotationMethod,
                 jSrcBitmap,                     // source Bitmap
                 0,                              // x
                 0,                              // y
@@ -227,6 +254,39 @@
                 videoFrame->mDisplayHeight,     // height
                 matrix,                         // transform matrix
                 false);                         // filter
+
+#else
+
+    jobject config = env->CallStaticObjectMethod(
+                        fields.configClazz,
+                        fields.createConfigMethod,
+                        SkBitmap::kRGB_565_Config);
+
+    jobject jBitmap = env->CallStaticObjectMethod(
+                            fields.bitmapClazz,
+                            fields.createBitmapMethod,
+                            videoFrame->mDisplayWidth,
+                            videoFrame->mDisplayHeight,
+                            config);
+    SkBitmap *bitmap =
+            (SkBitmap *) env->GetIntField(jBitmap, fields.nativeBitmap);
+
+    bitmap->lockPixels();
+
+    memcpy((uint8_t*)bitmap->getPixels(),
+            (uint8_t*)videoFrame + sizeof(VideoFrame), videoFrame->mSize);
+
+    bitmap->unlockPixels();
+
+    if (videoFrame->mRotationAngle != 0) {
+        SkDevice device(*bitmap);
+        SkCanvas canvas(&device);
+        canvas.rotate((SkScalar) (videoFrame->mRotationAngle * 1.0));
+        canvas.drawBitmap(*bitmap, 0, 0);
+    }
+#endif
+    LOGV("Return a new bitmap constructed with the rotation matrix");
+    return jBitmap;
 }
 
 static jbyteArray android_media_MediaMetadataRetriever_extractAlbumArt(JNIEnv *env, jobject thiz)
@@ -293,7 +353,6 @@
 static void android_media_MediaMetadataRetriever_native_finalize(JNIEnv *env, jobject thiz)
 {
     LOGV("native_finalize");
-    
     // No lock is needed, since android_media_MediaMetadataRetriever_release() is protected
     android_media_MediaMetadataRetriever_release(env, thiz);
 }
@@ -320,21 +379,52 @@
         jniThrowException(env, "java/lang/RuntimeException", "Can't find android/graphics/Bitmap");
         return;
     }
-
+#if USE_PRIVATE_NATIVE_BITMAP_CONSTUCTOR
     fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(I[BZ[BI)V");
     if (fields.bitmapConstructor == NULL) {
         jniThrowException(env, "java/lang/RuntimeException", "Can't find Bitmap constructor");
         return;
     }
-    fields.createBitmapMethod =
+    fields.createBitmapRotationMethod =
             env->GetStaticMethodID(fields.bitmapClazz, "createBitmap",
                     "(Landroid/graphics/Bitmap;IIIILandroid/graphics/Matrix;Z)"
                     "Landroid/graphics/Bitmap;");
-    if (fields.createBitmapMethod == NULL) {
+    if (fields.createBitmapRotationMethod == NULL) {
         jniThrowException(env, "java/lang/RuntimeException",
                 "Can't find Bitmap.createBitmap method");
         return;
     }
+#else
+    fields.createBitmapMethod =
+            env->GetStaticMethodID(fields.bitmapClazz, "createBitmap",
+                    "(IILandroid/graphics/Bitmap$Config;)"
+                    "Landroid/graphics/Bitmap;");
+    if (fields.createBitmapMethod == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException",
+                "Can't find Bitmap.createBitmap(int, int, Config)  method");
+        return;
+    }
+    fields.nativeBitmap = env->GetFieldID(fields.bitmapClazz, "mNativeBitmap", "I");
+    if (fields.nativeBitmap == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException",
+                "Can't find Bitmap.mNativeBitmap field");
+    }
+
+    fields.configClazz = env->FindClass("android/graphics/Bitmap$Config");
+    if (fields.configClazz == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException",
+                               "Can't find Bitmap$Config class");
+        return;
+    }
+    fields.createConfigMethod =
+            env->GetStaticMethodID(fields.configClazz, "nativeToConfig",
+                    "(I)Landroid/graphics/Bitmap$Config;");
+    if (fields.createConfigMethod == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException",
+                "Can't find Bitmap$Config.nativeToConfig(int)  method");
+        return;
+    }
+#endif
 }
 
 static void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobject thiz)
diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp
index 9738e33..4d4cd8d 100644
--- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp
+++ b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp
@@ -151,6 +151,7 @@
             const sp<AMessage> &notify);
 
     void start();
+    void stop();
     void readMore(bool flush = false);
 
 protected:
@@ -189,6 +190,10 @@
     readMore();
 }
 
+void DecoderWrapper::WrapperReader::stop() {
+    CHECK_EQ(mDecoder->stop(), (status_t)OK);
+}
+
 void DecoderWrapper::WrapperReader::readMore(bool flush) {
     if (!flush && mEOS) {
         return;
@@ -351,6 +356,10 @@
             onSetup(msg);
             break;
 
+        case kWhatShutdown:
+            onShutdown();
+            break;
+
         case kWhatInputDataRequested:
         {
             postFillBuffer();
@@ -493,6 +502,25 @@
     ++mNumPendingDecodes;
 }
 
+void DecoderWrapper::onShutdown() {
+    mReaderLooper->stop();
+    mReaderLooper.clear();
+
+    mReader->stop();
+    mReader.clear();
+
+    mSource.clear();
+
+    mNumOutstandingInputBuffers = 0;
+    mNumOutstandingOutputBuffers = 0;
+    mNumPendingDecodes = 0;
+    mFlushing = false;
+
+    sp<AMessage> notify = mNotify->dup();
+    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
+    notify->post();
+}
+
 void DecoderWrapper::postFillBuffer() {
     sp<AMessage> notify = mNotify->dup();
     notify->setInt32("what", ACodec::kWhatFillThisBuffer);
diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.h b/media/libmediaplayerservice/nuplayer/DecoderWrapper.h
index 883b356..b9be12c 100644
--- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.h
+++ b/media/libmediaplayerservice/nuplayer/DecoderWrapper.h
@@ -66,6 +66,7 @@
     bool mFlushing;
 
     void onSetup(const sp<AMessage> &msg);
+    void onShutdown();
     void onFlush();
     void onResume();
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index e99c24a..967fa49 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -23,6 +23,7 @@
 #include "NuPlayerRenderer.h"
 #include "NuPlayerStreamListener.h"
 
+#include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
@@ -75,6 +76,26 @@
     (new AMessage(kWhatStart, id()))->post();
 }
 
+// static
+bool NuPlayer::IsFlushingState(FlushStatus state, bool *formatChange) {
+    switch (state) {
+        case FLUSHING_DECODER:
+            if (formatChange != NULL) {
+                *formatChange = false;
+            }
+            return true;
+
+        case FLUSHING_DECODER_FORMATCHANGE:
+            if (formatChange != NULL) {
+                *formatChange = true;
+            }
+            return true;
+
+        default:
+            return false;
+    }
+}
+
 void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatSetDataSource:
@@ -132,10 +153,16 @@
 
         case kWhatScanSources:
         {
-            instantiateDecoder(false, &mVideoDecoder);
+            instantiateDecoder(
+                    false,
+                    &mVideoDecoder,
+                    false /* ignoreCodecSpecificData */);
 
             if (mAudioSink != NULL) {
-                instantiateDecoder(true, &mAudioDecoder);
+                instantiateDecoder(
+                        true,
+                        &mAudioDecoder,
+                        false /* ignoreCodecSpecificData */);
             }
 
             if (mEOS) {
@@ -172,32 +199,32 @@
             } else if (what == ACodec::kWhatEOS) {
                 mRenderer->queueEOS(audio, ERROR_END_OF_STREAM);
             } else if (what == ACodec::kWhatFlushCompleted) {
+                bool formatChange;
+
                 if (audio) {
-                    CHECK_EQ((int)mFlushingAudio, (int)FLUSHING_DECODER);
+                    CHECK(IsFlushingState(mFlushingAudio, &formatChange));
                     mFlushingAudio = FLUSHED;
                 } else {
-                    CHECK_EQ((int)mFlushingVideo, (int)FLUSHING_DECODER);
+                    CHECK(IsFlushingState(mFlushingVideo, &formatChange));
                     mFlushingVideo = FLUSHED;
                 }
 
                 LOGI("decoder %s flush completed", audio ? "audio" : "video");
 
-                if (mFlushingAudio == FLUSHED && mFlushingVideo == FLUSHED) {
-                    LOGI("both audio and video are flushed now.");
+                if (formatChange) {
+                    LOGI("initiating %s decoder shutdown",
+                         audio ? "audio" : "video");
 
-                    mRenderer->signalTimeDiscontinuity();
+                    (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
 
-                    if (mAudioDecoder != NULL) {
-                        mAudioDecoder->signalResume();
+                    if (audio) {
+                        mFlushingAudio = SHUTTING_DOWN_DECODER;
+                    } else {
+                        mFlushingVideo = SHUTTING_DOWN_DECODER;
                     }
-
-                    if (mVideoDecoder != NULL) {
-                        mVideoDecoder->signalResume();
-                    }
-
-                    mFlushingAudio = NONE;
-                    mFlushingVideo = NONE;
                 }
+
+                finishFlushIfPossible();
             } else if (what == ACodec::kWhatOutputFormatChanged) {
                 CHECK(audio);
 
@@ -213,6 +240,23 @@
                 mAudioSink->close();
                 CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
                 mAudioSink->start();
+
+                mRenderer->signalAudioSinkChanged();
+            } else if (what == ACodec::kWhatShutdownCompleted) {
+                LOGI("%s shutdown completed", audio ? "audio" : "video");
+                if (audio) {
+                    mAudioDecoder.clear();
+
+                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
+                    mFlushingAudio = SHUT_DOWN;
+                } else {
+                    mVideoDecoder.clear();
+
+                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
+                    mFlushingVideo = SHUT_DOWN;
+                }
+
+                finishFlushIfPossible();
             } else {
                 CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer);
 
@@ -265,6 +309,43 @@
     }
 }
 
+void NuPlayer::finishFlushIfPossible() {
+    if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
+        return;
+    }
+
+    if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
+        return;
+    }
+
+    LOGI("both audio and video are flushed now.");
+
+    mRenderer->signalTimeDiscontinuity();
+
+    if (mFlushingAudio == SHUT_DOWN) {
+        instantiateDecoder(
+                true,
+                &mAudioDecoder,
+                true /* ignoreCodecSpecificData */);
+        CHECK(mAudioDecoder != NULL);
+    } else if (mAudioDecoder != NULL) {
+        mAudioDecoder->signalResume();
+    }
+
+    if (mFlushingVideo == SHUT_DOWN) {
+        instantiateDecoder(
+                false,
+                &mVideoDecoder,
+                true /* ignoreCodecSpecificData */);
+        CHECK(mVideoDecoder != NULL);
+    } else if (mVideoDecoder != NULL) {
+        mVideoDecoder->signalResume();
+    }
+
+    mFlushingAudio = NONE;
+    mFlushingVideo = NONE;
+}
+
 void NuPlayer::feedMoreTSData() {
     CHECK(!mEOS);
 
@@ -285,7 +366,10 @@
         } else {
             if (buffer[0] == 0x00) {
                 // XXX legacy
-                mTSParser->signalDiscontinuity(ATSParser::DISCONTINUITY_SEEK);
+                mTSParser->signalDiscontinuity(
+                        buffer[1] == 0x00
+                            ? ATSParser::DISCONTINUITY_SEEK
+                            : ATSParser::DISCONTINUITY_FORMATCHANGE);
             } else {
                 mTSParser->feedTSPacket(buffer, sizeof(buffer));
             }
@@ -354,7 +438,7 @@
 }
 
 status_t NuPlayer::instantiateDecoder(
-        bool audio, sp<Decoder> *decoder) {
+        bool audio, sp<Decoder> *decoder, bool ignoreCodecSpecificData) {
     if (*decoder != NULL) {
         return OK;
     }
@@ -378,7 +462,7 @@
     looper()->registerHandler(*decoder);
 
     const sp<MetaData> &meta = source->getFormat();
-    (*decoder)->configure(meta);
+    (*decoder)->configure(meta, ignoreCodecSpecificData);
 
     return OK;
 }
@@ -387,8 +471,8 @@
     sp<AMessage> reply;
     CHECK(msg->findMessage("reply", &reply));
 
-    if ((audio && mFlushingAudio == FLUSHING_DECODER)
-            || (!audio && mFlushingVideo == FLUSHING_DECODER)) {
+    if ((audio && IsFlushingState(mFlushingAudio))
+            || (!audio && IsFlushingState(mFlushingVideo))) {
         reply->setInt32("err", INFO_DISCONTINUITY);
         reply->post();
         return OK;
@@ -403,14 +487,25 @@
         return err;
     } else if (err != OK) {
         if (err == INFO_DISCONTINUITY) {
-            LOGI("%s discontinuity", audio ? "audio" : "video");
+            int32_t formatChange;
+            if (!accessUnit->meta()->findInt32(
+                        "format-change", &formatChange)) {
+                formatChange = 0;
+            }
+
+            LOGI("%s discontinuity (formatChange=%d)",
+                 audio ? "audio" : "video", formatChange);
+
             (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
             mRenderer->flush(audio);
 
             if (audio) {
                 CHECK(mFlushingAudio == NONE
                         || mFlushingAudio == AWAITING_DISCONTINUITY);
-                mFlushingAudio = FLUSHING_DECODER;
+
+                mFlushingAudio = formatChange
+                    ? FLUSHING_DECODER_FORMATCHANGE : FLUSHING_DECODER;
+
                 if (mFlushingVideo == NONE) {
                     mFlushingVideo = (mVideoDecoder != NULL)
                         ? AWAITING_DISCONTINUITY
@@ -419,7 +514,10 @@
             } else {
                 CHECK(mFlushingVideo == NONE
                         || mFlushingVideo == AWAITING_DISCONTINUITY);
-                mFlushingVideo = FLUSHING_DECODER;
+
+                mFlushingVideo = formatChange
+                    ? FLUSHING_DECODER_FORMATCHANGE : FLUSHING_DECODER;
+
                 if (mFlushingAudio == NONE) {
                     mFlushingAudio = (mAudioDecoder != NULL)
                         ? AWAITING_DISCONTINUITY
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 9a5a6c4..d4e7428 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -79,14 +79,17 @@
         NONE,
         AWAITING_DISCONTINUITY,
         FLUSHING_DECODER,
-        FLUSHED
+        FLUSHING_DECODER_FORMATCHANGE,
+        SHUTTING_DOWN_DECODER,
+        FLUSHED,
+        SHUT_DOWN,
     };
 
     FlushStatus mFlushingAudio;
     FlushStatus mFlushingVideo;
 
     status_t instantiateDecoder(
-            bool audio, sp<Decoder> *decoder);
+            bool audio, sp<Decoder> *decoder, bool ignoreCodecSpecificData);
 
     status_t feedDecoderInputData(bool audio, const sp<AMessage> &msg);
     void renderBuffer(bool audio, const sp<AMessage> &msg);
@@ -100,6 +103,10 @@
     void feedMoreTSData();
     void notifyListener(int msg, int ext1, int ext2);
 
+    void finishFlushIfPossible();
+
+    static bool IsFlushingState(FlushStatus state, bool *formatChange = NULL);
+
     DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
 };
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index d1ed222..1d78808 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -42,7 +42,8 @@
 NuPlayer::Decoder::~Decoder() {
 }
 
-void NuPlayer::Decoder::configure(const sp<MetaData> &meta) {
+void NuPlayer::Decoder::configure(
+        const sp<MetaData> &meta, bool ignoreCodecSpecificData) {
     CHECK(mCodec == NULL);
     CHECK(mWrapper == NULL);
 
@@ -54,6 +55,10 @@
 
     sp<AMessage> format = makeFormat(meta);
 
+    if (ignoreCodecSpecificData) {
+        mCSD.clear();
+    }
+
     if (mSurface != NULL) {
         format->setObject("surface", mSurface);
     }
@@ -282,5 +287,14 @@
     }
 }
 
+void NuPlayer::Decoder::initiateShutdown() {
+    if (mCodec != NULL) {
+        mCodec->initiateShutdown();
+    } else {
+        CHECK(mWrapper != NULL);
+        mWrapper->initiateShutdown();
+    }
+}
+
 }  // namespace android
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index 77800be..07fe47e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -29,9 +29,12 @@
 struct NuPlayer::Decoder : public AHandler {
     Decoder(const sp<AMessage> &notify, const sp<Surface> &surface = NULL);
 
-    void configure(const sp<MetaData> &meta);
+    void configure(
+            const sp<MetaData> &meta, bool ignoreCodecSpecificData);
+
     void signalFlush();
     void signalResume();
+    void initiateShutdown();
 
 protected:
     virtual ~Decoder();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 855bc0a..57a652c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -39,7 +39,9 @@
       mAnchorTimeRealUs(-1),
       mFlushingAudio(false),
       mFlushingVideo(false),
-      mSyncQueues(true) {
+      mHasAudio(mAudioSink != NULL),
+      mHasVideo(true),
+      mSyncQueues(mHasAudio && mHasVideo) {
 }
 
 NuPlayer::Renderer::~Renderer() {
@@ -87,7 +89,7 @@
     CHECK(mVideoQueue.empty());
     mAnchorTimeMediaUs = -1;
     mAnchorTimeRealUs = -1;
-    mSyncQueues = true;
+    mSyncQueues = mHasAudio && mHasVideo;
 }
 
 void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
@@ -142,6 +144,12 @@
             break;
         }
 
+        case kWhatAudioSinkChanged:
+        {
+            onAudioSinkChanged();
+            break;
+        }
+
         default:
             TRESPASS();
             break;
@@ -163,6 +171,10 @@
     msg->post(10000);
 }
 
+void NuPlayer::Renderer::signalAudioSinkChanged() {
+    (new AMessage(kWhatAudioSinkChanged, id()))->post();
+}
+
 void NuPlayer::Renderer::onDrainAudioQueue() {
     uint32_t numFramesPlayed;
     CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
@@ -264,7 +276,7 @@
         if (mAnchorTimeMediaUs < 0) {
             delayUs = 0;
 
-            if (mAudioSink == NULL) {
+            if (!mHasAudio) {
                 mAnchorTimeMediaUs = mediaTimeUs;
                 mAnchorTimeRealUs = ALooper::GetNowUs();
             }
@@ -492,5 +504,10 @@
     return true;
 }
 
+void NuPlayer::Renderer::onAudioSinkChanged() {
+    CHECK(!mDrainAudioQueuePending);
+    mNumFramesWritten = 0;
+}
+
 }  // namespace android
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 834ddc5..eaa004a 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -37,6 +37,8 @@
 
     void signalTimeDiscontinuity();
 
+    void signalAudioSinkChanged();
+
     enum {
         kWhatEOS,
         kWhatFlushComplete,
@@ -54,6 +56,7 @@
         kWhatQueueBuffer,
         kWhatQueueEOS,
         kWhatFlush,
+        kWhatAudioSinkChanged,
     };
 
     struct QueueEntry {
@@ -81,6 +84,8 @@
     bool mFlushingAudio;
     bool mFlushingVideo;
 
+    bool mHasAudio;
+    bool mHasVideo;
     bool mSyncQueues;
 
     void onDrainAudioQueue();
@@ -92,6 +97,7 @@
     void onQueueBuffer(const sp<AMessage> &msg);
     void onQueueEOS(const sp<AMessage> &msg);
     void onFlush(const sp<AMessage> &msg);
+    void onAudioSinkChanged();
 
     void notifyEOS(bool audio);
     void notifyFlushComplete(bool audio);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 77276ab..3bb61f2 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1157,6 +1157,9 @@
     if (!msg->findObject("buffer", &obj)) {
         CHECK(msg->findInt32("err", &err));
 
+        LOGV("[%s] saw error %d instead of an input buffer",
+             mCodec->mComponentName.c_str(), err);
+
         obj.clear();
     }
 
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 2f3353b..b1c6b18 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -573,7 +573,7 @@
 }
 
 status_t CameraSource::stop() {
-    LOGV("stop");
+    LOGD("stop: E");
     Mutex::Autolock autoLock(mLock);
     mStarted = false;
     mFrameAvailableCondition.signal();
@@ -581,9 +581,11 @@
     int64_t token = IPCThreadState::self()->clearCallingIdentity();
     releaseQueuedFrames();
     while (!mFramesBeingEncoded.empty()) {
-        LOGI("Waiting for outstanding frames being encoded: %d",
+        if (NO_ERROR !=
+            mFrameCompleteCondition.waitRelative(mLock, 3000000000LL)) {
+            LOGW("Timed out waiting for outstanding frames being encoded: %d",
                 mFramesBeingEncoded.size());
-        mFrameCompleteCondition.wait(mLock);
+        }
     }
     stopCameraRecording();
     releaseCamera();
@@ -601,6 +603,7 @@
     }
 
     CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
+    LOGD("stop: X");
     return OK;
 }
 
@@ -666,7 +669,11 @@
     {
         Mutex::Autolock autoLock(mLock);
         while (mStarted && mFramesReceived.empty()) {
-            mFrameAvailableCondition.wait(mLock);
+            if (NO_ERROR !=
+                mFrameAvailableCondition.waitRelative(mLock, 3000000000LL)) {
+                LOGW("Timed out waiting for incoming camera video frames: %lld us",
+                    mLastFrameTimestampUs);
+            }
         }
         if (!mStarted) {
             return OK;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 352f9fb..f63774a 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -3361,7 +3361,15 @@
     }
 
     while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
-        mBufferFilled.wait(mLock);
+        if (mIsEncoder) {
+            if (NO_ERROR != mBufferFilled.waitRelative(mLock, 3000000000LL)) {
+                LOGW("Timed out waiting for buffers from video encoder: %d/%d",
+                    countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
+                    countBuffersWeOwn(mPortBuffers[kPortIndexOutput]));
+            }
+        } else {
+            mBufferFilled.wait(mLock);
+        }
     }
 
     if (mState == ERROR) {
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 30ac404..5c4c5df 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -179,9 +179,9 @@
 
     if (!strncasecmp(url, "file://", 7)) {
         source = new FileSource(url + 7);
+    } else if (strncasecmp(url, "http://", 7)) {
+        return ERROR_UNSUPPORTED;
     } else {
-        CHECK(!strncasecmp(url, "http://", 7));
-
         status_t err = mHTTPDataSource->connect(url);
 
         if (err != OK) {
@@ -468,13 +468,16 @@
         return;
     }
 
-    if (explicitDiscontinuity
-            || (mPrevBandwidthIndex >= 0
-                && (size_t)mPrevBandwidthIndex != bandwidthIndex)) {
+    bool bandwidthChanged =
+        mPrevBandwidthIndex >= 0
+            && (size_t)mPrevBandwidthIndex != bandwidthIndex;
+
+    if (explicitDiscontinuity || bandwidthChanged) {
         // Signal discontinuity.
 
         sp<ABuffer> tmp = new ABuffer(188);
         memset(tmp->data(), 0, tmp->size());
+        tmp->data()[1] = bandwidthChanged;
 
         mDataSource->queueBuffer(tmp);
     }
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 38a7cc5..95f6741 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -84,12 +84,13 @@
     out->clear();
 
     if (strncasecmp("http://", baseURL, 7)
+            && strncasecmp("https://", baseURL, 8)
             && strncasecmp("file://", baseURL, 7)) {
         // Base URL must be absolute
         return false;
     }
 
-    if (!strncasecmp("http://", url, 7)) {
+    if (!strncasecmp("http://", url, 7) || !strncasecmp("https://", url, 8)) {
         // "url" is already an absolute URL, ignore base URL.
         out->setTo(url);
 
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index de6346b..ee9b5739 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -284,7 +284,7 @@
     : mProgram(program),
       mElementaryPID(elementaryPID),
       mStreamType(streamType),
-      mBuffer(new ABuffer(128 * 1024)),
+      mBuffer(new ABuffer(192 * 1024)),
       mPayloadStarted(false),
       mQueue(streamType == 0x1b
               ? ElementaryStreamQueue::H264 : ElementaryStreamQueue::AAC) {
@@ -334,7 +334,7 @@
 
             if (mStreamType == 0x1b && mSource != NULL) {
                 // Don't signal discontinuities on audio streams.
-                mSource->queueDiscontinuity();
+                mSource->queueDiscontinuity(true /* formatChange */);
             }
             break;
         }
@@ -348,7 +348,7 @@
 
             if (mSource != NULL) {
                 mSource->clear();
-                mSource->queueDiscontinuity();
+                mSource->queueDiscontinuity(!isASeek);
             }
             break;
         }
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 7a1d5b0..a8fe2c1 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -63,8 +63,6 @@
         int32_t discontinuity;
         if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity)
                 && discontinuity) {
-            buffer->clear();
-
             return INFO_DISCONTINUITY;
         }
 
@@ -125,10 +123,14 @@
     mCondition.signal();
 }
 
-void AnotherPacketSource::queueDiscontinuity() {
+void AnotherPacketSource::queueDiscontinuity(bool formatChange) {
     sp<ABuffer> buffer = new ABuffer(0);
     buffer->meta()->setInt32("discontinuity", true);
 
+    if (formatChange) {
+        buffer->meta()->setInt32("format-change", true);
+    }
+
     Mutex::Autolock autoLock(mLock);
 
     mBuffers.push_back(buffer);
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index 2bc7404..f25a067 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -42,7 +42,7 @@
     status_t nextBufferTime(int64_t *timeUs);
 
     void queueAccessUnit(const sp<ABuffer> &buffer);
-    void queueDiscontinuity();
+    void queueDiscontinuity(bool formatChange);
     void signalEOS(status_t result);
 
     void clear();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
index 2d6ae0d..f5e677d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
@@ -174,7 +174,7 @@
         switch (visibility) {
             case ID_IME_BUTTON_VISIBILITY_AUTO:
                 return size > 1 || (size == 1
-                        && mImm.getEnabledInputMethodSubtypeList(imis.get(0)).size() > 1);
+                        && mImm.getEnabledInputMethodSubtypeList(imis.get(0), false).size() > 1);
             case ID_IME_BUTTON_VISIBILITY_ALWAYS_SHOW:
                 return true;
             case ID_IME_BUTTON_VISIBILITY_ALWAYS_HIDE:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index edcf096..3c665fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -58,9 +58,9 @@
     private static final int COLLAPSE_DURATION = 360;
     private static final String TAG = "RecentAppsPanel";
     private static final boolean DEBUG = TabletStatusBar.DEBUG;
-    private static final int DISPLAY_TASKS_PORTRAIT = 8;
+    private static final int DISPLAY_TASKS_PORTRAIT = 7; // Limited by max binder transaction size
     private static final int DISPLAY_TASKS_LANDSCAPE = 5; // number of recent tasks to display
-    private static final int MAX_TASKS = DISPLAY_TASKS_PORTRAIT + 2; // allow extra for non-apps
+    private static final int MAX_TASKS = DISPLAY_TASKS_PORTRAIT + 1; // allow extra for non-apps
     private static final int STAGGER_ANIMATION_DELAY = 30;
     private static final long ALPHA_ANIMATION_DURATION = 120;
     private TabletStatusBar mBar;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c6984a4..2e89a21 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2360,15 +2360,27 @@
             Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                     .getDefaultDisplay();
             if (d.getWidth() > d.getHeight()) {
-                mPortraitRotation = Surface.ROTATION_90;
                 mLandscapeRotation = Surface.ROTATION_0;
-                mUpsideDownRotation = Surface.ROTATION_270;
                 mSeascapeRotation = Surface.ROTATION_180;
+                if (mContext.getResources().getBoolean(
+                        com.android.internal.R.bool.config_reverseDefaultRotation)) {
+                    mPortraitRotation = Surface.ROTATION_90;
+                    mUpsideDownRotation = Surface.ROTATION_270;
+                } else {
+                    mPortraitRotation = Surface.ROTATION_270;
+                    mUpsideDownRotation = Surface.ROTATION_90;
+                }
             } else {
                 mPortraitRotation = Surface.ROTATION_0;
-                mLandscapeRotation = Surface.ROTATION_90;
                 mUpsideDownRotation = Surface.ROTATION_180;
-                mSeascapeRotation = Surface.ROTATION_270;
+                if (mContext.getResources().getBoolean(
+                        com.android.internal.R.bool.config_reverseDefaultRotation)) {
+                    mLandscapeRotation = Surface.ROTATION_270;
+                    mSeascapeRotation = Surface.ROTATION_90;
+                } else {
+                    mLandscapeRotation = Surface.ROTATION_90;
+                    mSeascapeRotation = Surface.ROTATION_270;
+                }
             }
         }
 
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index f82a243..e7e4302 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -16,8 +16,7 @@
 
 package com.android.server;
 
-import android.app.Notification;
-import android.app.NotificationManager;
+import android.bluetooth.BluetoothTetheringDataTracker;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -26,9 +25,9 @@
 import android.net.ConnectivityManager;
 import android.net.DummyDataStateTracker;
 import android.net.IConnectivityManager;
+import android.net.LinkProperties;
 import android.net.MobileDataStateTracker;
 import android.net.NetworkInfo;
-import android.net.LinkProperties;
 import android.net.NetworkStateTracker;
 import android.net.NetworkUtils;
 import android.net.Proxy;
@@ -50,7 +49,6 @@
 import android.util.Slog;
 
 import com.android.internal.telephony.Phone;
-
 import com.android.server.connectivity.Tethering;
 
 import java.io.FileDescriptor;
@@ -58,7 +56,6 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.InetAddress;
-import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -412,6 +409,10 @@
                         mNetAttributes[netType].mName);
                 mNetTrackers[netType].startMonitoring(context, mHandler);
                 break;
+            case ConnectivityManager.TYPE_BLUETOOTH:
+                mNetTrackers[netType] = BluetoothTetheringDataTracker.getInstance();
+                mNetTrackers[netType].startMonitoring(context, mHandler);
+                break;
             default:
                 loge("Trying to create a DataStateTracker for an unknown radio type " +
                         mNetAttributes[netType].mRadio);
@@ -1097,6 +1098,7 @@
                     // gotten a positive report we don't want to overwrite, but if not we need to
                     // clear this now to turn our cellular sig strength white
                     mDefaultInetConditionPublished = 0;
+                    intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
                 }
                 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
             } else {
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 9c56a2a..7ed9187 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -118,9 +118,6 @@
 
     private static final int NOT_A_SUBTYPE_ID = -1;
     private static final String NOT_A_SUBTYPE_ID_STR = String.valueOf(NOT_A_SUBTYPE_ID);
-    // If IME doesn't support the system locale, the default subtype will be the first defined one.
-    private static final int DEFAULT_SUBTYPE_ID = 0;
-
     private static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
     private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
     private static final String SUBTYPE_MODE_VOICE = "voice";
@@ -566,12 +563,19 @@
         }
     }
 
-    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi) {
+    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi,
+            boolean allowsImplicitlySelectedSubtypes) {
         synchronized (mMethodMap) {
             if (imi == null && mCurMethodId != null) {
                 imi = mMethodMap.get(mCurMethodId);
             }
-            return mSettings.getEnabledInputMethodSubtypeListLocked(imi);
+            final List<InputMethodSubtype> enabledSubtypes =
+                    mSettings.getEnabledInputMethodSubtypeListLocked(imi);
+            if (!allowsImplicitlySelectedSubtypes || enabledSubtypes.size() > 0) {
+                return enabledSubtypes;
+            } else {
+                return getApplicableSubtypesLocked(imi.getSubtypes());
+            }
         }
     }
 
@@ -1665,6 +1669,22 @@
         synchronized (mMethodMap) {
             final List<Pair<InputMethodInfo, ArrayList<String>>> immis =
                     mSettings.getEnabledInputMethodAndSubtypeHashCodeListLocked();
+            int N = immis.size();
+
+            // Add applicable subtypes if no subtype for each IME is enabled.
+            for (int i = 0; i < N; ++i) {
+                InputMethodInfo imi = immis.get(i).first;
+                ArrayList<String> subtypes = immis.get(i).second;
+                if (subtypes != null && subtypes.size() == 0) {
+                    ArrayList<InputMethodSubtype> applicableSubtypes =
+                            getApplicableSubtypesLocked(imi.getSubtypes());
+                    final int numSubtypes = applicableSubtypes.size();
+                    for (int j = 0; j < numSubtypes; ++j) {
+                        subtypes.add(String.valueOf(applicableSubtypes.get(j).hashCode()));
+                    }
+                }
+            }
+
             ArrayList<Integer> subtypeIds = new ArrayList<Integer>();
 
             if (immis == null || immis.size() == 0) {
@@ -1673,7 +1693,6 @@
 
             hideInputMethodMenuLocked();
 
-            int N = immis.size();
 
             final Map<CharSequence, Pair<InputMethodInfo, Integer>> imMap =
                 new TreeMap<CharSequence, Pair<InputMethodInfo, Integer>>(Collator.getInstance());
@@ -1960,18 +1979,46 @@
         return NOT_A_SUBTYPE_ID;
     }
 
+    private ArrayList<InputMethodSubtype> getApplicableSubtypesLocked(
+            List<InputMethodSubtype> subtypes) {
+        ArrayList<InputMethodSubtype> applicableSubtypes = new ArrayList<InputMethodSubtype>();
+        final String systemLocale = mRes.getConfiguration().locale.toString();
+        if (TextUtils.isEmpty(systemLocale)) return applicableSubtypes;
+        final int N = subtypes.size();
+        boolean containsKeyboardSubtype = false;
+        for (int i = 0; i < N; ++i) {
+            InputMethodSubtype subtype = subtypes.get(i);
+            if (subtype.getLocale().equals(systemLocale)) {
+                applicableSubtypes.add(subtype);
+                if (!containsKeyboardSubtype
+                        && SUBTYPE_MODE_KEYBOARD.equalsIgnoreCase(subtype.getMode())) {
+                    containsKeyboardSubtype = true;
+                }
+            }
+        }
+        if (!containsKeyboardSubtype) {
+            InputMethodSubtype lastResortKeyboardSubtype = findLastResortApplicableSubtypeLocked(
+                    subtypes, SUBTYPE_MODE_KEYBOARD, systemLocale, true);
+            if (lastResortKeyboardSubtype != null) {
+                applicableSubtypes.add(lastResortKeyboardSubtype);
+            }
+        }
+        return applicableSubtypes;
+    }
+
     /**
      * If there are no selected subtypes, tries finding the most applicable one according to the
      * given locale.
      * @param subtypes this function will search the most applicable subtype in subtypes
      * @param mode subtypes will be filtered by mode
      * @param locale subtypes will be filtered by locale
-     * @param defaultSubtypeId if this function can't find the most applicable subtype, it will
-     * return defaultSubtypeId
+     * @param canIgnoreLocaleAsLastResort if this function can't find the most applicable subtype,
+     * it will return the first subtype matched with mode
      * @return the most applicable subtypeId
      */
     private InputMethodSubtype findLastResortApplicableSubtypeLocked(
-            List<InputMethodSubtype> subtypes, String mode, String locale, int defaultSubtypeId) {
+            List<InputMethodSubtype> subtypes, String mode, String locale,
+            boolean canIgnoreLocaleAsLastResort) {
         if (subtypes == null || subtypes.size() == 0) {
             return null;
         }
@@ -1981,11 +2028,16 @@
         final String language = locale.substring(0, 2);
         boolean partialMatchFound = false;
         InputMethodSubtype applicableSubtype = null;
-        for (int i = 0; i < subtypes.size(); ++i) {
+        InputMethodSubtype firstMatchedModeSubtype = null;
+        final int N = subtypes.size();
+        for (int i = 0; i < N; ++i) {
             InputMethodSubtype subtype = subtypes.get(i);
             final String subtypeLocale = subtype.getLocale();
             // An applicable subtype should match "mode".
             if (subtypes.get(i).getMode().equalsIgnoreCase(mode)) {
+                if (firstMatchedModeSubtype == null) {
+                    firstMatchedModeSubtype = subtype;
+                }
                 if (locale.equals(subtypeLocale)) {
                     // Exact match (e.g. system locale is "en_US" and subtype locale is "en_US")
                     applicableSubtype = subtype;
@@ -1998,11 +2050,17 @@
             }
         }
 
+        if (applicableSubtype == null && canIgnoreLocaleAsLastResort) {
+            return firstMatchedModeSubtype;
+        }
+
         // The first subtype applicable to the system locale will be defined as the most applicable
         // subtype.
         if (DEBUG) {
-            Slog.d(TAG, "Applicable InputMethodSubtype was found: " + applicableSubtype.getMode()
-                    + "," + applicableSubtype.getLocale());
+            if (applicableSubtype != null) {
+                Slog.d(TAG, "Applicable InputMethodSubtype was found: "
+                        + applicableSubtype.getMode() + "," + applicableSubtype.getLocale());
+            }
         }
         return applicableSubtype;
     }
@@ -2017,44 +2075,49 @@
 
         // Search applicable subtype for each InputMethodInfo
         for (InputMethodInfo imi: imis) {
+            final String imiId = imi.getId();
+            if (foundInSystemIME && !imiId.equals(mCurMethodId)) {
+                continue;
+            }
             InputMethodSubtype subtype = null;
+            final List<InputMethodSubtype> explicitlyEnabledSubtypes =
+                    mSettings.getEnabledInputMethodSubtypeListLocked(imi);
+            // 1. Search by the current subtype's locale from explicitlyEnabledSubtypes.
             if (mCurrentSubtype != null) {
-                // 1. Search with the current subtype's locale and the enabled subtypes
                 subtype = findLastResortApplicableSubtypeLocked(
-                        mSettings.getEnabledInputMethodSubtypeListLocked(
-                        imi), mode, mCurrentSubtype.getLocale(), NOT_A_SUBTYPE_ID);
-                if (subtype == null) {
-                    // 2. Search with the current subtype's locale and all subtypes
-                    subtype = findLastResortApplicableSubtypeLocked(imi.getSubtypes(),
-                            mode, mCurrentSubtype.getLocale(), NOT_A_SUBTYPE_ID);
-                }
+                        explicitlyEnabledSubtypes, mode, mCurrentSubtype.getLocale(), false);
             }
-            // 3. Search with the system locale and the enabled subtypes
+            // 2. Search by the system locale from explicitlyEnabledSubtypes.
+            // 3. Search the first enabled subtype matched with mode from explicitlyEnabledSubtypes.
             if (subtype == null) {
                 subtype = findLastResortApplicableSubtypeLocked(
-                        mSettings.getEnabledInputMethodSubtypeListLocked(
-                        imi), mode, null, NOT_A_SUBTYPE_ID);
+                        explicitlyEnabledSubtypes, mode, null, true);
             }
+            // 4. Search by the current subtype's locale from all subtypes.
+            if (subtype == null && mCurrentSubtype != null) {
+                subtype = findLastResortApplicableSubtypeLocked(
+                        imi.getSubtypes(), mode, mCurrentSubtype.getLocale(), false);
+            }
+            // 5. Search by the system locale from all subtypes.
+            // 6. Search the first enabled subtype matched with mode from all subtypes.
             if (subtype == null) {
-                // 4. Search with the system locale and all subtypes
-                subtype = findLastResortApplicableSubtypeLocked(imi.getSubtypes(),
-                        mode, null, NOT_A_SUBTYPE_ID);
+                subtype = findLastResortApplicableSubtypeLocked(
+                        imi.getSubtypes(), mode, null, true);
             }
             if (subtype != null) {
-                if (imi.getId().equals(mCurMethodId)) {
+                if (imiId.equals(mCurMethodId)) {
                     // The current input method is the most applicable IME.
                     mostApplicableIMI = imi;
                     mostApplicableSubtype = subtype;
                     break;
-                } else if ((imi.getServiceInfo().applicationInfo.flags
-                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                } else if (!foundInSystemIME) {
                     // The system input method is 2nd applicable IME.
                     mostApplicableIMI = imi;
                     mostApplicableSubtype = subtype;
-                    foundInSystemIME = true;
-                } else if (!foundInSystemIME) {
-                    mostApplicableIMI = imi;
-                    mostApplicableSubtype = subtype;
+                    if ((imi.getServiceInfo().applicationInfo.flags
+                            & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                        foundInSystemIME = true;
+                    }
                 }
             }
         }
@@ -2100,7 +2163,7 @@
                         // SUBTYPE_MODE_KEYBOARD. This is an exceptional case, so we will hardcode
                         // the mode.
                         mCurrentSubtype = findLastResortApplicableSubtypeLocked(imi.getSubtypes(),
-                                SUBTYPE_MODE_KEYBOARD, null, DEFAULT_SUBTYPE_ID);
+                                SUBTYPE_MODE_KEYBOARD, null, true);
                     }
                 } else {
                     mCurrentSubtype =
@@ -2132,7 +2195,9 @@
                 Pair<InputMethodInfo, InputMethodSubtype> info =
                     findLastResortApplicableShortcutInputMethodAndSubtypeLocked(
                             SUBTYPE_MODE_VOICE);
-                addShortcutInputMethodAndSubtypes(info.first, info.second);
+                if (info != null) {
+                    addShortcutInputMethodAndSubtypes(info.first, info.second);
+                }
             }
             ArrayList<Object> ret = new ArrayList<Object>();
             for (InputMethodInfo imi: mShortcutInputMethodsAndSubtypes.keySet()) {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 748f2e9..94ed813 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -6814,6 +6814,11 @@
         // Input channel
         InputChannel mInputChannel;
         
+        // Used to improve performance of toString()
+        String mStringNameCache;
+        CharSequence mLastTitle;
+        boolean mWasPaused;
+
         WindowState(Session s, IWindow c, WindowToken token,
                WindowState attachedWindow, WindowManager.LayoutParams a,
                int viewVisibility) {
@@ -8131,9 +8136,14 @@
 
         @Override
         public String toString() {
-            return "Window{"
-                + Integer.toHexString(System.identityHashCode(this))
-                + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
+            if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
+                    || mWasPaused != mToken.paused) {
+                mLastTitle = mAttrs.getTitle();
+                mWasPaused = mToken.paused;
+                mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
+                        + " " + mLastTitle + " paused=" + mWasPaused + "}";
+            }
+            return mStringNameCache;
         }
     }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index a26fe5f..4cf01aa 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -129,7 +129,6 @@
 import java.io.PrintWriter;
 import java.lang.IllegalStateException;
 import java.lang.ref.WeakReference;
-import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -2314,8 +2313,12 @@
     }
 
     final void addRecentTaskLocked(TaskRecord task) {
-        // Remove any existing entries that are the same kind of task.
         int N = mRecentTasks.size();
+        // Quick case: check if the top-most recent task is the same.
+        if (N > 0 && mRecentTasks.get(0) == task) {
+            return;
+        }
+        // Remove any existing entries that are the same kind of task.
         for (int i=0; i<N; i++) {
             TaskRecord tr = mRecentTasks.get(i);
             if ((task.affinity != null && task.affinity.equals(tr.affinity))
@@ -11746,14 +11749,9 @@
         
         if (starting != null) {
             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
-            if (kept) {
-                // If this didn't result in the starting activity being
-                // destroyed, then we need to make sure at this point that all
-                // other activities are made visible.
-                if (DEBUG_SWITCH) Slog.i(TAG, "Config didn't destroy " + starting
-                        + ", ensuring others are correct.");
-                mMainStack.ensureActivitiesVisibleLocked(starting, changes);
-            }
+            // And we need to make sure at this point that all other activities
+            // are made visible with the correct configuration.
+            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
         }
         
         if (values != null && mWindowManager != null) {
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index b4e426f..caaae1f 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -413,7 +413,7 @@
         // an application, and that application is not blocked or unresponding.
         // In any other case, we can't count on getting the screen unfrozen,
         // so it is best to leave as-is.
-        return app == null || (!app.crashing && !app.notResponding);
+        return app != null && !app.crashing && !app.notResponding;
     }
     
     public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 516dfa2..eee9f7e 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -572,6 +572,9 @@
             r.stopped = false;
             mResumedActivity = r;
             r.task.touchActiveTime();
+            if (mMainStack) {
+                mService.addRecentTaskLocked(r.task);
+            }
             completeResumeLocked(r);
             pauseIfSleepingLocked();                
         } else {
@@ -1249,6 +1252,9 @@
             next.state = ActivityState.RESUMED;
             mResumedActivity = next;
             next.task.touchActiveTime();
+            if (mMainStack) {
+                mService.addRecentTaskLocked(next.task);
+            }
             mService.updateLruProcessLocked(next.app, true, true);
             updateLRUListLocked(next);
 
@@ -1638,9 +1644,6 @@
                             taskTopI = -1;
                         }
                         replyChainEnd = -1;
-                        if (mMainStack) {
-                            mService.addRecentTaskLocked(target.task);
-                        }
                     } else if (forceReset || finishOnTaskLaunch
                             || clearWhenTaskReset) {
                         // If the activity should just be removed -- either
@@ -2409,9 +2412,6 @@
                 r.task = reuseTask;
             }
             newTask = true;
-            if (mMainStack) {
-                mService.addRecentTaskLocked(r.task);
-            }
             moveHomeToFrontFromLaunchLocked(launchFlags);
             
         } else if (sourceRecord != null) {
@@ -3472,17 +3472,12 @@
             ActivityRecord r = (ActivityRecord)mHistory.get(pos);
             if (localLOGV) Slog.v(
                 TAG, "At " + pos + " ckp " + r.task + ": " + r);
-            boolean first = true;
             if (r.task.taskId == task) {
                 if (localLOGV) Slog.v(TAG, "Removing and adding at " + top);
                 mHistory.remove(pos);
                 mHistory.add(top, r);
                 moved.add(0, r);
                 top--;
-                if (first && mMainStack) {
-                    mService.addRecentTaskLocked(r.task);
-                    first = false;
-                }
             }
             pos--;
         }
diff --git a/test-runner/src/android/test/InstrumentationTestRunner.java b/test-runner/src/android/test/InstrumentationTestRunner.java
index 5ce3efc..c3d09ff 100644
--- a/test-runner/src/android/test/InstrumentationTestRunner.java
+++ b/test-runner/src/android/test/InstrumentationTestRunner.java
@@ -16,8 +16,6 @@
 
 package android.test;
 
-import static android.test.suitebuilder.TestPredicates.REJECT_PERFORMANCE;
-
 import com.android.internal.util.Predicate;
 import com.android.internal.util.Predicates;
 
@@ -172,8 +170,6 @@
     /** @hide */
     public static final String ARGUMENT_TEST_SIZE_PREDICATE = "size";
     /** @hide */
-    public static final String ARGUMENT_INCLUDE_PERF = "perf";
-    /** @hide */
     public static final String ARGUMENT_DELAY_MSEC = "delay_msec";
 
     private static final String SMALL_SUITE = "small";
@@ -305,7 +301,6 @@
         Predicate<TestMethod> testSizePredicate = null;
         Predicate<TestMethod> testAnnotationPredicate = null;
         Predicate<TestMethod> testNotAnnotationPredicate = null;
-        boolean includePerformance = false;
         String testClassesArg = null;
         boolean logOnly = false;
 
@@ -323,7 +318,6 @@
             testNotAnnotationPredicate = getNotAnnotationPredicate(
                     arguments.getString(ARGUMENT_NOT_ANNOTATION));
 
-            includePerformance = getBooleanArgument(arguments, ARGUMENT_INCLUDE_PERF);
             logOnly = getBooleanArgument(arguments, ARGUMENT_LOG_ONLY);
             mCoverage = getBooleanArgument(arguments, "coverage");
             mCoverageFilePath = arguments.getString("coverageFile");
@@ -348,9 +342,6 @@
         if (testNotAnnotationPredicate != null) {
             testSuiteBuilder.addRequirements(testNotAnnotationPredicate);
         }
-        if (!includePerformance) {
-            testSuiteBuilder.addRequirements(REJECT_PERFORMANCE);
-        }
 
         if (testClassesArg == null) {
             if (mPackageOfTests != null) {
diff --git a/test-runner/src/android/test/PerformanceTestBase.java b/test-runner/src/android/test/PerformanceTestBase.java
deleted file mode 100644
index 4a0a589..0000000
--- a/test-runner/src/android/test/PerformanceTestBase.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.test;
-
-import junit.framework.TestCase;
-
-/**
- * {@hide} Not needed for SDK.
- */
-public class PerformanceTestBase extends TestCase implements PerformanceTestCase {
-
-    public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-        return 0;
-    }
-
-    public boolean isPerformanceOnly() {
-        return true;
-    }
-}
diff --git a/test-runner/src/android/test/suitebuilder/TestPredicates.java b/test-runner/src/android/test/suitebuilder/TestPredicates.java
index d814e0b..47aca55 100644
--- a/test-runner/src/android/test/suitebuilder/TestPredicates.java
+++ b/test-runner/src/android/test/suitebuilder/TestPredicates.java
@@ -17,7 +17,6 @@
 package android.test.suitebuilder;
 
 import android.test.InstrumentationTestCase;
-import android.test.PerformanceTestBase;
 import android.test.suitebuilder.annotation.HasAnnotation;
 import android.test.suitebuilder.annotation.Suppress;
 import android.test.suitebuilder.annotation.LargeTest;
@@ -43,7 +42,5 @@
     public static final Predicate<TestMethod> SELECT_LARGE = new HasAnnotation(LargeTest.class);
     public static final Predicate<TestMethod> REJECT_SUPPRESSED =
             Predicates.not(new HasAnnotation(Suppress.class));
-    public static final Predicate<TestMethod> REJECT_PERFORMANCE =
-            Predicates.not(new AssignableFrom(PerformanceTestBase.class));
 
 }
diff --git a/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java b/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
index 428905e..28f7216 100644
--- a/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
+++ b/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
@@ -24,7 +24,6 @@
 import com.google.android.collect.Lists;
 import static android.test.suitebuilder.TestGrouping.SORT_BY_FULLY_QUALIFIED_NAME;
 import static android.test.suitebuilder.TestPredicates.REJECT_SUPPRESSED;
-import static android.test.suitebuilder.TestPredicates.REJECT_PERFORMANCE;
 
 import junit.framework.Test;
 import junit.framework.TestCase;
@@ -71,9 +70,9 @@
         this.testCases = Lists.newArrayList();
         addRequirements(REJECT_SUPPRESSED);
     }
-    
+
     /** @hide pending API Council approval */
-    public TestSuiteBuilder addTestClassByName(String testClassName, String testMethodName, 
+    public TestSuiteBuilder addTestClassByName(String testClassName, String testMethodName,
             Context context) {
 
         AndroidTestRunner atr = new AndroidTestRunner();
@@ -83,7 +82,7 @@
         this.testCases.addAll(atr.getTestCases());
         return this;
     }
-    
+
     /** @hide pending API Council approval */
     public TestSuiteBuilder addTestSuite(TestSuite testSuite) {
         for (TestCase testCase : (List<TestCase>) TestCaseUtil.getTests(testSuite, true)) {
@@ -242,7 +241,7 @@
 
     /**
      * @return the test package that represents the packages that were included for our test suite.
-     * 
+     *
      * {@hide} Not needed for 1.0 SDK.
      */
     protected TestGrouping getTestGrouping() {
@@ -262,7 +261,7 @@
         addSuiteIfNecessary(testMethod.getEnclosingClassname());
         suiteForCurrentClass.addTest(testMethod.createTest());
     }
-    
+
     private void addTest(Test test) {
         addSuiteIfNecessary(test.getClass().getName());
         suiteForCurrentClass.addTest(test);
diff --git a/test-runner/src/android/test/suitebuilder/UnitTestSuiteBuilder.java b/test-runner/src/android/test/suitebuilder/UnitTestSuiteBuilder.java
index 8cf4c86..a746b35 100644
--- a/test-runner/src/android/test/suitebuilder/UnitTestSuiteBuilder.java
+++ b/test-runner/src/android/test/suitebuilder/UnitTestSuiteBuilder.java
@@ -18,7 +18,7 @@
 
 /**
  * A suite builder that finds unit tests.
- * 
+ *
  * {@hide} Not needed for 1.0 SDK.
  */
 public class UnitTestSuiteBuilder extends TestSuiteBuilder {
@@ -31,6 +31,5 @@
     public UnitTestSuiteBuilder(String name, ClassLoader classLoader) {
         super(name, classLoader);
         addRequirements(TestPredicates.REJECT_INSTRUMENTATION);
-        addRequirements(TestPredicates.REJECT_PERFORMANCE);
     }
 }
diff --git a/tests/CoreTests/android/core/AndroidPerformanceTests.java b/tests/CoreTests/android/core/AndroidPerformanceTests.java
deleted file mode 100644
index e604d59..0000000
--- a/tests/CoreTests/android/core/AndroidPerformanceTests.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import android.test.TestListActivity;
-
-public class AndroidPerformanceTests extends TestListActivity {
-    @Override
-    public String getTestSuite() {
-        return "com.android.unit_tests.AndroidPerformanceTests$Suite";
-    }
-
-    public static class Suite {
-        public static String[] children() {
-            return new String[] {
-                JavaPerformanceTests.class.getName(),
-                PerformanceTests.class.getName(),
-            };
-        }
-    }
-}
diff --git a/tests/CoreTests/android/core/ArrayListPerformanceTest.java b/tests/CoreTests/android/core/ArrayListPerformanceTest.java
deleted file mode 100644
index 6130e83..0000000
--- a/tests/CoreTests/android/core/ArrayListPerformanceTest.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import java.util.ArrayList;
-import android.test.PerformanceTestBase;
-
-public class ArrayListPerformanceTest extends PerformanceTestBase {
-
-    private ArrayList<Integer> mList;
-
-    @Override
-    @SuppressWarnings("unchecked")
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mList = new ArrayList();
-        mList.add(0);
-        mList.add(1);
-        mList.add(2);
-        mList.add(3);
-        mList.add(4);
-        mList.add(5);
-        mList.add(6);
-        mList.add(7);
-        mList.add(8);
-        mList.add(9);
-    }
-
-    public void testArrayListAdd() {
-        int i = 0;
-        for (; i < 10; i++) {
-            mList.add(i);
-            mList.add(i);
-            mList.add(i);
-            mList.add(i);
-            mList.add(i);
-            mList.add(i);
-            mList.add(i);
-            mList.add(i);
-            mList.add(i);
-            mList.add(i);
-        }
-    }
-
-    public void testArrayListAdd1() {
-        int i = 0;
-        for (; i < 10; i++) {
-            mList.add(7, i);
-            mList.add(7, i);
-            mList.add(7, i);
-            mList.add(7, i);
-            mList.add(7, i);
-            mList.add(7, i);
-            mList.add(7, i);
-            mList.add(7, i);
-            mList.add(7, i);
-            mList.add(7, i);
-        }
-    }
-
-    public void testArrayListToArray() {
-        Object rArray;
-        int i = 0;
-        for (; i < 100; i++) {
-            rArray = mList.toArray();
-            rArray = mList.toArray();
-            rArray = mList.toArray();
-            rArray = mList.toArray();
-            rArray = mList.toArray();
-            rArray = mList.toArray();
-            rArray = mList.toArray();
-            rArray = mList.toArray();
-            rArray = mList.toArray();
-            rArray = mList.toArray();
-        }
-    }
-
-    public void testArrayListSize() {
-        int i = 0, len;
-        for (; i < 100; i++) {
-            len = mList.size();
-            len = mList.size();
-            len = mList.size();
-            len = mList.size();
-            len = mList.size();
-            len = mList.size();
-            len = mList.size();
-            len = mList.size();
-            len = mList.size();
-            len = mList.size();
-        }
-    }
-
-    public void testArrayListGet() {
-        int i = 0, value;
-        int len = mList.size();
-        for (; i < len; i++) {
-            value = mList.get(i);
-            value = mList.get(i);
-            value = mList.get(i);
-            value = mList.get(i);
-            value = mList.get(i);
-            value = mList.get(i);
-            value = mList.get(i);
-            value = mList.get(i);
-            value = mList.get(i);
-            value = mList.get(i);
-        }
-    }
-
-    public void testArrayListContains() {
-        boolean flag;
-        int i = 0;
-
-        for (; i < 100; i++) {
-            flag = mList.contains(i);
-            flag = mList.contains(i);
-            flag = mList.contains(i);
-            flag = mList.contains(i);
-            flag = mList.contains(i);
-            flag = mList.contains(i);
-            flag = mList.contains(i);
-            flag = mList.contains(i);
-            flag = mList.contains(i);
-            flag = mList.contains(i);
-
-        }
-    }
-
-    public void testArrayListToArray1() {
-        Integer[] rArray = new Integer[10];
-
-        Integer[] mArray;
-        int i = 0;
-        for (; i < 100; i++) {
-            mArray = mList.toArray(rArray);
-            mArray = mList.toArray(rArray);
-            mArray = mList.toArray(rArray);
-            mArray = mList.toArray(rArray);
-            mArray = mList.toArray(rArray);
-            mArray = mList.toArray(rArray);
-            mArray = mList.toArray(rArray);
-            mArray = mList.toArray(rArray);
-            mArray = mList.toArray(rArray);
-            mArray = mList.toArray(rArray);
-        }
-    }
-
-    public void testArrayListSet() {
-        int i = 0;
-        for (; i < 10; i++) {
-            mList.set(5, 0);
-            mList.set(5, 0);
-            mList.set(5, 0);
-            mList.set(5, 0);
-            mList.set(5, 0);
-            mList.set(5, 0);
-            mList.set(5, 0);
-            mList.set(5, 0);
-            mList.set(5, 0);
-            mList.set(5, 0);
-        }
-    }
-
-    public void testArrayListIndexOf() {
-        int i = 0, index;
-
-        for (; i < 100; i++) {
-            index = mList.indexOf(0);
-            index = mList.indexOf(0);
-            index = mList.indexOf(0);
-            index = mList.indexOf(0);
-            index = mList.indexOf(0);
-            index = mList.indexOf(0);
-            index = mList.indexOf(0);
-            index = mList.indexOf(0);
-            index = mList.indexOf(0);
-            index = mList.indexOf(0);
-        }
-    }
-
-    public void testArrayListLastIndexOf() {
-        int i = 0, index;
-
-        for (; i < 100; i++) {
-            index = mList.lastIndexOf(0);
-            index = mList.lastIndexOf(0);
-            index = mList.lastIndexOf(0);
-            index = mList.lastIndexOf(0);
-            index = mList.lastIndexOf(0);
-            index = mList.lastIndexOf(0);
-            index = mList.lastIndexOf(0);
-            index = mList.lastIndexOf(0);
-            index = mList.lastIndexOf(0);
-            index = mList.lastIndexOf(0);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testArrayListRemove() {
-        ArrayList<Integer> aList;
-        aList = new ArrayList();
-        for (int j = 0; j < 10000; j++) {
-            aList.add(0);
-        }
-
-        int i = 0, index;
-
-        for (; i < 10; i++) {
-            index = aList.remove(0);
-            index = aList.remove(0);
-            index = aList.remove(0);
-            index = aList.remove(0);
-            index = aList.remove(0);
-            index = aList.remove(0);
-            index = aList.remove(0);
-            index = aList.remove(0);
-            index = aList.remove(0);
-            index = aList.remove(0);
-
-
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testArrayListAddAll() {
-        ArrayList<Integer> aList = new ArrayList();
-
-        int i = 0;
-        boolean b;
-        for (; i < 10; i++) {
-            b = aList.addAll(mList);
-            b = aList.addAll(mList);
-            b = aList.addAll(mList);
-            b = aList.addAll(mList);
-            b = aList.addAll(mList);
-            b = aList.addAll(mList);
-            b = aList.addAll(mList);
-            b = aList.addAll(mList);
-            b = aList.addAll(mList);
-            b = aList.addAll(mList);
-
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testArrayListRemove1() {
-        ArrayList<String> aList;
-        String s;
-
-        aList = new ArrayList();
-        for (int j = 0; j < 100; j++) {
-            aList.add("a");
-            aList.add("b");
-        }
-        s = new String("a");
-
-        int i = 0;
-        boolean b;
-        for (; i < 10; i++) {
-            b = aList.remove(s);
-            b = aList.remove(s);
-            b = aList.remove(s);
-            b = aList.remove(s);
-            b = aList.remove(s);
-            b = aList.remove(s);
-            b = aList.remove(s);
-            b = aList.remove(s);
-            b = aList.remove(s);
-            b = aList.remove(s);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testArrayListAddAll1() {
-        ArrayList<Integer> aList = new ArrayList();
-
-        int i = 0;
-        boolean b;
-
-        for (; i < 10; i++) {
-            b = aList.addAll(0, mList);
-            b = aList.addAll(0, mList);
-            b = aList.addAll(0, mList);
-            b = aList.addAll(0, mList);
-            b = aList.addAll(0, mList);
-            b = aList.addAll(0, mList);
-            b = aList.addAll(0, mList);
-            b = aList.addAll(0, mList);
-            b = aList.addAll(0, mList);
-            b = aList.addAll(0, mList);
-        }
-    }
-
-    public void testArrayListClone() {
-        Object rObj;
-        int i = 0;
-
-        for (; i < 100; i++) {
-            rObj = mList.clone();
-            rObj = mList.clone();
-            rObj = mList.clone();
-            rObj = mList.clone();
-            rObj = mList.clone();
-            rObj = mList.clone();
-            rObj = mList.clone();
-            rObj = mList.clone();
-            rObj = mList.clone();
-            rObj = mList.clone();
-        }
-    }
-}
diff --git a/tests/CoreTests/android/core/HashMapPerfTest.java b/tests/CoreTests/android/core/HashMapPerfTest.java
deleted file mode 100644
index 8475222..0000000
--- a/tests/CoreTests/android/core/HashMapPerfTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.core;
-
-import android.os.SystemClock;
-import android.test.suitebuilder.annotation.LargeTest;
-import junit.framework.TestCase;
-
-import java.util.HashMap;
-import java.util.Random;
-
-/**
- * Tests basic functionality of HashMaps and prints the time needed to System.out
- */
-public class HashMapPerfTest extends TestCase {
-
-    private static final Random sRandom = new Random(1);
-
-    class StringThing {
-
-        String mId;
-
-        public StringThing() {
-            int len = sRandom.nextInt(20) + 1;
-            char[] chars = new char[len];
-            chars[0] = 't';
-            for (int i = 1; i < len; i++) {
-                chars[i] = (char) ('q' + sRandom.nextInt(4));
-            }
-            mId = new String(chars, 0, len);
-        }
-
-        public String getId() {
-            return mId;
-        }
-    }
-
-    private static final int NUM_ELTS = 1000;
-    private static final int ITERS = 100;
-
-    String[] keyCopies = new String[NUM_ELTS];
-
-    private static final boolean lookupByOriginals = false;
-
-    @LargeTest
-    public void testHashMapPerformance() throws Exception {
-        StringThing[] st = new StringThing[NUM_ELTS];
-        for (int i = 0; i < NUM_ELTS; i++) {
-            st[i] = new StringThing();
-            keyCopies[i] = st[i].getId();
-        }
-
-        // android.os.Debug.startMethodTracing();
-        long start = SystemClock.uptimeMillis();
-        for (int i = 0; i < ITERS; i++) {
-            HashMap<String, StringThing> map = new HashMap<String, StringThing>();
-            for (int j = 0; j < NUM_ELTS; j++) {
-                StringThing s = st[i];
-                map.put(s.getId(), s);
-            }
-            for (int j = 0; j < NUM_ELTS; j++) {
-                if (lookupByOriginals) {
-                    StringThing s = st[i];
-                    map.get(s.getId());
-                } else {
-                    map.get(keyCopies[j]);
-                }
-            }
-        }
-        long finish = SystemClock.uptimeMillis();
-        // android.os.Debug.stopMethodTracing();
-
-        // This should be an assertion instead
-        
-//        System.out.println("time (" + NUM_ELTS +
-//                ", elts, " + ITERS +
-//                " iters) = " + (finish - start));
-    }
-}
diff --git a/tests/CoreTests/android/core/HashMapPerformanceTest.java b/tests/CoreTests/android/core/HashMapPerformanceTest.java
deleted file mode 100644
index 82727bb..0000000
--- a/tests/CoreTests/android/core/HashMapPerformanceTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Set;
-
-import android.test.PerformanceTestBase;
-import android.test.PerformanceTestCase;
-
-public class HashMapPerformanceTest extends PerformanceTestBase {
-    public static final int ITERATIONS = 1000;
-    public HashMap mMap;
-    public String[] mKeys;
-
-    @Override
-    @SuppressWarnings("unchecked")
-    protected void setUp() throws Exception {
-        super.setUp();
-        mMap = new HashMap();
-        mKeys = new String[ITERATIONS];
-
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            mKeys[i] = Integer.toString(i, 16);
-            mMap.put(mKeys[i], i);
-        }
-    }
-
-    @Override
-    public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-        intermediates.setInternalIterations(ITERATIONS);
-        return 0;
-    }
-
-    public void testHashMapGet() {
-        int num;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            num = (Integer) mMap.get(mKeys[i]);
-            num = (Integer) mMap.get(mKeys[i]);
-            num = (Integer) mMap.get(mKeys[i]);
-            num = (Integer) mMap.get(mKeys[i]);
-            num = (Integer) mMap.get(mKeys[i]);
-            num = (Integer) mMap.get(mKeys[i]);
-            num = (Integer) mMap.get(mKeys[i]);
-            num = (Integer) mMap.get(mKeys[i]);
-            num = (Integer) mMap.get(mKeys[i]);
-            num = (Integer) mMap.get(mKeys[i]);
-        }
-    }
-
-    public void testHashMapKeySet() {
-        Set keyset;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            keyset = mMap.keySet();
-            keyset = mMap.keySet();
-            keyset = mMap.keySet();
-            keyset = mMap.keySet();
-            keyset = mMap.keySet();
-            keyset = mMap.keySet();
-            keyset = mMap.keySet();
-            keyset = mMap.keySet();
-            keyset = mMap.keySet();
-            keyset = mMap.keySet();
-        }
-    }
-
-    public void testHashMapEntrySet() {
-        Set keyset;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            keyset = mMap.entrySet();
-            keyset = mMap.entrySet();
-            keyset = mMap.entrySet();
-            keyset = mMap.entrySet();
-            keyset = mMap.entrySet();
-            keyset = mMap.entrySet();
-            keyset = mMap.entrySet();
-            keyset = mMap.entrySet();
-            keyset = mMap.entrySet();
-            keyset = mMap.entrySet();
-
-
-        }
-    }
-
-    public void testHashMapValues() {
-        Collection c;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            c = mMap.values();
-            c = mMap.values();
-            c = mMap.values();
-            c = mMap.values();
-            c = mMap.values();
-            c = mMap.values();
-            c = mMap.values();
-            c = mMap.values();
-            c = mMap.values();
-            c = mMap.values();
-
-
-        }
-    }
-
-    public void testHashMapSize() {
-        int len;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            len = mMap.size();
-            len = mMap.size();
-            len = mMap.size();
-            len = mMap.size();
-            len = mMap.size();
-            len = mMap.size();
-            len = mMap.size();
-            len = mMap.size();
-            len = mMap.size();
-            len = mMap.size();
-
-
-        }
-    }
-
-    public void testHashMapContainsValue() {
-        boolean flag;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = mMap.containsValue(i);
-            flag = mMap.containsValue(i);
-            flag = mMap.containsValue(i);
-            flag = mMap.containsValue(i);
-            flag = mMap.containsValue(i);
-            flag = mMap.containsValue(i);
-            flag = mMap.containsValue(i);
-            flag = mMap.containsValue(i);
-            flag = mMap.containsValue(i);
-            flag = mMap.containsValue(i);
-
-
-        }
-    }
-
-    public void testHashMapRemove() {
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            mMap.remove(mKeys[i]);
-            mMap.remove(mKeys[i]);
-            mMap.remove(mKeys[i]);
-            mMap.remove(mKeys[i]);
-            mMap.remove(mKeys[i]);
-            mMap.remove(mKeys[i]);
-            mMap.remove(mKeys[i]);
-            mMap.remove(mKeys[i]);
-            mMap.remove(mKeys[i]);
-            mMap.remove(mKeys[i]);
-        }
-    }
-
-
-    public void testHashMapClone() {
-        HashMap cMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            cMap = (HashMap) mMap.clone();
-            cMap = (HashMap) mMap.clone();
-            cMap = (HashMap) mMap.clone();
-            cMap = (HashMap) mMap.clone();
-            cMap = (HashMap) mMap.clone();
-            cMap = (HashMap) mMap.clone();
-            cMap = (HashMap) mMap.clone();
-            cMap = (HashMap) mMap.clone();
-            cMap = (HashMap) mMap.clone();
-            cMap = (HashMap) mMap.clone();
-        }
-    }
-}
diff --git a/tests/CoreTests/android/core/HashSetTest.java b/tests/CoreTests/android/core/HashSetTest.java
deleted file mode 100644
index 09a711f..0000000
--- a/tests/CoreTests/android/core/HashSetTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import android.test.PerformanceTestBase;
-import android.test.PerformanceTestCase;
-
-import java.util.HashSet;
-import java.util.Iterator;
-
-/**
- * Implements basic performance test functionality for HashSets
- */
-
-public class HashSetTest extends PerformanceTestBase {
-    public static final int ITERATIONS = 1000;
-    public static HashSet<Integer> sSet;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        sSet = new HashSet<Integer>();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            sSet.add(i);
-        }
-    }
-
-    @Override
-    public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-        intermediates.setInternalIterations(ITERATIONS);
-        return 0;
-    }
-
-    /**
-     * 
-     * Tests performance for the HashSet method Add(Object arg 0)
-     * 
-     */
-
-    @SuppressWarnings("unchecked")
-    public void testHashSetAdd() {
-        HashSet set = new HashSet();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-        }
-
-    }
-
-    /**
-     * 
-     * Tests performance of HashSet method contains(Object arg 0)
-     * 
-     */
-
-    public void testHashSetContains() {
-        Integer index = new Integer(500);
-        boolean flag;
-        HashSet set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-        }
-    }
-
-    /**
-     * 
-     * Tests performance of HashSet method size()
-     * 
-     */
-
-    public void testHashSetSize() {
-        int num;
-        HashSet set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            num = set.size();
-            num = set.size();
-            num = set.size();
-            num = set.size();
-            num = set.size();
-            num = set.size();
-            num = set.size();
-            num = set.size();
-            num = set.size();
-        }
-    }
-
-    /**
-     * 
-     * Tests performance of the HashSet method -iterator()
-     * 
-     */
-
-    public void testHashSetIterator() {
-        Iterator iterator;
-        HashSet set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the HashSet method Remove(Object arg 0)
-     * 
-     */
-
-    @SuppressWarnings("unchecked")
-    public void testHashSetRemove() {
-        HashSet set = new HashSet(sSet);
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the HashSet method isEmpty(Object arg 0)
-     * 
-     */
-
-    public void testHashSetIsEmpty() {
-        HashSet set = sSet;
-        boolean flag;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = set.isEmpty();
-            flag = set.isEmpty();
-            flag = set.isEmpty();
-            flag = set.isEmpty();
-            flag = set.isEmpty();
-            flag = set.isEmpty();
-            flag = set.isEmpty();
-            flag = set.isEmpty();
-            flag = set.isEmpty();
-            flag = set.isEmpty();
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the HashSet method clone()
-     * 
-     */
-
-    public void testHashSetClone() {
-        HashSet hSet = sSet;
-        Object set;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            set = hSet.clone();
-            set = hSet.clone();
-            set = hSet.clone();
-            set = hSet.clone();
-            set = hSet.clone();
-            set = hSet.clone();
-            set = hSet.clone();
-            set = hSet.clone();
-            set = hSet.clone();
-            set = hSet.clone();
-        }
-    }
-}
diff --git a/tests/CoreTests/android/core/HashtableTest.java b/tests/CoreTests/android/core/HashtableTest.java
deleted file mode 100644
index 6160f57..0000000
--- a/tests/CoreTests/android/core/HashtableTest.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import android.test.PerformanceTestBase;
-import android.test.PerformanceTestCase;
-
-import java.util.Hashtable;
-import java.util.Set;
-import java.util.Enumeration;
-
-/**
- * Implements basic performance test functionality for java.util.Hashtable
- */
-
-public class HashtableTest extends PerformanceTestBase {
-    public static final int ITERATIONS = 1000;
-    public Hashtable<String, Integer> sTable;
-    public String[] sKeys;
-
-    @Override
-    @SuppressWarnings("unchecked")
-    protected void setUp() throws Exception {
-        super.setUp();
-        sTable = new Hashtable();
-        sKeys = new String[ITERATIONS];
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            sKeys[i] = Integer.toString(i, 16);
-            sTable.put(sKeys[i], i);
-        }
-    }
-
-    @Override
-    public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-        intermediates.setInternalIterations(ITERATIONS);
-        return 0;
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testHashtablePut() {
-        Hashtable hTable = new Hashtable();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            hTable.put(i, i);
-            hTable.put(i, i);
-            hTable.put(i, i);
-            hTable.put(i, i);
-            hTable.put(i, i);
-            hTable.put(i, i);
-            hTable.put(i, i);
-            hTable.put(i, i);
-            hTable.put(i, i);
-            hTable.put(i, i);
-        }
-    }
-
-    public void testHashtableGet() {
-        int value;
-        String[] keys = sKeys;
-        Hashtable<String, Integer> hTable = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            value = hTable.get(keys[i]);
-            value = hTable.get(keys[i]);
-            value = hTable.get(keys[i]);
-            value = hTable.get(keys[i]);
-            value = hTable.get(keys[i]);
-            value = hTable.get(keys[i]);
-            value = hTable.get(keys[i]);
-            value = hTable.get(keys[i]);
-            value = hTable.get(keys[i]);
-            value = hTable.get(keys[i]);
-        }
-    }
-
-    public void testHashtablekeyset() {
-        Set keyset;
-        Hashtable<String, Integer> hTable = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            keyset = hTable.keySet();
-            keyset = hTable.keySet();
-            keyset = hTable.keySet();
-            keyset = hTable.keySet();
-            keyset = hTable.keySet();
-            keyset = hTable.keySet();
-            keyset = hTable.keySet();
-            keyset = hTable.keySet();
-            keyset = hTable.keySet();
-            keyset = hTable.keySet();
-        }
-    }
-
-    /**
-     * 
-     */
-
-    public void testHashtableEntrySet() {
-        Set keyset;
-        Hashtable<String, Integer> hTable = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            keyset = hTable.entrySet();
-            keyset = hTable.entrySet();
-            keyset = hTable.entrySet();
-            keyset = hTable.entrySet();
-            keyset = hTable.entrySet();
-            keyset = hTable.entrySet();
-            keyset = hTable.entrySet();
-            keyset = hTable.entrySet();
-            keyset = hTable.entrySet();
-            keyset = hTable.entrySet();
-        }
-    }
-
-    public void testHashtableSize() {
-        int len;
-        Hashtable<String, Integer> hTable = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            len = hTable.size();
-            len = hTable.size();
-            len = hTable.size();
-            len = hTable.size();
-            len = hTable.size();
-            len = hTable.size();
-            len = hTable.size();
-            len = hTable.size();
-            len = hTable.size();
-            len = hTable.size();
-        }
-    }
-
-    public void testHashtableContainsValue() {
-        boolean flag;
-        Hashtable<String, Integer> hTable = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = hTable.containsValue(i);
-            flag = hTable.containsValue(i);
-            flag = hTable.containsValue(i);
-            flag = hTable.containsValue(i);
-            flag = hTable.containsValue(i);
-            flag = hTable.containsValue(i);
-            flag = hTable.containsValue(i);
-            flag = hTable.containsValue(i);
-            flag = hTable.containsValue(i);
-            flag = hTable.containsValue(i);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testHashtableRemove() {
-        Hashtable<String, Integer> hTable = new Hashtable(sTable);
-        String[] keys = sKeys;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            hTable.remove(keys[i]);
-            hTable.remove(keys[i]);
-            hTable.remove(keys[i]);
-            hTable.remove(keys[i]);
-            hTable.remove(keys[i]);
-            hTable.remove(keys[i]);
-            hTable.remove(keys[i]);
-            hTable.remove(keys[i]);
-            hTable.remove(keys[i]);
-            hTable.remove(keys[i]);
-        }
-    }
-
-    public void testHashtableContains() {
-        Hashtable<String, Integer> hTable = sTable;
-        boolean flag;
-
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = hTable.contains(i);
-            flag = hTable.contains(i);
-            flag = hTable.contains(i);
-            flag = hTable.contains(i);
-            flag = hTable.contains(i);
-            flag = hTable.contains(i);
-            flag = hTable.contains(i);
-            flag = hTable.contains(i);
-            flag = hTable.contains(i);
-            flag = hTable.contains(i);
-        }
-    }
-
-    public void testHashtableContainsKey() {
-        Hashtable<String, Integer> hTable = sTable;
-        boolean flag;
-
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = hTable.containsKey(i);
-            flag = hTable.containsKey(i);
-            flag = hTable.containsKey(i);
-            flag = hTable.containsKey(i);
-            flag = hTable.containsKey(i);
-            flag = hTable.containsKey(i);
-            flag = hTable.containsKey(i);
-            flag = hTable.containsKey(i);
-            flag = hTable.containsKey(i);
-            flag = hTable.containsKey(i);
-        }
-    }
-
-    public void testHashtableIsEmpty() {
-        Hashtable<String, Integer> hTable = sTable;
-        boolean flag;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = hTable.isEmpty();
-            flag = hTable.isEmpty();
-            flag = hTable.isEmpty();
-            flag = hTable.isEmpty();
-            flag = hTable.isEmpty();
-            flag = hTable.isEmpty();
-            flag = hTable.isEmpty();
-            flag = hTable.isEmpty();
-            flag = hTable.isEmpty();
-            flag = hTable.isEmpty();
-        }
-    }
-
-    public void testHashtableKeys() {
-        Hashtable<String, Integer> hTable = sTable;
-        Enumeration<String> keys;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            keys = hTable.keys();
-            keys = hTable.keys();
-            keys = hTable.keys();
-            keys = hTable.keys();
-            keys = hTable.keys();
-            keys = hTable.keys();
-            keys = hTable.keys();
-            keys = hTable.keys();
-            keys = hTable.keys();
-            keys = hTable.keys();
-        }
-    }
-
-    public void testHashtableElements() {
-        Hashtable<String, Integer> hTable = sTable;
-        Enumeration<Integer> elements;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            elements = hTable.elements();
-            elements = hTable.elements();
-            elements = hTable.elements();
-            elements = hTable.elements();
-            elements = hTable.elements();
-            elements = hTable.elements();
-            elements = hTable.elements();
-            elements = hTable.elements();
-            elements = hTable.elements();
-            elements = hTable.elements();
-        }
-    }
-
-    public void testHashtableHashCode() {
-        int index;
-        Hashtable<String, Integer> hTable = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            index = hTable.hashCode();
-            index = hTable.hashCode();
-            index = hTable.hashCode();
-            index = hTable.hashCode();
-            index = hTable.hashCode();
-            index = hTable.hashCode();
-            index = hTable.hashCode();
-            index = hTable.hashCode();
-            index = hTable.hashCode();
-            index = hTable.hashCode();
-        }
-    }
-
-    public void testHashtableEquals() {
-        boolean flag;
-        Hashtable<String, Integer> hTable = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = hTable.equals(hTable);
-            flag = hTable.equals(hTable);
-            flag = hTable.equals(hTable);
-            flag = hTable.equals(hTable);
-            flag = hTable.equals(hTable);
-            flag = hTable.equals(hTable);
-            flag = hTable.equals(hTable);
-            flag = hTable.equals(hTable);
-            flag = hTable.equals(hTable);
-            flag = hTable.equals(hTable);
-        }
-    }
-
-    public void testHashtableToString() {
-        String str;
-        Hashtable<String, Integer> hTable = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            str = hTable.toString();
-            str = hTable.toString();
-            str = hTable.toString();
-            str = hTable.toString();
-            str = hTable.toString();
-            str = hTable.toString();
-            str = hTable.toString();
-            str = hTable.toString();
-            str = hTable.toString();
-            str = hTable.toString();
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testHashtablePutAll() {
-        Hashtable<String, Integer> hTable = new Hashtable();
-        Hashtable<String, Integer> hTable1 = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            hTable.putAll(hTable1);
-            hTable.putAll(hTable1);
-            hTable.putAll(hTable1);
-            hTable.putAll(hTable1);
-            hTable.putAll(hTable1);
-            hTable.putAll(hTable1);
-            hTable.putAll(hTable1);
-            hTable.putAll(hTable1);
-            hTable.putAll(hTable1);
-            hTable.putAll(hTable1);
-        }
-    }
-
-    /**
-     * 
-     * clone() returns a Hashtable .. It should return Object as per the
-     * specification.
-     * 
-     */
-
-    public void testHashtableClone() {
-        Hashtable hashTable;
-        Hashtable<String, Integer> hTable = sTable;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            hashTable = (Hashtable) hTable.clone();
-            hashTable = (Hashtable) hTable.clone();
-            hashTable = (Hashtable) hTable.clone();
-            hashTable = (Hashtable) hTable.clone();
-            hashTable = (Hashtable) hTable.clone();
-            hashTable = (Hashtable) hTable.clone();
-            hashTable = (Hashtable) hTable.clone();
-            hashTable = (Hashtable) hTable.clone();
-            hashTable = (Hashtable) hTable.clone();
-            hashTable = (Hashtable) hTable.clone();
-        }
-    }
-}
diff --git a/tests/CoreTests/android/core/JavaPerformanceTests.java b/tests/CoreTests/android/core/JavaPerformanceTests.java
deleted file mode 100644
index 95075ea..0000000
--- a/tests/CoreTests/android/core/JavaPerformanceTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-/**
- * 
- */
-public class JavaPerformanceTests {
-
-    public static String[] children() {
-        return new String[] {
-                HashMapPerformanceTest.class.getName(),
-                ArrayListPerformanceTest.class.getName(),
-                TreeMapPerformanceTest.class.getName(),
-                TreeSetTest.class.getName(),
-                HashSetTest.class.getName(),
-                HashtableTest.class.getName(),
-                VectorTest.class.getName(),
-                LinkedListTest.class.getName(),
-                MathPerformanceTest.class.getName(),
-        };
-    }
-}
diff --git a/tests/CoreTests/android/core/LinkedListTest.java b/tests/CoreTests/android/core/LinkedListTest.java
deleted file mode 100644
index 8b237fd..0000000
--- a/tests/CoreTests/android/core/LinkedListTest.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import android.test.PerformanceTestBase;
-import android.test.PerformanceTestCase;
-import java.util.LinkedList;
-import java.util.ListIterator;
-
-/**
- * This class contains performance tests for methods in java.util.LinkedList
- * 
- */
-@SuppressWarnings("unchecked")
-public class LinkedListTest extends PerformanceTestBase {
-    public static final int ITERATIONS = 1000;
-    LinkedList<Integer> mLinkedList;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mLinkedList = new LinkedList();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            mLinkedList.add(i);
-        }
-    }
-
-    @Override
-    public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-        intermediates.setInternalIterations(ITERATIONS);
-        return 0;
-    }
-
-    public void testLinkedListAdd() {
-        LinkedList<Integer> list = new LinkedList();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            list.add(i);
-            list.add(i);
-            list.add(i);
-            list.add(i);
-            list.add(i);
-            list.add(i);
-            list.add(i);
-            list.add(i);
-            list.add(i);
-            list.add(i);
-        }
-    }
-
-    public void testLinkedListAdd1() {
-        LinkedList<Integer> list = new LinkedList();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            list.add(0, i);
-            list.add(0, i);
-            list.add(0, i);
-            list.add(0, i);
-            list.add(0, i);
-            list.add(0, i);
-            list.add(0, i);
-            list.add(0, i);
-            list.add(0, i);
-            list.add(0, i);
-        }
-    }
-
-    public void testLinkedListToArray() {
-        Object array;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            array = list.toArray();
-            array = list.toArray();
-            array = list.toArray();
-            array = list.toArray();
-            array = list.toArray();
-            array = list.toArray();
-            array = list.toArray();
-            array = list.toArray();
-            array = list.toArray();
-            array = list.toArray();
-        }
-    }
-
-    public void testLinkedListSize() {
-        LinkedList<Integer> list = mLinkedList;
-        int len;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            len = list.size();
-            len = list.size();
-            len = list.size();
-            len = list.size();
-            len = list.size();
-            len = list.size();
-            len = list.size();
-            len = list.size();
-            len = list.size();
-            len = list.size();
-        }
-    }
-
-    public void testLinkedListGet() {
-        int element;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            element = list.get(i);
-            element = list.get(i);
-            element = list.get(i);
-            element = list.get(i);
-            element = list.get(i);
-            element = list.get(i);
-            element = list.get(i);
-            element = list.get(i);
-            element = list.get(i);
-            element = list.get(i);
-        }
-    }
-
-    public void testLinkedListContains() {
-        boolean flag;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = list.contains(i);
-            flag = list.contains(i);
-            flag = list.contains(i);
-            flag = list.contains(i);
-            flag = list.contains(i);
-            flag = list.contains(i);
-            flag = list.contains(i);
-            flag = list.contains(i);
-            flag = list.contains(i);
-            flag = list.contains(i);
-        }
-    }
-
-    public void testLinkedListToArray1() {
-        Integer[] rArray = new Integer[100];
-        Integer[] array;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            array = list.toArray(rArray);
-            array = list.toArray(rArray);
-            array = list.toArray(rArray);
-            array = list.toArray(rArray);
-            array = list.toArray(rArray);
-            array = list.toArray(rArray);
-            array = list.toArray(rArray);
-            array = list.toArray(rArray);
-            array = list.toArray(rArray);
-            array = list.toArray(rArray);
-        }
-    }
-
-    public void testLinkedListSet() {
-        LinkedList<Integer> list = mLinkedList;
-        int value1 = 500, value2 = 0;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            list.set(value1, value2);
-            list.set(value1, value2);
-            list.set(value1, value2);
-            list.set(value1, value2);
-            list.set(value1, value2);
-            list.set(value1, value2);
-            list.set(value1, value2);
-            list.set(value1, value2);
-            list.set(value1, value2);
-            list.set(value1, value2);
-        }
-    }
-
-    public void testLinkedListIndexOf() {
-        int index;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            index = list.indexOf(0);
-            index = list.indexOf(0);
-            index = list.indexOf(0);
-            index = list.indexOf(0);
-            index = list.indexOf(0);
-            index = list.indexOf(0);
-            index = list.indexOf(0);
-            index = list.indexOf(0);
-            index = list.indexOf(0);
-            index = list.indexOf(0);
-
-        }
-    }
-
-    public void testLinkedListLastIndexOf() {
-        int index;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            index = list.lastIndexOf(0);
-            index = list.lastIndexOf(0);
-            index = list.lastIndexOf(0);
-            index = list.lastIndexOf(0);
-            index = list.lastIndexOf(0);
-            index = list.lastIndexOf(0);
-            index = list.lastIndexOf(0);
-            index = list.lastIndexOf(0);
-            index = list.lastIndexOf(0);
-            index = list.lastIndexOf(0);
-        }
-    }
-
-    public void testLinkedListRemove() {
-        int index;
-        LinkedList<Integer> list = new LinkedList(mLinkedList);
-        for (int i = 10; i > 0; i--) {
-            index = list.remove();
-            index = list.remove();
-            index = list.remove();
-            index = list.remove();
-            index = list.remove();
-            index = list.remove();
-            index = list.remove();
-            index = list.remove();
-            index = list.remove();
-            index = list.remove();
-        }
-    }
-
-    public void testLinkedListRemove1() {
-        int index;
-        LinkedList<Integer> list = new LinkedList(mLinkedList);
-        for (int i = 10; i > 0; i--) {
-            index = list.remove(0);
-            index = list.remove(0);
-            index = list.remove(0);
-            index = list.remove(0);
-            index = list.remove(0);
-            index = list.remove(0);
-            index = list.remove(0);
-            index = list.remove(0);
-            index = list.remove(0);
-            index = list.remove(0);
-        }
-    }
-
-    public void testLinkedListRemoveFirst() {
-        int index;
-        LinkedList<Integer> list = new LinkedList(mLinkedList);
-        for (int i = 10; i > 0; i--) {
-            index = list.removeFirst();
-            index = list.removeFirst();
-            index = list.removeFirst();
-            index = list.removeFirst();
-            index = list.removeFirst();
-            index = list.removeFirst();
-            index = list.removeFirst();
-            index = list.removeFirst();
-            index = list.removeFirst();
-            index = list.removeFirst();
-        }
-    }
-
-    public void testLinkedListRemoveLast() {
-        int index;
-        LinkedList<Integer> list = new LinkedList(mLinkedList);
-        for (int i = 10; i > 0; i--) {
-            index = list.removeLast();
-            index = list.removeLast();
-            index = list.removeLast();
-            index = list.removeLast();
-            index = list.removeLast();
-            index = list.removeLast();
-            index = list.removeLast();
-            index = list.removeLast();
-            index = list.removeLast();
-            index = list.removeLast();
-        }
-    }
-
-    public void testLinkedListAddAll() {
-        LinkedList<Integer> mList = mLinkedList;
-        boolean flag;
-        LinkedList<Integer> list = new LinkedList();
-        for (int i = 10; i > 0; i--) {
-            flag = list.addAll(mList);
-            flag = list.addAll(mList);
-            flag = list.addAll(mList);
-            flag = list.addAll(mList);
-            flag = list.addAll(mList);
-            flag = list.addAll(mList);
-            flag = list.addAll(mList);
-            flag = list.addAll(mList);
-            flag = list.addAll(mList);
-            flag = list.addAll(mList);
-        }
-    }
-
-    public void testLinkedListRemove2() {
-        LinkedList<String> list;
-        String s = new String("a");
-        list = new LinkedList();
-        for (int j = 1000; j > 0; j--) {
-            list.add("a");
-            list.add("b");
-        }
-        boolean flag;
-        for (int i = 10; i > 0; i--) {
-            flag = list.remove(s);
-            flag = list.remove(s);
-            flag = list.remove(s);
-            flag = list.remove(s);
-            flag = list.remove(s);
-            flag = list.remove(s);
-            flag = list.remove(s);
-            flag = list.remove(s);
-            flag = list.remove(s);
-            flag = list.remove(s);
-        }
-    }
-
-    public void testLinkedListAddAll1() {
-        LinkedList<Integer> mList = new LinkedList();
-        int pos = 0;
-        boolean flag;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = 0; i < 10; i++) {
-            flag = mList.addAll(pos, list);
-            flag = mList.addAll(pos, list);
-            flag = mList.addAll(pos, list);
-            flag = mList.addAll(pos, list);
-            flag = mList.addAll(pos, list);
-            flag = mList.addAll(pos, list);
-            flag = mList.addAll(pos, list);
-            flag = mList.addAll(pos, list);
-            flag = mList.addAll(pos, list);
-            flag = mList.addAll(pos, list);
-        }
-    }
-
-    public void testLinkedListClone() {
-        Object rObj;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = 100; i > 0; i--) {
-            rObj = list.clone();
-            rObj = list.clone();
-            rObj = list.clone();
-            rObj = list.clone();
-            rObj = list.clone();
-            rObj = list.clone();
-            rObj = list.clone();
-            rObj = list.clone();
-            rObj = list.clone();
-            rObj = list.clone();
-        }
-    }
-
-    public void testLinkedListHashcode() {
-        int element;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            element = list.hashCode();
-            element = list.hashCode();
-            element = list.hashCode();
-            element = list.hashCode();
-            element = list.hashCode();
-            element = list.hashCode();
-            element = list.hashCode();
-            element = list.hashCode();
-            element = list.hashCode();
-            element = list.hashCode();
-        }
-    }
-
-    public void testLinkedListElement() {
-        int element;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            element = list.element();
-            element = list.element();
-            element = list.element();
-            element = list.element();
-            element = list.element();
-            element = list.element();
-            element = list.element();
-            element = list.element();
-            element = list.element();
-            element = list.element();
-        }
-    }
-
-    public void testLinkedListToString() {
-        String str;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            str = list.toString();
-            str = list.toString();
-            str = list.toString();
-            str = list.toString();
-            str = list.toString();
-            str = list.toString();
-            str = list.toString();
-            str = list.toString();
-            str = list.toString();
-            str = list.toString();
-        }
-    }
-
-    public void testLinkedListIsEmpty() {
-        boolean flag;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = list.isEmpty();
-            flag = list.isEmpty();
-            flag = list.isEmpty();
-            flag = list.isEmpty();
-            flag = list.isEmpty();
-            flag = list.isEmpty();
-            flag = list.isEmpty();
-            flag = list.isEmpty();
-            flag = list.isEmpty();
-            flag = list.isEmpty();
-        }
-    }
-
-    public void testLinkedListOffer() {
-        LinkedList<Integer> list = new LinkedList();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            list.offer(i);
-            list.offer(i);
-            list.offer(i);
-            list.offer(i);
-            list.offer(i);
-            list.offer(i);
-            list.offer(i);
-            list.offer(i);
-            list.offer(i);
-            list.offer(i);
-        }
-    }
-
-    public void testLinkedListPeek() {
-        int element;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            element = list.peek();
-            element = list.peek();
-            element = list.peek();
-            element = list.peek();
-            element = list.peek();
-            element = list.peek();
-            element = list.peek();
-            element = list.peek();
-            element = list.peek();
-            element = list.peek();
-        }
-    }
-
-    public void testLinkedListPoll() {
-        int element;
-        LinkedList<Integer> list = new LinkedList(mLinkedList);
-        for (int i = 10; i > 0; i--) {
-            element = list.poll();
-            element = list.poll();
-            element = list.poll();
-            element = list.poll();
-            element = list.poll();
-            element = list.poll();
-            element = list.poll();
-            element = list.poll();
-            element = list.poll();
-            element = list.poll();
-        }
-    }
-
-    public void testLinkedListAddLast() {
-        LinkedList<Integer> list = new LinkedList();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            list.addLast(i);
-            list.addLast(i);
-            list.addLast(i);
-            list.addLast(i);
-            list.addLast(i);
-            list.addLast(i);
-            list.addLast(i);
-            list.addLast(i);
-            list.addLast(i);
-            list.addLast(i);
-        }
-    }
-
-    public void testLinkedListAddFirst() {
-        LinkedList<Integer> list = new LinkedList();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            list.addFirst(i);
-            list.addFirst(i);
-            list.addFirst(i);
-            list.addFirst(i);
-            list.addFirst(i);
-            list.addFirst(i);
-            list.addFirst(i);
-            list.addFirst(i);
-            list.addFirst(i);
-            list.addFirst(i);
-        }
-    }
-
-    public void testLinkedListIterator() {
-        ListIterator iterator;
-        LinkedList<Integer> list = mLinkedList;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            iterator = list.listIterator();
-            iterator = list.listIterator();
-            iterator = list.listIterator();
-            iterator = list.listIterator();
-            iterator = list.listIterator();
-            iterator = list.listIterator();
-            iterator = list.listIterator();
-            iterator = list.listIterator();
-            iterator = list.listIterator();
-            iterator = list.listIterator();
-        }
-    }
-}
diff --git a/tests/CoreTests/android/core/MathPerformanceTest.java b/tests/CoreTests/android/core/MathPerformanceTest.java
deleted file mode 100644
index b1eb500..0000000
--- a/tests/CoreTests/android/core/MathPerformanceTest.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import android.test.PerformanceTestBase;
-import android.test.PerformanceTestCase;
-
-/**
- * 
- * Implements basic performance test functionality for java.lang.Math
- * 
- */
-
-public class MathPerformanceTest extends PerformanceTestBase {
-    public static final int ITERATIONS = 1000;
-    public static final double sDouble1 = -2450.50;
-    public static final double sDouble2 = -500;
-    public static final float sFloat = 300.50f;
-    public static final int sInt = 90;
-
-    @Override
-    public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-        intermediates.setInternalIterations(ITERATIONS);
-        return 0;
-    }
-
-    public void testDoubleAbs() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.abs(sDouble1);
-            result = Math.abs(sDouble1);
-            result = Math.abs(sDouble1);
-            result = Math.abs(sDouble1);
-            result = Math.abs(sDouble1);
-            result = Math.abs(sDouble1);
-            result = Math.abs(sDouble1);
-            result = Math.abs(sDouble1);
-            result = Math.abs(sDouble1);
-            result = Math.abs(sDouble1);
-        }
-    }
-
-    public void testFloatAbs() {
-        float result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.abs(sFloat);
-            result = Math.abs(sFloat);
-            result = Math.abs(sFloat);
-            result = Math.abs(sFloat);
-            result = Math.abs(sFloat);
-            result = Math.abs(sFloat);
-            result = Math.abs(sFloat);
-            result = Math.abs(sFloat);
-            result = Math.abs(sFloat);
-            result = Math.abs(sFloat);
-        }
-    }
-
-    public void testMathSin() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.sin(sDouble1);
-            result = Math.sin(sDouble1);
-            result = Math.sin(sDouble1);
-            result = Math.sin(sDouble1);
-            result = Math.sin(sDouble1);
-            result = Math.sin(sDouble1);
-            result = Math.sin(sDouble1);
-            result = Math.sin(sDouble1);
-            result = Math.sin(sDouble1);
-            result = Math.sin(sDouble1);
-        }
-    }
-
-    public void testMathCos() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.cos(sDouble1);
-            result = Math.cos(sDouble1);
-            result = Math.cos(sDouble1);
-            result = Math.cos(sDouble1);
-            result = Math.cos(sDouble1);
-            result = Math.cos(sDouble1);
-            result = Math.cos(sDouble1);
-            result = Math.cos(sDouble1);
-            result = Math.cos(sDouble1);
-            result = Math.cos(sDouble1);
-        }
-    }
-
-    public void testMathTan() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.tan(sDouble1);
-            result = Math.tan(sDouble1);
-            result = Math.tan(sDouble1);
-            result = Math.tan(sDouble1);
-            result = Math.tan(sDouble1);
-            result = Math.tan(sDouble1);
-            result = Math.tan(sDouble1);
-            result = Math.tan(sDouble1);
-            result = Math.tan(sDouble1);
-            result = Math.tan(sDouble1);
-        }
-    }
-
-    public void testMathASin() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.asin(sDouble1);
-            result = Math.asin(sDouble1);
-            result = Math.asin(sDouble1);
-            result = Math.asin(sDouble1);
-            result = Math.asin(sDouble1);
-            result = Math.asin(sDouble1);
-            result = Math.asin(sDouble1);
-            result = Math.asin(sDouble1);
-            result = Math.asin(sDouble1);
-            result = Math.asin(sDouble1);
-        }
-    }
-
-    public void testMathACos() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.acos(sDouble1);
-            result = Math.acos(sDouble1);
-            result = Math.acos(sDouble1);
-            result = Math.acos(sDouble1);
-            result = Math.acos(sDouble1);
-            result = Math.acos(sDouble1);
-            result = Math.acos(sDouble1);
-            result = Math.acos(sDouble1);
-            result = Math.acos(sDouble1);
-            result = Math.acos(sDouble1);
-        }
-    }
-
-    public void testMathATan() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.atan(sDouble1);
-            result = Math.atan(sDouble1);
-            result = Math.atan(sDouble1);
-            result = Math.atan(sDouble1);
-            result = Math.atan(sDouble1);
-            result = Math.atan(sDouble1);
-            result = Math.atan(sDouble1);
-            result = Math.atan(sDouble1);
-            result = Math.atan(sDouble1);
-            result = Math.atan(sDouble1);
-        }
-    }
-
-    public void testMathLog() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.log(sDouble1);
-            result = Math.log(sDouble1);
-            result = Math.log(sDouble1);
-            result = Math.log(sDouble1);
-            result = Math.log(sDouble1);
-            result = Math.log(sDouble1);
-            result = Math.log(sDouble1);
-            result = Math.log(sDouble1);
-            result = Math.log(sDouble1);
-            result = Math.log(sDouble1);
-        }
-    }
-
-    public void testMathSqrt() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.sqrt(sDouble1);
-            result = Math.sqrt(sDouble1);
-            result = Math.sqrt(sDouble1);
-            result = Math.sqrt(sDouble1);
-            result = Math.sqrt(sDouble1);
-            result = Math.sqrt(sDouble1);
-            result = Math.sqrt(sDouble1);
-            result = Math.sqrt(sDouble1);
-            result = Math.sqrt(sDouble1);
-            result = Math.sqrt(sDouble1);
-        }
-    }
-
-    public void testMathCeil() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.ceil(sDouble1);
-            result = Math.ceil(sDouble1);
-            result = Math.ceil(sDouble1);
-            result = Math.ceil(sDouble1);
-            result = Math.ceil(sDouble1);
-            result = Math.ceil(sDouble1);
-            result = Math.ceil(sDouble1);
-            result = Math.ceil(sDouble1);
-            result = Math.ceil(sDouble1);
-            result = Math.ceil(sDouble1);
-        }
-    }
-
-    public void testMathRound() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.round(sDouble1);
-            result = Math.round(sDouble1);
-            result = Math.round(sDouble1);
-            result = Math.round(sDouble1);
-            result = Math.round(sDouble1);
-            result = Math.round(sDouble1);
-            result = Math.round(sDouble1);
-            result = Math.round(sDouble1);
-            result = Math.round(sDouble1);
-            result = Math.round(sDouble1);
-        }
-    }
-
-    public void testMathFloor() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.floor(sDouble1);
-            result = Math.floor(sDouble1);
-            result = Math.floor(sDouble1);
-            result = Math.floor(sDouble1);
-            result = Math.floor(sDouble1);
-            result = Math.floor(sDouble1);
-            result = Math.floor(sDouble1);
-            result = Math.floor(sDouble1);
-            result = Math.floor(sDouble1);
-            result = Math.floor(sDouble1);
-        }
-    }
-
-    public void testMathExp() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.exp(sDouble1);
-            result = Math.exp(sDouble1);
-            result = Math.exp(sDouble1);
-            result = Math.exp(sDouble1);
-            result = Math.exp(sDouble1);
-            result = Math.exp(sDouble1);
-            result = Math.exp(sDouble1);
-            result = Math.exp(sDouble1);
-            result = Math.exp(sDouble1);
-            result = Math.exp(sDouble1);
-        }
-    }
-
-    /**
-     * 
-     */
-
-    public void testMathPow() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.pow(sDouble1, sDouble2);
-            result = Math.pow(sDouble1, sDouble2);
-            result = Math.pow(sDouble1, sDouble2);
-            result = Math.pow(sDouble1, sDouble2);
-            result = Math.pow(sDouble1, sDouble2);
-            result = Math.pow(sDouble1, sDouble2);
-            result = Math.pow(sDouble1, sDouble2);
-            result = Math.pow(sDouble1, sDouble2);
-            result = Math.pow(sDouble1, sDouble2);
-            result = Math.pow(sDouble1, sDouble2);
-        }
-    }
-
-    public void testMathMax() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.max(sDouble1, sDouble2);
-            result = Math.max(sDouble1, sDouble2);
-            result = Math.max(sDouble1, sDouble2);
-            result = Math.max(sDouble1, sDouble2);
-            result = Math.max(sDouble1, sDouble2);
-            result = Math.max(sDouble1, sDouble2);
-            result = Math.max(sDouble1, sDouble2);
-            result = Math.max(sDouble1, sDouble2);
-            result = Math.max(sDouble1, sDouble2);
-            result = Math.max(sDouble1, sDouble2);
-        }
-    }
-
-    public void testMathMin() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.min(sDouble1, sDouble2);
-            result = Math.min(sDouble1, sDouble2);
-            result = Math.min(sDouble1, sDouble2);
-            result = Math.min(sDouble1, sDouble2);
-            result = Math.min(sDouble1, sDouble2);
-            result = Math.min(sDouble1, sDouble2);
-            result = Math.min(sDouble1, sDouble2);
-            result = Math.min(sDouble1, sDouble2);
-            result = Math.min(sDouble1, sDouble2);
-            result = Math.min(sDouble1, sDouble2);
-        }
-    }
-
-    public void testMathRandom() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.random();
-            result = Math.random();
-            result = Math.random();
-            result = Math.random();
-            result = Math.random();
-            result = Math.random();
-            result = Math.random();
-            result = Math.random();
-            result = Math.random();
-            result = Math.random();
-        }
-    }
-
-    public void testMathIEEERemainder() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-            result = Math.IEEEremainder(sDouble1, sDouble2);
-        }
-    }
-
-    public void testMathToDegrees() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.toDegrees(sDouble1);
-            result = Math.toDegrees(sDouble1);
-            result = Math.toDegrees(sDouble1);
-            result = Math.toDegrees(sDouble1);
-            result = Math.toDegrees(sDouble1);
-            result = Math.toDegrees(sDouble1);
-            result = Math.toDegrees(sDouble1);
-            result = Math.toDegrees(sDouble1);
-            result = Math.toDegrees(sDouble1);
-            result = Math.toDegrees(sDouble1);
-        }
-    }
-
-    public void testMathToRadians() {
-        double result;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            result = Math.toRadians(sDouble1);
-            result = Math.toRadians(sDouble1);
-            result = Math.toRadians(sDouble1);
-            result = Math.toRadians(sDouble1);
-            result = Math.toRadians(sDouble1);
-            result = Math.toRadians(sDouble1);
-            result = Math.toRadians(sDouble1);
-            result = Math.toRadians(sDouble1);
-            result = Math.toRadians(sDouble1);
-            result = Math.toRadians(sDouble1);
-        }
-    }
-}
diff --git a/tests/CoreTests/android/core/PerformanceTests.java b/tests/CoreTests/android/core/PerformanceTests.java
deleted file mode 100644
index faf46e6..0000000
--- a/tests/CoreTests/android/core/PerformanceTests.java
+++ /dev/null
@@ -1,1224 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import org.apache.harmony.dalvik.NativeTestTarget;
-
-import android.test.PerformanceTestBase;
-import android.test.PerformanceTestCase;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import junit.framework.Assert;
-
-public class PerformanceTests {
-    public static String[] children() {
-        return new String[] {
-                //StringEquals2.class.getName(),
-                //StringEquals10.class.getName(),
-                //StringEquals20.class.getName(),
-                //StringEquals200.class.getName(),
-                //StringEquals200U.class.getName(),
-                //StringCompareTo10.class.getName(),
-                //StringCompareTo200.class.getName(),
-                StringLength.class.getName(),
-                StringCrawl.class.getName(),
-                Ackermann.class.getName(),
-                AddTest.class.getName(),
-//                AddMemberVariableTest.class.getName(),
-                ArrayListIterator.class.getName(),
-                BoundsCheckTest.class.getName(),
-//                EmptyClassBaseTest.class.getName(),
-                EmptyJniStaticMethod0.class.getName(),
-                EmptyJniStaticMethod6.class.getName(),
-                EmptyJniStaticMethod6L.class.getName(),
-                FibonacciFast.class.getName(),
-                FibonacciSlow.class.getName(),
-//                LoopTests.class.getName(),
-//                HashMapTest.class.getName(),
-//                InterfaceTests.class.getName(),
-                LocalVariableAccess.class.getName(),
-                MemeberVariableAccess.class.getName(),
-                NestedLoop.class.getName(),
-//                StringConcatenationTests.class.getName(),
-//                ArrayListBase.class.getName(),
-                SynchronizedGetAndSetInt.class.getName(),
-
-                /* this will not work on JamVM -- lacks atomic ops */
-                AtomicGetAndSetInt.class.getName(),
-        };
-    }
-
-    public static class SizeTest {
-        private int mSize;
-
-        public SizeTest(int size) {
-            mSize = size;
-        }
-
-        public int size() {
-            return mSize;
-        }
-    }
-
-    public static class LocalVariableAccess extends PerformanceTestBase {
-        private static final int ITERATIONS = 100000;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 20);
-            return 0;
-        }
-
-        public void testRun() {
-            boolean variable = false;
-            boolean local = true;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                local = variable;
-                local = variable;
-                local = variable;
-                local = variable;
-                local = variable; // 5
-                local = variable;
-                local = variable;
-                local = variable;
-                local = variable;
-                local = variable; // 10
-                local = variable;
-                local = variable;
-                local = variable;
-                local = variable;
-                local = variable; // 15
-                local = variable;
-                local = variable;
-                local = variable;
-                local = variable;
-                local = variable; // 20
-            }
-        }
-    }
-
-    /* This test is intentionally misspelled. Please do not rename it. Thanks! */
-    public static class MemeberVariableAccess extends PerformanceTestBase {
-        private static final int ITERATIONS = 100000;
-
-        public volatile boolean mMember = false;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 20);
-            return 0;
-        }
-
-        public void testRun() {
-            boolean local = true;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                local = mMember;
-                local = mMember;
-                local = mMember;
-                local = mMember;
-                local = mMember; // 5
-                local = mMember;
-                local = mMember;
-                local = mMember;
-                local = mMember;
-                local = mMember; // 10
-                local = mMember;
-                local = mMember;
-                local = mMember;
-                local = mMember;
-                local = mMember; // 15
-                local = mMember;
-                local = mMember;
-                local = mMember;
-                local = mMember;
-                local = mMember; // 20
-            }
-        }
-    }
-
-    public static class ArrayListIterator extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-        private ArrayList mList;
-        private String[] mKeys;
-        private Iterator mIterator;
-
-        public void setUp() throws Exception {
-            super.setUp();
-            mList = new ArrayList();
-            mKeys = new String[ITERATIONS];
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                mKeys[i] = Integer.toString(i, 16);
-                mList.add(mKeys[i]);
-            }
-        }
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS);
-            return 0;
-        }
-
-        public void testRun() {
-            mIterator = mList.iterator();
-            while (mIterator.hasNext()) {
-                mIterator.next();
-            }
-        }
-    }
-
-    public static class Ackermann extends PerformanceTestBase {
-        public static final int ITERATIONS = 100;
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS);
-            return 0;
-        }
-
-        public void testRun() {
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                ackermann(3, 13);
-            }
-        }
-
-        private int ackermann(int m, int n) {
-            if (m == 0)
-                return n + 1;
-            if (n == 0)
-                return ackermann(m - 1, 1);
-            return ackermann(m, n - 1);
-        }
-    }
-
-    public static class FibonacciSlow extends PerformanceTestBase {
-        public void setUp() throws Exception {
-            super.setUp();
-            Assert.assertEquals(0, fibonacci(0));
-            Assert.assertEquals(1, fibonacci(1));
-            Assert.assertEquals(1, fibonacci(2));
-            Assert.assertEquals(2, fibonacci(3));
-            Assert.assertEquals(6765, fibonacci(20));
-        }
-
-        public void tearDown() {
-        }
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            return 0;
-        }
-
-        public void testRun() {
-            fibonacci(20);
-        }
-
-        private long fibonacci(long n) {
-            if (n == 0)
-                return 0;
-            if (n == 1)
-                return 1;
-            return fibonacci(n - 2) + fibonacci(n - 1);
-        }
-    }
-
-    public static class FibonacciFast extends PerformanceTestBase {
-        public void setUp() throws Exception {
-            super.setUp();
-            Assert.assertEquals(0, fibonacci(0));
-            Assert.assertEquals(1, fibonacci(1));
-            Assert.assertEquals(1, fibonacci(2));
-            Assert.assertEquals(2, fibonacci(3));
-            Assert.assertEquals(6765, fibonacci(20));
-        }
-
-        public void tearDown() {
-        }
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            return 0;
-        }
-
-        public void testRun() {
-            fibonacci(5000);
-        }
-
-        private long fibonacci(long n) {
-            if (n == 0)
-                return 0;
-            if (n == 1)
-                return 1;
-
-            int x = 0;
-            int y = 1;
-            for (int i = 0; i < n - 1; i++) {
-                y = y + x;
-                x = y - x;
-            }
-
-            return y;
-        }
-    }
-
-    public static class HashMapTest extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-        private HashMap mMap;
-        private String[] mKeys;
-
-        public void setUp() throws Exception {
-            super.setUp();
-            mMap = new HashMap();
-            mKeys = new String[ITERATIONS];
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                mKeys[i] = Integer.toString(i, 16);
-                mMap.put(mKeys[i], i);
-            }
-        }
-
-        public void tearDown() {
-        }
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS);
-            return 0;
-        }
-
-        public void testHashMapContainsKey() {
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                mMap.containsKey(mKeys[i]);
-            }
-        }
-
-        public void testHashMapIterator() {
-            Iterator iterator;
-
-            iterator = mMap.entrySet().iterator();
-            while (iterator.hasNext()) {
-                iterator.next();
-            }
-        }
-
-        public void testHashMapPut() {
-            HashMap map = new HashMap();
-            String[] keys = mKeys;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                map.put(keys[i], i);
-            }
-        }
-    }
-
-    interface IA {
-        void funcA0();
-        void funcA1();
-        void funcA2();
-        void funcA3();
-    }
-    interface IAB extends IA {
-        void funcAB0();
-        void funcAB1();
-        void funcAB2();
-        void funcAB3();
-    }
-    interface IABC extends IAB {
-        void funcABC0();
-        void funcABC1();
-        void funcABC2();
-        void funcABC3();
-    }
-    interface IB {
-        void funcB0();
-        void funcB1();
-        void funcB2();
-        void funcB3();
-    }
-    interface IC {
-        void funcC0();
-        void funcC1();
-        void funcC2();
-        void funcC3();
-    }
-
-    static class Alphabet implements Cloneable, IB, IABC, IC, Runnable {
-        public void funcA0() {
-        }
-        public void funcA1() {
-        }
-        public void funcA2() {
-        }
-        public void funcA3() {
-        }
-        public void funcAB0() {
-        }
-        public void funcAB1() {
-        }
-        public void funcAB2() {
-        }
-        public void funcAB3() {
-        }
-        public void funcABC0() {
-        }
-        public void funcABC1() {
-        }
-        public void funcABC2() {
-        }
-        public void funcABC3() {
-        }
-        public void funcB0() {
-        }
-        public void funcB1() {
-        }
-        public void funcB2() {
-        }
-        public void funcB3() {
-        }
-        public void funcC0() {
-        }
-        public void funcC1() {
-        }
-        public void funcC2() {
-        }
-        public void funcC3() {
-        }
-        public void run() {
-        }
-    };
-
-    public static class InterfaceTests extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        /* call method directly */
-        public void testInterfaceCalls0() {
-            Alphabet alpha = new Alphabet();
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                alpha.funcABC1();
-                alpha.funcABC1();
-                alpha.funcABC1();
-                alpha.funcABC1();
-                alpha.funcABC1();
-                alpha.funcABC1();
-                alpha.funcABC1();
-                alpha.funcABC1();
-                alpha.funcABC1();
-                alpha.funcABC1();
-            }
-        }
-
-       /* call method through interface reference */
-        public void testInterfaceCalls1() {
-            Alphabet alpha = new Alphabet();
-            IABC iabc = alpha;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                iabc.funcABC1();
-                iabc.funcABC1();
-                iabc.funcABC1();
-                iabc.funcABC1();
-                iabc.funcABC1();
-                iabc.funcABC1();
-                iabc.funcABC1();
-                iabc.funcABC1();
-                iabc.funcABC1();
-                iabc.funcABC1();
-            }
-        }
-
-        public void testInstanceOfTrivial() {
-            Alphabet alpha = new Alphabet();
-            IABC iabc = alpha;
-            boolean val;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                val = iabc instanceof Alphabet;
-                val = iabc instanceof Alphabet;
-                val = iabc instanceof Alphabet;
-                val = iabc instanceof Alphabet;
-                val = iabc instanceof Alphabet;
-                val = iabc instanceof Alphabet;
-                val = iabc instanceof Alphabet;
-                val = iabc instanceof Alphabet;
-                val = iabc instanceof Alphabet;
-                val = iabc instanceof Alphabet;
-            }
-        }
-
-        public void testInstanceOfInterface() {
-            Alphabet alpha = new Alphabet();
-            IABC iabc = alpha;
-            boolean val;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                val = iabc instanceof IA;
-                val = iabc instanceof IA;
-                val = iabc instanceof IA;
-                val = iabc instanceof IA;
-                val = iabc instanceof IA;
-                val = iabc instanceof IA;
-                val = iabc instanceof IA;
-                val = iabc instanceof IA;
-                val = iabc instanceof IA;
-                val = iabc instanceof IA;
-            }
-        }
-
-        public void testInstanceOfNot() {
-            Alphabet alpha = new Alphabet();
-            IABC iabc = alpha;
-            boolean val;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                val = iabc instanceof EmptyInterface;
-                val = iabc instanceof EmptyInterface;
-                val = iabc instanceof EmptyInterface;
-                val = iabc instanceof EmptyInterface;
-                val = iabc instanceof EmptyInterface;
-                val = iabc instanceof EmptyInterface;
-                val = iabc instanceof EmptyInterface;
-                val = iabc instanceof EmptyInterface;
-                val = iabc instanceof EmptyInterface;
-                val = iabc instanceof EmptyInterface;
-            }
-        }
-    }
-
-    public static class NestedLoop extends PerformanceTestBase {
-        private static final int ITERATIONS = 10;
-        private static final int LOOPS = 5;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * LOOPS);
-            return 0;
-        }
-
-        public void testRun() {
-            int x = 0;
-            for (int a = 0; a < ITERATIONS; a++) {
-                for (int b = 0; b < ITERATIONS; b++) {
-                    for (int c = 0; c < ITERATIONS; c++) {
-                        for (int d = 0; d < ITERATIONS; d++) {
-                            for (int e = 0; e < ITERATIONS; e++) {
-                                x++;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public static class StringConcatenationTests extends PerformanceTestBase {
-        private static final int ITERATIONS = 1000;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS);
-            return 0;
-        }
-
-        public void testStringConcatenation1() {
-            StringBuffer buffer = new StringBuffer();
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                buffer.append("Hello World!\n");
-            }
-            buffer = null;
-        }
-
-        public void testStringConcatenation2() {
-            String string = "";
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                string += "Hello World!\n";
-            }
-            string = null;
-        }
-    }
-
-    public static class StringLength extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-        private static final String TEST_STRING = "This is the string we use for testing..."; // 40 chars
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        public void testRun() {
-            String testStr = TEST_STRING;
-            int length;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                length = testStr.length();
-                length = testStr.length();
-                length = testStr.length();
-                length = testStr.length();
-                length = testStr.length();
-                length = testStr.length();
-                length = testStr.length();
-                length = testStr.length();
-                length = testStr.length();
-                length = testStr.length();
-            }
-        }
-    }
-
-    public static class EmptyJniStaticMethod0 extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        public void testRun() {
-            int a, b, c, d, e, f;
-
-            a = b = c = d = e = f = 0;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-            }
-        }
-    }
-    public static class EmptyJniStaticMethod6 extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        public void testRun() {
-            int a, b, c, d, e, f;
-
-            a = b = c = d = e = f = 0;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-            }
-        }
-    }
-    public static class EmptyJniStaticMethod6L extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        public void testRun() {
-            String a = null;
-            String[] b = null;
-            int[][] c = null;
-            Object d = null;
-            Object[] e = null;
-            Object[][][][] f = null;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6L(a, b, c, d, e, f);
-            }
-        }
-    }
-
-    public static class StringCrawl extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-        private static final String TEST_STRING = "This is the string we use for testing..."; // 40 chars
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * TEST_STRING.length());
-            return 0;
-        }
-
-        public void testRun() {
-            String testStr = TEST_STRING;
-            char ch;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                /* this is the wrong way to walk through a string */
-                for (int j = 0; j < testStr.length(); j++) {
-                    ch = testStr.charAt(j);
-                }
-            }
-        }
-    }
-
-    public static class AddTest extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 20);
-            return 0;
-        }
-
-        public void testRun() {
-            int j = 0;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-            }
-        }
-    }
-
-    public static class AddMemberVariableTest extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-        private int j;
-
-        public void setUp() throws Exception {
-           super.setUp();
-           j = 0;
-        }
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        public void testAddMemberVariableTest() {
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-                j++;
-            }
-        }
-
-        public void testAddMemberVariableInMethodTest() {
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                add();
-                add();
-                add();
-                add();
-                add();
-                add();
-                add();
-                add();
-                add();
-                add();
-            }
-        }
-
-        public void add() {
-            j++;
-        }
-    }
-
-    private interface EmptyInterface {
-        public void emptyVirtual();
-
-    }
-
-    private static class EmptyClass implements EmptyInterface {
-        public void emptyVirtual() {
-        }
-
-        public static void emptyStatic() {
-        }
-    }
-
-    public static class EmptyClassBaseTest extends PerformanceTestBase {
-        protected EmptyInterface mEmptyInterface;
-        protected EmptyClass mEmptyClass;
-
-        public void setUp() throws Exception {
-            super.setUp();
-            mEmptyClass = new EmptyClass();
-            mEmptyInterface = mEmptyClass;
-        }
-        private static final int ITERATIONS = 10000;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        public void testEmptyVirtualMethod() {
-            //EmptyClass emtpyClass = mEmptyClass;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                mEmptyClass.emptyVirtual();
-                mEmptyClass.emptyVirtual();
-                mEmptyClass.emptyVirtual();
-                mEmptyClass.emptyVirtual();
-                mEmptyClass.emptyVirtual();
-                mEmptyClass.emptyVirtual();
-                mEmptyClass.emptyVirtual();
-                mEmptyClass.emptyVirtual();
-                mEmptyClass.emptyVirtual();
-                mEmptyClass.emptyVirtual();
-            }
-        }
-
-        public void testEmptyVirtualMethodTestInLocal() {
-            EmptyClass empty = mEmptyClass;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                empty.emptyVirtual();
-                empty.emptyVirtual();
-                empty.emptyVirtual();
-                empty.emptyVirtual();
-                empty.emptyVirtual();
-                empty.emptyVirtual();
-                empty.emptyVirtual();
-                empty.emptyVirtual();
-                empty.emptyVirtual();
-                empty.emptyVirtual();
-            }
-        }
-
-    public void testEmptyStaticMethod () {
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                EmptyClass.emptyStatic();
-                EmptyClass.emptyStatic();
-                EmptyClass.emptyStatic();
-                EmptyClass.emptyStatic();
-                EmptyClass.emptyStatic();
-                EmptyClass.emptyStatic();
-                EmptyClass.emptyStatic();
-                EmptyClass.emptyStatic();
-                EmptyClass.emptyStatic();
-                EmptyClass.emptyStatic();
-            }
-        }
-
-    public void testEmptyJniStaticMethod0() {
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-                NativeTestTarget.emptyJniStaticMethod0();
-            }
-        }
-
-    public void testEmptyJniStaticMethod6() {
-            int a, b, c, d, e, f;
-
-            a = b = c = d = e = f = 0;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-                NativeTestTarget.emptyJniStaticMethod6(a, b, c, d, e, f);
-            }
-        }
-
-    public void testEmptyInternalStaticMethod() {
-            /*
-             * The method called is a VM-internal method with no extra
-             * wrapping.
-             */
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                NativeTestTarget.emptyInternalStaticMethod();
-                NativeTestTarget.emptyInternalStaticMethod();
-                NativeTestTarget.emptyInternalStaticMethod();
-                NativeTestTarget.emptyInternalStaticMethod();
-                NativeTestTarget.emptyInternalStaticMethod();
-                NativeTestTarget.emptyInternalStaticMethod();
-                NativeTestTarget.emptyInternalStaticMethod();
-                NativeTestTarget.emptyInternalStaticMethod();
-                NativeTestTarget.emptyInternalStaticMethod();
-                NativeTestTarget.emptyInternalStaticMethod();
-            }
-        }
-
-    public void testEmptyInlineStaticMethod() {
-            /*
-             * The method called is a VM-internal method that gets
-             * specially "inlined" in a bytecode transformation.
-             */
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                NativeTestTarget.emptyInlineMethod();
-                NativeTestTarget.emptyInlineMethod();
-                NativeTestTarget.emptyInlineMethod();
-                NativeTestTarget.emptyInlineMethod();
-                NativeTestTarget.emptyInlineMethod();
-                NativeTestTarget.emptyInlineMethod();
-                NativeTestTarget.emptyInlineMethod();
-                NativeTestTarget.emptyInlineMethod();
-                NativeTestTarget.emptyInlineMethod();
-                NativeTestTarget.emptyInlineMethod();
-            }
-        }
-
-    public void testEmptyInterfaceMethodTest() {
-            EmptyInterface emptyInterface = mEmptyInterface;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                emptyInterface.emptyVirtual();
-                emptyInterface.emptyVirtual();
-                emptyInterface.emptyVirtual();
-                emptyInterface.emptyVirtual();
-                emptyInterface.emptyVirtual();
-                emptyInterface.emptyVirtual();
-                emptyInterface.emptyVirtual();
-                emptyInterface.emptyVirtual();
-                emptyInterface.emptyVirtual();
-                emptyInterface.emptyVirtual();
-            }
-        }
-    }
-
-    public static class LoopTests extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-        private SizeTest mSizeTest = new SizeTest(ITERATIONS);
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS);
-            return 0;
-        }
-
-        public void testForLoopTest() {
-            int i = 0;
-            for (; i < 10000; i++) {
-            }
-        }
-
-        public void testWhileLoopTest() {
-            int i = 0;
-
-            while (i < 10000) {
-                i++;
-            }
-        }
-
-        public void testForLoopSizeCalledInside() {
-            for (int i = 0; i < mSizeTest.size(); i++) {
-            }
-        }
-
-        public void testForLoopSizeCalledOutside() {
-            final int size = mSizeTest.size();
-            for (int i = 0; i < size; i++) {
-            }
-        }
-    }
-
-    public static class BoundsCheckTest extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        public void testRun() {
-            int[] data = new int[1];
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                data[0] = i;
-                data[0] = i;
-                data[0] = i;
-                data[0] = i;
-                data[0] = i;
-                data[0] = i;
-                data[0] = i;
-                data[0] = i;
-                data[0] = i;
-                data[0] = i;
-            }
-        }
-    }
-
-    public static class ArrayListBase extends PerformanceTestBase {
-        public void setUp() throws Exception {
-            super.setUp();
-            mList = new ArrayList();
-            mList.add(0);
-            mList.add(1);
-            mList.add(2);
-            mList.add(3);
-            mList.add(4);
-            mList.add(5);
-            mList.add(6);
-            mList.add(7);
-            mList.add(8);
-            mList.add(9);
-        }
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(100);
-            return 0;
-        }
-
-        ArrayList<Integer> mList;
-
-        public void testForArrayList() {
-            int i = 0;
-            int res = 0;
-            for (; i < 100; i++) {
-                for (int j = 0; j < mList.size(); j++) {
-                    res += mList.get(j);
-                }
-            }
-        }
-
-        public void testForLocalArrayList() {
-            int i = 0;
-            int res = 0;
-            for (; i < 100; i++) {
-                final List<Integer> list = mList;
-                final int N = list.size();
-                for (int j = 0; j < N; j++) {
-                    res += list.get(j);
-                }
-            }
-        }
-
-        public void testForEachArrayList() {
-            int i = 0;
-            int res = 0;
-            for (; i < 100; i++) {
-                for (Integer v : mList) {
-                    res += v;
-                }
-            }
-        }
-    }
-
-    public static class SynchronizedGetAndSetInt extends PerformanceTestBase {
-        private static final int ITERATIONS = 100000;
-
-        public int mMember = 0;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS);
-            return 0;
-        }
-
-        public void testRun() {
-            int result = 0;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                synchronized (this) {
-                    result = mMember;
-                    mMember = i;
-                }
-            }
-        }
-    }
-
-    public static class AtomicGetAndSetInt extends PerformanceTestBase {
-        private static final int ITERATIONS = 100000;
-
-        public AtomicInteger mMember = new AtomicInteger(0);
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS);
-            return 0;
-        }
-
-        public void testRun() {
-            int result = 0;
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                result = mMember.getAndSet(i);
-            }
-        }
-    }
-
-    public static abstract class StringEquals extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-
-        protected String mString1, mString2;
-        public void setUp() throws Exception {
-          super.setUp();
-        }
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        public void testRun() {
-            String string1 = mString1;
-            String string2 = mString2;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                string1.equals(string2);
-                string1.equals(string2);
-                string1.equals(string2);
-                string1.equals(string2);
-                string1.equals(string2);
-                string1.equals(string2);
-                string1.equals(string2);
-                string1.equals(string2);
-                string1.equals(string2);
-                string1.equals(string2);
-            }
-        }
-    }
-
-    public static class StringEquals2 extends StringEquals {
-        public void setUp() throws Exception {
-            mString1 = "01";
-            mString2 = "0x";
-        }
-    }
-    public static class StringEquals10 extends StringEquals {
-        public void setUp() throws Exception {
-            mString1 = "0123456789";
-            mString2 = "012345678x";
-        }
-    }
-    public static class StringEquals20 extends StringEquals {
-        public void setUp() throws Exception {
-            mString1 = "01234567890123456789";
-            mString2 = "0123456789012345678x";
-        }
-    }
-
-    public static class StringEquals200 extends StringEquals {
-        public void setUp() throws Exception {
-            mString1 = "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789";
-            mString2 = "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "012345678901234567890123456789012345678x";
-        }
-    }
-    public static class StringEquals200U extends StringEquals {
-        /* make one of the strings non-word aligned (bad memcmp case) */
-        public void setUp() throws Exception {
-            String tmpStr;
-            mString1 = "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789";
-            tmpStr = "z0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "012345678901234567890123456789012345678x";
-            mString2 = tmpStr.substring(1);
-        }
-    }
-
-    public static abstract class StringCompareTo extends PerformanceTestBase {
-        private static final int ITERATIONS = 10000;
-
-        protected String mString1, mString2;
-
-        public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-            intermediates.setInternalIterations(ITERATIONS * 10);
-            return 0;
-        }
-
-        public void testRun() {
-            String string1 = mString1;
-            String string2 = mString2;
-
-            for (int i = ITERATIONS - 1; i >= 0; i--) {
-                string1.compareTo(string2);
-                string1.compareTo(string2);
-                string1.compareTo(string2);
-                string1.compareTo(string2);
-                string1.compareTo(string2);
-                string1.compareTo(string2);
-                string1.compareTo(string2);
-                string1.compareTo(string2);
-                string1.compareTo(string2);
-                string1.compareTo(string2);
-            }
-        }
-    }
-    public static class StringCompareTo10 extends StringCompareTo {
-        public void setUp() throws Exception {
-            mString1 = "0123456789";
-            mString2 = "012345678x";
-        }
-    }
-    public static class StringCompareTo200 extends StringCompareTo {
-        public void setUp() throws Exception {
-            mString1 = "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789";
-            mString2 = "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "0123456789012345678901234567890123456789"
-                    + "012345678901234567890123456789012345678x";
-        }
-    }
-}
-
diff --git a/tests/CoreTests/android/core/TreeMapPerformanceTest.java b/tests/CoreTests/android/core/TreeMapPerformanceTest.java
deleted file mode 100644
index 3a210f4..0000000
--- a/tests/CoreTests/android/core/TreeMapPerformanceTest.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import android.test.PerformanceTestBase;
-import android.test.PerformanceTestCase;
-
-import java.util.Collection;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/**
- * Implements basic performance test functionality for java.util.TreeMap
- */
-
-public class TreeMapPerformanceTest extends PerformanceTestBase {
-    public static final int ITERATIONS = 1000;
-    public static TreeMap<String, Integer> sMap;
-    public static String[] sKeys;
-
-    @Override
-    @SuppressWarnings("unchecked")
-    protected void setUp() throws Exception {
-        super.setUp();
-        sMap = new TreeMap();
-        sKeys = new String[ITERATIONS];
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            sKeys[i] = Integer.toString(i, 16);
-            sMap.put(sKeys[i], i);
-        }
-    }
-
-    @Override
-    public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-        intermediates.setInternalIterations(ITERATIONS);
-        return 0;
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testTreeMapPut() {
-        TreeMap map = new TreeMap();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            map.put(i, i);
-            map.put(i, i);
-            map.put(i, i);
-            map.put(i, i);
-            map.put(i, i);
-            map.put(i, i);
-            map.put(i, i);
-            map.put(i, i);
-            map.put(i, i);
-            map.put(i, i);
-        }
-    }
-
-    public void testTreeMapGet() {
-        int value;
-        TreeMap<String, Integer> map = sMap;
-        String[] keys = sKeys;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            value = map.get(keys[i]);
-            value = map.get(keys[i]);
-            value = map.get(keys[i]);
-            value = map.get(keys[i]);
-            value = map.get(keys[i]);
-            value = map.get(keys[i]);
-            value = map.get(keys[i]);
-            value = map.get(keys[i]);
-            value = map.get(keys[i]);
-            value = map.get(keys[i]);
-        }
-    }
-
-    public void testTreeMapFirstKey() {
-        String key;
-        TreeMap<String, Integer> map = sMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            key = map.firstKey();
-            key = map.firstKey();
-            key = map.firstKey();
-            key = map.firstKey();
-            key = map.firstKey();
-            key = map.firstKey();
-            key = map.firstKey();
-            key = map.firstKey();
-            key = map.firstKey();
-            key = map.firstKey();
-        }
-    }
-
-    public void testTreeMapKeySet() {
-        Set keyset;
-        TreeMap<String, Integer> map = sMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            keyset = map.keySet();
-            keyset = map.keySet();
-            keyset = map.keySet();
-            keyset = map.keySet();
-            keyset = map.keySet();
-            keyset = map.keySet();
-            keyset = map.keySet();
-            keyset = map.keySet();
-            keyset = map.keySet();
-            keyset = map.keySet();
-        }
-    }
-
-    public void testTreeMapEntrySet() {
-        Set keyset;
-        TreeMap<String, Integer> map = sMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            keyset = map.entrySet();
-            keyset = map.entrySet();
-            keyset = map.entrySet();
-            keyset = map.entrySet();
-            keyset = map.entrySet();
-            keyset = map.entrySet();
-            keyset = map.entrySet();
-            keyset = map.entrySet();
-            keyset = map.entrySet();
-            keyset = map.entrySet();
-        }
-    }
-
-    public void testTreeMapValues() {
-        Collection collection;
-        TreeMap<String, Integer> map = sMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            collection = map.values();
-            collection = map.values();
-            collection = map.values();
-            collection = map.values();
-            collection = map.values();
-            collection = map.values();
-            collection = map.values();
-            collection = map.values();
-            collection = map.values();
-            collection = map.values();
-        }
-    }
-
-    public void testTreeMapSize() {
-        int len;
-        TreeMap<String, Integer> map = sMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            len = map.size();
-            len = map.size();
-            len = map.size();
-            len = map.size();
-            len = map.size();
-            len = map.size();
-            len = map.size();
-            len = map.size();
-            len = map.size();
-            len = map.size();
-        }
-    }
-
-    public void testTreeMapContainsKey() {
-        boolean flag;
-        String key = sKeys[525];
-        TreeMap<String, Integer> map = sMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = map.containsKey(key);
-            flag = map.containsKey(key);
-            flag = map.containsKey(key);
-            flag = map.containsKey(key);
-            flag = map.containsKey(key);
-            flag = map.containsKey(key);
-            flag = map.containsKey(key);
-            flag = map.containsKey(key);
-            flag = map.containsKey(key);
-            flag = map.containsKey(key);
-        }
-    }
-
-    public void testTreeMapContainsValue() {
-        boolean flag;
-        TreeMap<String, Integer> map = sMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = map.containsValue(i);
-            flag = map.containsValue(i);
-            flag = map.containsValue(i);
-            flag = map.containsValue(i);
-            flag = map.containsValue(i);
-            flag = map.containsValue(i);
-            flag = map.containsValue(i);
-            flag = map.containsValue(i);
-            flag = map.containsValue(i);
-            flag = map.containsValue(i);
-        }
-    }
-
-    public void testTreeMapHeadMap() {
-        SortedMap map;
-        String str = sKeys[100];
-        TreeMap<String, Integer> tMap = sMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            map = tMap.headMap(str);
-            map = tMap.headMap(str);
-            map = tMap.headMap(str);
-            map = tMap.headMap(str);
-            map = tMap.headMap(str);
-            map = tMap.headMap(str);
-            map = tMap.headMap(str);
-            map = tMap.headMap(str);
-            map = tMap.headMap(str);
-            map = tMap.headMap(str);
-        }
-    }
-
-    public void testTreeMapSubMap() {
-        String str1 = sKeys[400];
-        String str2 = sKeys[500];
-        SortedMap map;
-        TreeMap<String, Integer> tMap = sMap;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            map = tMap.subMap(str1, str2);
-            map = tMap.subMap(str1, str2);
-            map = tMap.subMap(str1, str2);
-            map = tMap.subMap(str1, str2);
-            map = tMap.subMap(str1, str2);
-            map = tMap.subMap(str1, str2);
-            map = tMap.subMap(str1, str2);
-            map = tMap.subMap(str1, str2);
-            map = tMap.subMap(str1, str2);
-            map = tMap.subMap(str1, str2);
-        }
-    }
-
-    public void testTreeMapTailMap() {
-        String str = sKeys[900];
-        TreeMap<String, Integer> tMap = sMap;
-        SortedMap map;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            map = tMap.tailMap(str);
-            map = tMap.tailMap(str);
-            map = tMap.tailMap(str);
-            map = tMap.tailMap(str);
-            map = tMap.tailMap(str);
-            map = tMap.tailMap(str);
-            map = tMap.tailMap(str);
-            map = tMap.tailMap(str);
-            map = tMap.tailMap(str);
-            map = tMap.tailMap(str);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public void testTreeMapRemove() {
-        TreeMap<String, Integer> tMap = new TreeMap(sMap);
-        String[] keys = sKeys;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            tMap.remove(keys[i]);
-            tMap.remove(keys[i]);
-            tMap.remove(keys[i]);
-            tMap.remove(keys[i]);
-            tMap.remove(keys[i]);
-            tMap.remove(keys[i]);
-            tMap.remove(keys[i]);
-            tMap.remove(keys[i]);
-            tMap.remove(keys[i]);
-            tMap.remove(keys[i]);
-        }
-    }
-}
diff --git a/tests/CoreTests/android/core/TreeSetTest.java b/tests/CoreTests/android/core/TreeSetTest.java
deleted file mode 100644
index a6a3309..0000000
--- a/tests/CoreTests/android/core/TreeSetTest.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import android.test.PerformanceTestBase;
-import android.test.PerformanceTestCase;
-
-import java.util.TreeSet;
-import java.util.SortedSet;
-import java.util.Iterator;
-import java.util.Comparator;
-
-/**
- * Implements basic performance test functionality for java.util.TreeSet
- */
-
-public class TreeSetTest extends PerformanceTestBase {
-    public static final int ITERATIONS = 1000;
-    public static TreeSet<Integer> sSet;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        sSet = new TreeSet<Integer>();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            sSet.add(i);
-        }
-    }
-
-    @Override
-    public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-        intermediates.setInternalIterations(ITERATIONS);
-        return 0;
-    }
-
-    /**
-     * 
-     * Tests performance for the java.util.TreeSet method Add(Object arg 0)
-     * 
-     */
-
-    @SuppressWarnings("unchecked")
-    public void testTreeSetAdd() {
-        TreeSet<Integer> set = new TreeSet();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-            set.add(i);
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the java.util.TreeSet method - first()
-     * 
-     */
-
-    public void testTreeSetFirst() {
-        int value;
-        TreeSet<Integer> set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            value = set.first();
-            value = set.first();
-            value = set.first();
-            value = set.first();
-            value = set.first();
-            value = set.first();
-            value = set.first();
-            value = set.first();
-            value = set.first();
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the java.util.TreeSet method - last()
-     * 
-     */
-
-    public void testTreeSetLast() {
-        int value;
-        TreeSet<Integer> set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            value = set.last();
-            value = set.last();
-            value = set.last();
-            value = set.last();
-            value = set.last();
-            value = set.last();
-            value = set.last();
-            value = set.last();
-            value = set.last();
-        }
-    }
-
-    /**
-     * 
-     * Tests performance of the java.util.TreeSet method- contains(Object arg0)
-     * 
-     */
-
-    public void testTreeSetContains() {
-        Integer index = new Integer(500);
-        boolean flag;
-        TreeSet<Integer> set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-            flag = set.contains(index);
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the java.util.TreeSet method - size()
-     * 
-     */
-
-    public void testTreeSetSize() {
-        int value;
-        TreeSet<Integer> set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            value = set.size();
-            value = set.size();
-            value = set.size();
-            value = set.size();
-            value = set.size();
-            value = set.size();
-            value = set.size();
-            value = set.size();
-            value = set.size();
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the java.util.TreeSet method - iterator()
-     * 
-     */
-
-    public void testTreeSetIterator() {
-        Iterator iterator;
-        TreeSet<Integer> set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-            iterator = set.iterator();
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the java.util.TreeSet method - comparator()
-     * 
-     */
-
-    public void testTreeSetComparator() {
-        Comparator comparator;
-        TreeSet<Integer> set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            comparator = set.comparator();
-            comparator = set.comparator();
-            comparator = set.comparator();
-            comparator = set.comparator();
-            comparator = set.comparator();
-            comparator = set.comparator();
-            comparator = set.comparator();
-            comparator = set.comparator();
-            comparator = set.comparator();
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the java.util.TreeSet method - clone()
-     * 
-     */
-
-    public void testTreeSetClone() {
-        Object obj;
-        TreeSet<Integer> set = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            obj = set.clone();
-            obj = set.clone();
-            obj = set.clone();
-            obj = set.clone();
-            obj = set.clone();
-            obj = set.clone();
-            obj = set.clone();
-            obj = set.clone();
-            obj = set.clone();
-            obj = set.clone();
-        }
-    }
-
-    /**
-     * 
-     * Tests performance of the java.util.TreeSet method - remove(Object arg0)
-     * 
-     */
-
-    @SuppressWarnings("unchecked")
-    public void testTreeSetRemove() {
-        TreeSet<Integer> set = new TreeSet(sSet);
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-            set.remove(i);
-        }
-    }
-
-    /**
-     * 
-     * Tests performance of the java.util.TreeSet method- headSet(Integer arg0)
-     * 
-     */
-
-    public void testTreeSetHeadSet() {
-        Integer value = new Integer(100);
-        SortedSet set;
-        TreeSet<Integer> tSet = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            set = tSet.headSet(value);
-            set = tSet.headSet(value);
-            set = tSet.headSet(value);
-            set = tSet.headSet(value);
-            set = tSet.headSet(value);
-            set = tSet.headSet(value);
-            set = tSet.headSet(value);
-            set = tSet.headSet(value);
-            set = tSet.headSet(value);
-            set = tSet.headSet(value);
-        }
-    }
-
-    /**
-     * 
-     * Tests performance of subSet(Integer arg0, Integer arg1) - TreeSet
-     * 
-     */
-
-    public void testTreeSetSubSet() {
-        Integer value = new Integer(400);
-        Integer nInt = new Integer(500);
-        SortedSet set;
-        TreeSet<Integer> tSet = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            set = tSet.subSet(value, nInt);
-            set = tSet.subSet(value, nInt);
-            set = tSet.subSet(value, nInt);
-            set = tSet.subSet(value, nInt);
-            set = tSet.subSet(value, nInt);
-            set = tSet.subSet(value, nInt);
-            set = tSet.subSet(value, nInt);
-            set = tSet.subSet(value, nInt);
-            set = tSet.subSet(value, nInt);
-            set = tSet.subSet(value, nInt);
-
-        }
-
-    }
-
-    /**
-     * 
-     * Tests performance of tailSet(Integer arg0) - TreeSet
-     * 
-     */
-
-    public void testTreeSetTailSet() {
-        Integer value = new Integer(900);
-        SortedSet set;
-        TreeSet<Integer> tSet = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            set = tSet.tailSet(value);
-            set = tSet.tailSet(value);
-            set = tSet.tailSet(value);
-            set = tSet.tailSet(value);
-            set = tSet.tailSet(value);
-            set = tSet.tailSet(value);
-            set = tSet.tailSet(value);
-            set = tSet.tailSet(value);
-            set = tSet.tailSet(value);
-            set = tSet.tailSet(value);
-        }
-    }
-
-    /**
-     * 
-     * Tests performance for the java.util.TreeSet method - isEmpty()
-     * 
-     */
-
-    public void testTreeSetIsEmpty() {
-        boolean flag;
-        TreeSet<Integer> tSet = sSet;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = tSet.isEmpty();
-            flag = tSet.isEmpty();
-            flag = tSet.isEmpty();
-            flag = tSet.isEmpty();
-            flag = tSet.isEmpty();
-            flag = tSet.isEmpty();
-            flag = tSet.isEmpty();
-            flag = tSet.isEmpty();
-            flag = tSet.isEmpty();
-            flag = tSet.isEmpty();
-        }
-    }
-}
diff --git a/tests/CoreTests/android/core/VectorTest.java b/tests/CoreTests/android/core/VectorTest.java
deleted file mode 100644
index b4c84fd..0000000
--- a/tests/CoreTests/android/core/VectorTest.java
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.core;
-
-import android.test.PerformanceTestBase;
-import android.test.PerformanceTestCase;
-
-import java.util.Vector;
-import java.util.Enumeration;
-
-/**
- * Basic Performance Tests for java.util.Vector
- */
-
-@SuppressWarnings("unchecked")
-public class VectorTest extends PerformanceTestBase {
-    public static final int ITERATIONS = 1000;
-    private Vector<Integer> mVector;
-    private Vector<String> mStrVector;
-    private String mTestString = "Hello Android";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mVector = new Vector();
-        mStrVector = new Vector();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            assertTrue(mVector.add(i));
-            assertTrue(mStrVector.add(Integer.toString(i)));
-        }
-    }
-
-    @Override
-    public int startPerformance(PerformanceTestCase.Intermediates intermediates) {
-        intermediates.setInternalIterations(ITERATIONS);
-        return 0;
-    }
-
-    public void testVectorAdd() {
-        Vector<Integer> vector = new Vector();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            vector.add(i);
-            vector.add(i);
-            vector.add(i);
-            vector.add(i);
-            vector.add(i);
-            vector.add(i);
-            vector.add(i);
-            vector.add(i);
-            vector.add(i);
-            vector.add(i);
-        }
-    }
-
-    public void testVectorAdd1() {
-        Vector<Integer> vector = new Vector();
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            vector.add(0, i);
-            vector.add(0, i);
-            vector.add(0, i);
-            vector.add(0, i);
-            vector.add(0, i);
-            vector.add(0, i);
-            vector.add(0, i);
-            vector.add(0, i);
-            vector.add(0, i);
-            vector.add(0, i);
-        }
-    }
-
-    public void testVectorToArray() {
-        Object array;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            array = vector.toArray();
-            array = vector.toArray();
-            array = vector.toArray();
-            array = vector.toArray();
-            array = vector.toArray();
-            array = vector.toArray();
-            array = vector.toArray();
-            array = vector.toArray();
-            array = vector.toArray();
-            array = vector.toArray();
-        }
-    }
-
-    /**
-     * 
-     */
-    public void testVectorSize() {
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            int mLen;
-            mLen = vector.size();
-            mLen = vector.size();
-            mLen = vector.size();
-            mLen = vector.size();
-            mLen = vector.size();
-            mLen = vector.size();
-            mLen = vector.size();
-            mLen = vector.size();
-            mLen = vector.size();
-            mLen = vector.size();
-        }
-    }
-
-    public void testVectorGet() {
-        int element;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            element = vector.get(i);
-            element = vector.get(i);
-            element = vector.get(i);
-            element = vector.get(i);
-            element = vector.get(i);
-            element = vector.get(i);
-            element = vector.get(i);
-            element = vector.get(i);
-            element = vector.get(i);
-            element = vector.get(i);
-        }
-
-    }
-
-    public void testVectorContains() {
-        boolean flag;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            flag = vector.contains(i);
-            flag = vector.contains(i);
-            flag = vector.contains(i);
-            flag = vector.contains(i);
-            flag = vector.contains(i);
-            flag = vector.contains(i);
-            flag = vector.contains(i);
-            flag = vector.contains(i);
-            flag = vector.contains(i);
-            flag = vector.contains(i);
-        }
-    }
-
-    public void testVectorToArray1() {
-        Integer[] rArray = new Integer[100];
-        Integer[] array;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            array = vector.toArray(rArray);
-            array = vector.toArray(rArray);
-            array = vector.toArray(rArray);
-            array = vector.toArray(rArray);
-            array = vector.toArray(rArray);
-            array = vector.toArray(rArray);
-            array = vector.toArray(rArray);
-            array = vector.toArray(rArray);
-            array = vector.toArray(rArray);
-            array = vector.toArray(rArray);
-        }
-    }
-
-    public void testVectorSet() {
-        Vector<Integer> vector = mVector;
-        int pos = 5, value = 0;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            vector.set(pos, value);
-            vector.set(pos, value);
-            vector.set(pos, value);
-            vector.set(pos, value);
-            vector.set(pos, value);
-            vector.set(pos, value);
-            vector.set(pos, value);
-            vector.set(pos, value);
-            vector.set(pos, value);
-            vector.set(pos, value);
-        }
-    }
-
-    public void testVectorIndexOf() {
-        int index, value = 0;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            index = vector.indexOf(value);
-            index = vector.indexOf(value);
-            index = vector.indexOf(value);
-            index = vector.indexOf(value);
-            index = vector.indexOf(value);
-            index = vector.indexOf(value);
-            index = vector.indexOf(value);
-            index = vector.indexOf(value);
-            index = vector.indexOf(value);
-            index = vector.indexOf(value);
-        }
-    }
-
-    public void testVectorLastIndexOf() {
-        int index, value = 0;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i >= 0; i--) {
-            index = vector.lastIndexOf(value);
-            index = vector.lastIndexOf(value);
-            index = vector.lastIndexOf(value);
-            index = vector.lastIndexOf(value);
-            index = vector.lastIndexOf(value);
-            index = vector.lastIndexOf(value);
-            index = vector.lastIndexOf(value);
-            index = vector.lastIndexOf(value);
-            index = vector.lastIndexOf(value);
-            index = vector.lastIndexOf(value);
-        }
-    }
-
-    public void testVectorRemove() {
-        int index, value = 0;
-        Vector<Integer> vector = new Vector(mVector);
-        for (int i = 10; i > 0; i--) {
-            index = vector.remove(value);
-            index = vector.remove(value);
-            index = vector.remove(value);
-            index = vector.remove(value);
-            index = vector.remove(value);
-            index = vector.remove(value);
-            index = vector.remove(value);
-            index = vector.remove(value);
-            index = vector.remove(value);
-            index = vector.remove(value);
-        }
-    }
-
-    public void testVectorRemoveElement() {
-        Vector<Integer> vector = new Vector(mVector);
-        for (int i = 10; i > 0; i--) {
-            vector.removeElement(i);
-            vector.removeElement(i);
-            vector.removeElement(i);
-            vector.removeElement(i);
-            vector.removeElement(i);
-            vector.removeElement(i);
-            vector.removeElement(i);
-            vector.removeElement(i);
-            vector.removeElement(i);
-            vector.removeElement(i);
-        }
-    }
-
-    public void VectorRemoveElementAt() {
-        Vector<Integer> vector = new Vector(mVector);
-        for (int i = 10; i > 0; i--) {
-            vector.removeElementAt(i);
-            vector.removeElementAt(i);
-            vector.removeElementAt(i);
-            vector.removeElementAt(i);
-            vector.removeElementAt(i);
-            vector.removeElementAt(i);
-            vector.removeElementAt(i);
-            vector.removeElementAt(i);
-            vector.removeElementAt(i);
-            vector.removeElementAt(i);
-        }
-    }
-
-    public void VectorAddAll() {
-        Vector<Integer> vector = new Vector(), vector1 = mVector;
-
-        boolean flag;
-        for (int i = 10; i > 0; i--) {
-            flag = vector.addAll(vector1);
-            flag = vector.addAll(vector1);
-            flag = vector.addAll(vector1);
-            flag = vector.addAll(vector1);
-            flag = vector.addAll(vector1);
-            flag = vector.addAll(vector1);
-            flag = vector.addAll(vector1);
-            flag = vector.addAll(vector1);
-            flag = vector.addAll(vector1);
-            flag = vector.addAll(vector1);
-        }
-    }
-
-    public void VectorRemove1() {
-        Vector<String> vector = mStrVector;
-        for (int j = 1000; j > 0; j--) {
-            vector.add("a");
-            vector.add("b");
-        }
-        String s = new String("a");
-        boolean flag;
-        for (int i = 10; i > 0; i--) {
-            flag = vector.remove(s);
-            flag = vector.remove(s);
-            flag = vector.remove(s);
-            flag = vector.remove(s);
-            flag = vector.remove(s);
-            flag = vector.remove(s);
-            flag = vector.remove(s);
-            flag = vector.remove(s);
-            flag = vector.remove(s);
-            flag = vector.remove(s);
-        }
-    }
-
-    public void testVectorAddAll1() {
-        Vector<Integer> mEmptyVector = new Vector();
-        boolean flag;
-        int pos = 0;
-        Vector<Integer> vector1 = mVector;
-        Vector<Integer> vector = mEmptyVector;
-        for (int i = 10; i > 0; i--) {
-            flag = vector.addAll(pos, vector1);
-            flag = vector.addAll(pos, vector1);
-            flag = vector.addAll(pos, vector1);
-            flag = vector.addAll(pos, vector1);
-            flag = vector.addAll(pos, vector1);
-            flag = vector.addAll(pos, vector1);
-            flag = vector.addAll(pos, vector1);
-            flag = vector.addAll(pos, vector1);
-            flag = vector.addAll(pos, vector1);
-            flag = vector.addAll(pos, vector1);
-        }
-    }
-
-    public void testVectorClone() {
-        Object obj;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            obj = vector.clone();
-            obj = vector.clone();
-            obj = vector.clone();
-            obj = vector.clone();
-            obj = vector.clone();
-            obj = vector.clone();
-            obj = vector.clone();
-            obj = vector.clone();
-            obj = vector.clone();
-            obj = vector.clone();
-        }
-    }
-
-    public void testVectorCapacity() {
-        int capacity;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            capacity = vector.capacity();
-            capacity = vector.capacity();
-            capacity = vector.capacity();
-            capacity = vector.capacity();
-            capacity = vector.capacity();
-            capacity = vector.capacity();
-            capacity = vector.capacity();
-            capacity = vector.capacity();
-            capacity = vector.capacity();
-            capacity = vector.capacity();
-        }
-    }
-
-    public void testVectorHashcode() {
-        int element;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            element = vector.hashCode();
-            element = vector.hashCode();
-            element = vector.hashCode();
-            element = vector.hashCode();
-            element = vector.hashCode();
-            element = vector.hashCode();
-            element = vector.hashCode();
-            element = vector.hashCode();
-            element = vector.hashCode();
-            element = vector.hashCode();
-        }
-    }
-
-    public void testVectorElements() {
-        Enumeration<Integer> elements;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            elements = vector.elements();
-            elements = vector.elements();
-            elements = vector.elements();
-            elements = vector.elements();
-            elements = vector.elements();
-            elements = vector.elements();
-            elements = vector.elements();
-            elements = vector.elements();
-            elements = vector.elements();
-            elements = vector.elements();
-        }
-    }
-
-    public void testVectorToString() {
-        String str;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            str = vector.toString();
-            str = vector.toString();
-            str = vector.toString();
-            str = vector.toString();
-            str = vector.toString();
-            str = vector.toString();
-            str = vector.toString();
-            str = vector.toString();
-            str = vector.toString();
-            str = vector.toString();
-        }
-    }
-
-    public void testVectorElementAt() {
-        int element;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            element = vector.elementAt(50);
-            element = vector.elementAt(50);
-            element = vector.elementAt(50);
-            element = vector.elementAt(50);
-            element = vector.elementAt(50);
-            element = vector.elementAt(50);
-            element = vector.elementAt(50);
-            element = vector.elementAt(50);
-            element = vector.elementAt(50);
-            element = vector.elementAt(50);
-        }
-    }
-
-    public void testVectorAddElement() {
-        int element;
-        Vector<String> vector = mStrVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            vector.addElement(mTestString);
-            vector.addElement(mTestString);
-            vector.addElement(mTestString);
-            vector.addElement(mTestString);
-            vector.addElement(mTestString);
-            vector.addElement(mTestString);
-            vector.addElement(mTestString);
-            vector.addElement(mTestString);
-            vector.addElement(mTestString);
-            vector.addElement(mTestString);
-        }
-    }
-
-    public void testVectorFirstElement() {
-        int element;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            element = vector.firstElement();
-            element = vector.firstElement();
-            element = vector.firstElement();
-            element = vector.firstElement();
-            element = vector.firstElement();
-            element = vector.firstElement();
-            element = vector.firstElement();
-            element = vector.firstElement();
-            element = vector.firstElement();
-            element = vector.firstElement();
-        }
-    }
-
-    public void testVectorLastElement() {
-        int element;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            element = vector.lastElement();
-            element = vector.lastElement();
-            element = vector.lastElement();
-            element = vector.lastElement();
-            element = vector.lastElement();
-            element = vector.lastElement();
-            element = vector.lastElement();
-            element = vector.lastElement();
-            element = vector.lastElement();
-            element = vector.lastElement();
-        }
-    }
-
-    public void testVectorSetElementAt() {
-        Vector<Integer> vector = mVector;
-        int value1 = 500, value2 = 50;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            vector.setElementAt(value1, value2);
-            vector.setElementAt(value1, value2);
-            vector.setElementAt(value1, value2);
-            vector.setElementAt(value1, value2);
-            vector.setElementAt(value1, value2);
-            vector.setElementAt(value1, value2);
-            vector.setElementAt(value1, value2);
-            vector.setElementAt(value1, value2);
-            vector.setElementAt(value1, value2);
-            vector.setElementAt(value1, value2);
-        }
-    }
-
-    public void testVectorIsEmpty() {
-        boolean flag;
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            flag = vector.isEmpty();
-            flag = vector.isEmpty();
-            flag = vector.isEmpty();
-            flag = vector.isEmpty();
-            flag = vector.isEmpty();
-            flag = vector.isEmpty();
-            flag = vector.isEmpty();
-            flag = vector.isEmpty();
-            flag = vector.isEmpty();
-            flag = vector.isEmpty();
-        }
-    }
-
-    public void testVectorCopyInto() {
-        Integer[] rArray = new Integer[ITERATIONS];
-        Vector<Integer> vector = mVector;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            vector.copyInto(rArray);
-            vector.copyInto(rArray);
-            vector.copyInto(rArray);
-            vector.copyInto(rArray);
-            vector.copyInto(rArray);
-            vector.copyInto(rArray);
-            vector.copyInto(rArray);
-            vector.copyInto(rArray);
-            vector.copyInto(rArray);
-            vector.copyInto(rArray);
-        }
-    }
-
-    public void testVectorInsertElementAt() {
-        Vector<String> vector = mStrVector;
-        String string = mTestString;
-        for (int i = ITERATIONS - 1; i > 0; i--) {
-            vector.insertElementAt(string, i);
-            vector.insertElementAt(string, i);
-            vector.insertElementAt(string, i);
-            vector.insertElementAt(string, i);
-            vector.insertElementAt(string, i);
-            vector.insertElementAt(string, i);
-            vector.insertElementAt(string, i);
-            vector.insertElementAt(string, i);
-            vector.insertElementAt(string, i);
-            vector.insertElementAt(string, i);
-        }
-    }
-}
diff --git a/tests/HwAccelerationTest/res/layout/advanced_blend.xml b/tests/HwAccelerationTest/res/layout/_advanced_blend.xml
similarity index 100%
rename from tests/HwAccelerationTest/res/layout/advanced_blend.xml
rename to tests/HwAccelerationTest/res/layout/_advanced_blend.xml
diff --git a/tests/HwAccelerationTest/res/layout/advanced_gradient.xml b/tests/HwAccelerationTest/res/layout/_advanced_gradient.xml
similarity index 100%
rename from tests/HwAccelerationTest/res/layout/advanced_gradient.xml
rename to tests/HwAccelerationTest/res/layout/_advanced_gradient.xml
diff --git a/tests/HwAccelerationTest/res/layout/_lines.xml b/tests/HwAccelerationTest/res/layout/_lines.xml
new file mode 100644
index 0000000..00f2556
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/_lines.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.test.hwui.LinesActivity.LinesView
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:layout_width="fill_parent"
+  android:layout_height="fill_parent">
+</com.android.test.hwui.LinesActivity.LinesView>
diff --git a/tests/HwAccelerationTest/res/layout/_paths.xml b/tests/HwAccelerationTest/res/layout/_paths.xml
new file mode 100644
index 0000000..b053482
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/_paths.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.test.hwui.PathsActivity.PathsView
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:layout_width="fill_parent"
+  android:layout_height="fill_parent">
+</com.android.test.hwui.PathsActivity.PathsView>
diff --git a/tests/HwAccelerationTest/res/layout/_shaders.xml b/tests/HwAccelerationTest/res/layout/_shaders.xml
new file mode 100644
index 0000000..dcb42fb
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/_shaders.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.test.hwui.ShadersActivity.ShadersView
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:layout_width="fill_parent"
+  android:layout_height="fill_parent">
+</com.android.test.hwui.ShadersActivity.ShadersView>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
index 6afbb01..91e3b84 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
@@ -35,7 +35,7 @@
         setContentView(view);
     }
 
-    static class LinesView extends View {
+    public static class LinesView extends View {
         private static final boolean LINE_AA = false;
 
         private final Bitmap mBitmap1;
@@ -47,7 +47,7 @@
         private final Paint mAlphaPaint;
         private final Paint mHairLinePaint;
 
-        LinesView(Context c) {
+        public LinesView(Context c) {
             super(c);
 
             mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
@@ -71,7 +71,7 @@
             mAlphaPaint.setAntiAlias(LINE_AA);
             mAlphaPaint.setColor(0x7fff0050);
             mAlphaPaint.setStrokeWidth(10.0f);
-            
+
             mHairLinePaint = new Paint();
             mHairLinePaint.setAntiAlias(LINE_AA);
             mHairLinePaint.setColor(0xff0000ff);
@@ -99,11 +99,11 @@
             canvas.drawLine(0.0f, 0.0f, 40.0f, 400.0f, mSmallPaint);
             canvas.drawLine(5.0f, 0.0f, 95.0f, 400.0f, mMediumPaint);
             canvas.drawLine(22.0f, 0.0f, 162.0f, 400.0f, mLargePaint);
-            
+
             mLargePaint.setShader(mShader);
             canvas.drawLine(42.0f, 0.0f, 222.0f, 400.0f, mLargePaint);
             mLargePaint.setShader(null);
-            
+
             canvas.drawLines(mPoints, mAlphaPaint);
 
             mSmallPaint.setAntiAlias(false);
@@ -111,14 +111,14 @@
             mSmallPaint.setAntiAlias(LINE_AA);
             canvas.drawLine(0.0f, 0.0f, 0.0f, 400.0f, mSmallPaint);
             canvas.drawLine(0.0f, 400.0f, 400.0f, 400.0f, mSmallPaint);
-            
+
             canvas.translate(120.0f, 0.0f);
-            mAlphaPaint.setShader(mShader);            
+            mAlphaPaint.setShader(mShader);
             canvas.drawLines(mPoints, mAlphaPaint);
             mAlphaPaint.setShader(null);
 
             canvas.restore();
-            
+
             canvas.scale(10.0f, 10.0f);
             canvas.drawLine(50.0f, 40.0f, 10.0f, 40.0f, mSmallPaint);
             canvas.drawLine(10.0f, 50.0f, 50.0f, 50.0f, mSmallPaint);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java
index 8d9bf37..aa1eb59 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsActivity.java
@@ -37,7 +37,7 @@
         setContentView(view);
     }
 
-    static class PathsView extends View {
+    public static class PathsView extends View {
         private final Bitmap mBitmap1;
         private final Paint mSmallPaint;
         private final Paint mMediumPaint;
@@ -50,7 +50,7 @@
         private final float mOffset;
         private final Paint mLinePaint;
 
-        PathsView(Context c) {
+        public PathsView(Context c) {
             super(c);
 
             mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
@@ -60,7 +60,7 @@
             mSmallPaint.setColor(0xffff0000);
             mSmallPaint.setStrokeWidth(1.0f);
             mSmallPaint.setStyle(Paint.Style.STROKE);
-            
+
             mLinePaint = new Paint();
             mLinePaint.setAntiAlias(true);
             mLinePaint.setColor(0xffff00ff);
@@ -112,7 +112,7 @@
             canvas.save();
             canvas.translate(200.0f, 60.0f);
             canvas.drawPath(mPath, mSmallPaint);
-            
+
             canvas.translate(350.0f, 0.0f);
             canvas.drawPath(mPath, mMediumPaint);
 
@@ -121,12 +121,12 @@
             canvas.drawPath(mPath, mLargePaint);
             mLargePaint.setShader(null);
             canvas.restore();
-            
+
             canvas.save();
             canvas.translate(200.0f, 360.0f);
             canvas.drawPath(mPath, mSmallPaint);
             canvas.drawRect(mPathBounds, mBoundsPaint);
-            
+
             canvas.translate(350.0f, 0.0f);
             canvas.drawBitmap(mBitmap, mPathBounds.left - mOffset * 1.5f,
                     mPathBounds.top - mOffset * 1.5f, null);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java
index 02eaa7c..1d18f61 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java
@@ -39,7 +39,7 @@
         setContentView(new ShadersView(this));
     }
 
-    static class ShadersView extends View {
+    public static class ShadersView extends View {
         private BitmapShader mRepeatShader;
         private BitmapShader mTranslatedShader;
         private BitmapShader mScaledShader;
@@ -52,8 +52,11 @@
         private LinearGradient mDiagGradient;
         private LinearGradient mVertGradient;
         private Bitmap mTexture;
+        private Matrix mMtx1;
+        private Matrix mMtx2;
+        private Matrix mMtx3;
 
-        ShadersView(Context c) {
+        public ShadersView(Context c) {
             super(c);
 
             mTexture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
@@ -67,28 +70,28 @@
 
             mTranslatedShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT,
                     Shader.TileMode.REPEAT);
-            Matrix m1 = new Matrix();
-            m1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f);
-            m1.postRotate(45, 0, 0);
-            mTranslatedShader.setLocalMatrix(m1);
-            
+            mMtx1 = new Matrix();
+            mMtx1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f);
+            mMtx1.postRotate(45, 0, 0);
+            mTranslatedShader.setLocalMatrix(mMtx1);
+
             mScaledShader = new BitmapShader(mTexture, Shader.TileMode.MIRROR,
                     Shader.TileMode.MIRROR);
-            Matrix m2 = new Matrix();
-            m2.setScale(0.5f, 0.5f);
-            mScaledShader.setLocalMatrix(m2);
+            mMtx2 = new Matrix();
+            mMtx2.setScale(0.5f, 0.5f);
+            mScaledShader.setLocalMatrix(mMtx2);
 
             mHorGradient = new LinearGradient(0.0f, 0.0f, 1.0f, 0.0f,
                     Color.RED, Color.GREEN, Shader.TileMode.CLAMP);
-            Matrix m3 = new Matrix();
-            m3.setScale(mDrawHeight, 1.0f);
-            m3.postRotate(-90.0f);
-            m3.postTranslate(0.0f, mDrawHeight);
-            mHorGradient.setLocalMatrix(m3);
-            
+            mMtx3 = new Matrix();
+            mMtx3.setScale(mDrawHeight, 1.0f);
+            mMtx3.postRotate(-90.0f);
+            mMtx3.postTranslate(0.0f, mDrawHeight);
+            mHorGradient.setLocalMatrix(mMtx3);
+
             mDiagGradient = new LinearGradient(0.0f, 0.0f, mDrawWidth / 1.5f, mDrawHeight,
                     Color.BLUE, Color.MAGENTA, Shader.TileMode.CLAMP);
-            
+
             mVertGradient = new LinearGradient(0.0f, 0.0f, 0.0f, mDrawHeight / 2.0f,
                     Color.YELLOW, Color.MAGENTA, Shader.TileMode.MIRROR);
 
@@ -107,7 +110,7 @@
 
             mPaint.setShader(mRepeatShader);
             canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
-            
+
             canvas.translate(0.0f, 40.0f + mDrawHeight);
             mPaint.setShader(mTranslatedShader);
             canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
@@ -124,7 +127,7 @@
 
             mPaint.setShader(mHorGradient);
             canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
-            
+
             canvas.translate(0.0f, 40.0f + mDrawHeight);
             mPaint.setShader(mDiagGradient);
             canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
@@ -132,7 +135,7 @@
             canvas.translate(0.0f, 40.0f + mDrawHeight);
             mPaint.setShader(mVertGradient);
             canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
-            
+
             canvas.restore();
         }
     }
diff --git a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
index b46d95c..60ad645 100644
--- a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.app;
 
-import com.android.layoutlib.api.IProjectCallback;
+import com.android.ide.common.rendering.api.IProjectCallback;
 
 import android.content.Context;
 import android.os.Bundle;
diff --git a/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java
new file mode 100644
index 0000000..190eb37
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java
@@ -0,0 +1,68 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import java.awt.Composite;
+
+/**
+ * Delegate implementing the native methods of android.graphics.AvoidXfermode
+ *
+ * Through the layoutlib_create tool, the original native methods of AvoidXfermode have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original AvoidXfermode class.
+ *
+ * Because this extends {@link Xfermode_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
+ * {@link Xfermode_Delegate}.
+ *
+ */
+public class AvoidXfermode_Delegate extends Xfermode_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Composite getComposite(int alpha) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Avoid Xfermodes are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    /*package*/ static int nativeCreate(int opColor, int tolerance, int nativeMode) {
+        AvoidXfermode_Delegate newDelegate = new AvoidXfermode_Delegate();
+        return sManager.addDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
index 626f878..c57aef6 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.api.ResourceDensity;
+import com.android.ide.common.rendering.api.ResourceDensity;
 import com.android.layoutlib.bridge.Bridge;
 
 import android.content.res.AssetManager;
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
new file mode 100644
index 0000000..b660ae6
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
@@ -0,0 +1,242 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import android.graphics.Shader.TileMode;
+
+/**
+ * Delegate implementing the native methods of android.graphics.BitmapShader
+ *
+ * Through the layoutlib_create tool, the original native methods of BitmapShader have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original BitmapShader class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class BitmapShader_Delegate extends Shader_Delegate {
+
+    // ---- delegate data ----
+    private java.awt.Paint mJavaPaint;
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public java.awt.Paint getJavaPaint() {
+        return mJavaPaint;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return true;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        // no message since isSupported returns true;
+        return null;
+    }
+
+    // ---- native methods ----
+
+    /*package*/ static int nativeCreate(int native_bitmap, int shaderTileModeX,
+            int shaderTileModeY) {
+        Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(native_bitmap);
+        assert bitmap != null;
+        if (bitmap == null) {
+            return 0;
+        }
+
+        BitmapShader_Delegate newDelegate = new BitmapShader_Delegate(
+                bitmap.getImage(),
+                Shader_Delegate.getTileMode(shaderTileModeX),
+                Shader_Delegate.getTileMode(shaderTileModeY));
+        return sManager.addDelegate(newDelegate);
+    }
+
+    /*package*/ static int nativePostCreate(int native_shader, int native_bitmap,
+            int shaderTileModeX, int shaderTileModeY) {
+        // pass, not needed.
+        return 0;
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    private BitmapShader_Delegate(java.awt.image.BufferedImage image,
+            TileMode tileModeX, TileMode tileModeY) {
+        mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
+    }
+
+    private class BitmapShaderPaint implements java.awt.Paint {
+        private final java.awt.image.BufferedImage mImage;
+        private final TileMode mTileModeX;
+        private final TileMode mTileModeY;
+
+        BitmapShaderPaint(java.awt.image.BufferedImage image,
+                TileMode tileModeX, TileMode tileModeY) {
+            mImage = image;
+            mTileModeX = tileModeX;
+            mTileModeY = tileModeY;
+        }
+
+        public java.awt.PaintContext createContext(
+                java.awt.image.ColorModel      colorModel,
+                java.awt.Rectangle             deviceBounds,
+                java.awt.geom.Rectangle2D      userBounds,
+                java.awt.geom.AffineTransform  xform,
+                java.awt.RenderingHints        hints) {
+
+            java.awt.geom.AffineTransform canvasMatrix;
+            try {
+                canvasMatrix = xform.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().error(null, "Unable to inverse matrix in BitmapShader", e);
+                canvasMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
+            try {
+                localMatrix = localMatrix.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().error(null, "Unable to inverse matrix in BitmapShader", e);
+                localMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
+        }
+
+        private class BitmapShaderContext implements java.awt.PaintContext {
+
+            private final java.awt.geom.AffineTransform mCanvasMatrix;
+            private final java.awt.geom.AffineTransform mLocalMatrix;
+            private final java.awt.image.ColorModel mColorModel;
+
+            public BitmapShaderContext(
+                    java.awt.geom.AffineTransform canvasMatrix,
+                    java.awt.geom.AffineTransform localMatrix,
+                    java.awt.image.ColorModel colorModel) {
+                mCanvasMatrix = canvasMatrix;
+                mLocalMatrix = localMatrix;
+                mColorModel = colorModel;
+            }
+
+            public void dispose() {
+            }
+
+            public java.awt.image.ColorModel getColorModel() {
+                return mColorModel;
+            }
+
+            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
+                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
+                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
+
+                int[] data = new int[w*h];
+
+                int index = 0;
+                float[] pt1 = new float[2];
+                float[] pt2 = new float[2];
+                for (int iy = 0 ; iy < h ; iy++) {
+                    for (int ix = 0 ; ix < w ; ix++) {
+                        // handle the canvas transform
+                        pt1[0] = x + ix;
+                        pt1[1] = y + iy;
+                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        // handle the local matrix.
+                        pt1[0] = pt2[0];
+                        pt1[1] = pt2[1];
+                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        data[index++] = getColor(pt2[0], pt2[1]);
+                    }
+                }
+
+                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
+
+                return image.getRaster();
+            }
+        }
+
+        /**
+         * Returns a color for an arbitrary point.
+         */
+        private int getColor(float fx, float fy) {
+            int x = getCoordinate(Math.round(fx), mImage.getWidth(), mTileModeX);
+            int y = getCoordinate(Math.round(fy), mImage.getHeight(), mTileModeY);
+
+            return mImage.getRGB(x, y);
+        }
+
+        private int getCoordinate(int i, int size, TileMode mode) {
+            if (i < 0) {
+                switch (mode) {
+                    case CLAMP:
+                        i = 0;
+                        break;
+                    case REPEAT:
+                        i = size - 1 - (-i % size);
+                        break;
+                    case MIRROR:
+                        // this is the same as the positive side, just make the value positive
+                        // first.
+                        i = -i;
+                        int count = i / size;
+                        i = i % size;
+
+                        if ((count % 2) == 1) {
+                            i = size - 1 - i;
+                        }
+                        break;
+                }
+            } else if (i >= size) {
+                switch (mode) {
+                    case CLAMP:
+                        i = size - 1;
+                        break;
+                    case REPEAT:
+                        i = i % size;
+                        break;
+                    case MIRROR:
+                        int count = i / size;
+                        i = i % size;
+
+                        if ((count % 2) == 1) {
+                            i = size - 1 - i;
+                        }
+                        break;
+                }
+            }
+
+            return i;
+        }
+
+
+        public int getTransparency() {
+            return java.awt.Paint.TRANSLUCENT;
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index fe201c1..b5f5005 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.api.ResourceDensity;
+import com.android.ide.common.rendering.api.ResourceDensity;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 
 import android.graphics.Bitmap.Config;
@@ -45,7 +45,7 @@
  * @see DelegateManager
  *
  */
-public class Bitmap_Delegate {
+public final class Bitmap_Delegate {
 
     // ---- delegate manager ----
     private static final DelegateManager<Bitmap_Delegate> sManager =
@@ -54,9 +54,11 @@
     // ---- delegate helper data ----
 
     // ---- delegate data ----
+    private final Config mConfig;
     private BufferedImage mImage;
     private boolean mHasAlpha = true;
 
+
     // ---- Public Helper methods ----
 
     /**
@@ -86,7 +88,7 @@
     public static Bitmap createBitmap(File input, boolean isMutable, ResourceDensity density)
             throws IOException {
         // create a delegate with the content of the file.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input));
+        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
 
         return createBitmap(delegate, isMutable, density.getDpi());
     }
@@ -104,7 +106,7 @@
     public static Bitmap createBitmap(InputStream input, boolean isMutable, ResourceDensity density)
             throws IOException {
         // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input));
+        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
 
         return createBitmap(delegate, isMutable, density.getDpi());
     }
@@ -122,7 +124,7 @@
     public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
             ResourceDensity density) throws IOException {
         // create a delegate with the given image.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image);
+        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
 
         return createBitmap(delegate, isMutable, density.getDpi());
     }
@@ -163,6 +165,15 @@
         return mImage;
     }
 
+    /**
+     * Returns the Android bitmap config. Note that this not the config of the underlying
+     * Java2D bitmap.
+     */
+    public Config getConfig() {
+        return mConfig;
+    }
+
+
     // ---- native methods ----
 
     /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
@@ -175,7 +186,7 @@
         // FIXME fill the bitmap!
 
         // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image);
+        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.sConfigs[nativeConfig]);
 
         return createBitmap(delegate, mutable, Bitmap.getDefaultDensity());
     }
@@ -211,10 +222,7 @@
 
         Graphics2D g = image.createGraphics();
         try {
-            if (delegate.mHasAlpha == false) {
-                color |= color & 0xFF000000;
-            }
-            g.setColor(new java.awt.Color(color));
+            g.setColor(new java.awt.Color(color, delegate.mHasAlpha));
 
             g.fillRect(0, 0, image.getWidth(), image.getHeight());
         } finally {
@@ -256,7 +264,14 @@
     }
 
     /*package*/ static int nativeConfig(int nativeBitmap) {
-        return Config.ARGB_8888.nativeInt;
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            assert false;
+            return 0;
+        }
+
+        return delegate.mConfig.nativeInt;
     }
 
     /*package*/ static boolean nativeHasAlpha(int nativeBitmap) {
@@ -355,8 +370,9 @@
 
     // ---- Private delegate/helper methods ----
 
-    private Bitmap_Delegate(BufferedImage image) {
+    private Bitmap_Delegate(BufferedImage image, Config config) {
         mImage = image;
+        mConfig = config;
     }
 
     private static Bitmap createBitmap(Bitmap_Delegate delegate, boolean isMutable, int density) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index c75e1b6..2720b61 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -23,12 +23,14 @@
 import android.graphics.Paint_Delegate.FontInfo;
 import android.text.TextUtils;
 
-import java.awt.AlphaComposite;
 import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Composite;
 import java.awt.Graphics2D;
 import java.awt.Rectangle;
 import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
 import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
 import java.util.List;
@@ -47,7 +49,7 @@
  * @see DelegateManager
  *
  */
-public class Canvas_Delegate {
+public final class Canvas_Delegate {
 
     // ---- delegate manager ----
     private static final DelegateManager<Canvas_Delegate> sManager =
@@ -55,6 +57,10 @@
 
     // ---- delegate helper data ----
 
+    private interface Drawable {
+        void draw(Graphics2D graphics, Paint_Delegate paint);
+    }
+
     // ---- delegate data ----
     private BufferedImage mBufferedImage;
     private GcSnapshot mSnapshot = new GcSnapshot();
@@ -403,9 +409,9 @@
 
         if (matrixDelegate.hasPerspective()) {
             assert false;
-            Bridge.getLog().warning(null,
+            Bridge.getLog().fidelityWarning(null,
                     "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
-                    "supports affine transformations in the Layout Preview.");
+                    "supports affine transformations in the Layout Preview.", null);
         }
     }
 
@@ -522,7 +528,11 @@
             // set the color
             graphics.setColor(new Color(color, true /*alpha*/));
 
-            setModeInGraphics(graphics, mode);
+            Composite composite = PorterDuffXfermode_Delegate.getComposite(
+                    PorterDuffXfermode_Delegate.getPorterDuffMode(mode), 0xFF);
+            if (composite != null) {
+                graphics.setComposite(composite);
+            }
 
             graphics.fillRect(0, 0, canvasDelegate.mBufferedImage.getWidth(),
                     canvasDelegate.mBufferedImage.getHeight());
@@ -709,8 +719,28 @@
 
     /*package*/ static void native_drawPath(int nativeCanvas, int path,
                                                int paint) {
-        // FIXME
-        throw new UnsupportedOperationException();
+        final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        draw(nativeCanvas, paint, new Drawable() {
+            public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                Shape shape = pathDelegate.getJavaShape();
+                int style = paint.getStyle();
+
+                if (style == Paint.Style.FILL.nativeInt ||
+                        style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                    graphics.fill(shape);
+                }
+
+                if (style == Paint.Style.STROKE.nativeInt ||
+                        style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                    graphics.draw(shape);
+                }
+            }
+        });
     }
 
     /*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
@@ -719,8 +749,20 @@
                                                  int canvasDensity,
                                                  int screenDensity,
                                                  int bitmapDensity) {
-        // FIXME
-        throw new UnsupportedOperationException();
+        // get the delegate from the native int.
+        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
+        if (bitmapDelegate == null) {
+            assert false;
+            return;
+        }
+
+        BufferedImage image = bitmapDelegate.getImage();
+        float right = left + image.getWidth();
+        float bottom = top + image.getHeight();
+
+        drawBitmap(nativeCanvas, image, bitmapDelegate.getConfig(), nativePaintOrZero,
+                0, 0, image.getWidth(), image.getHeight(),
+                (int)left, (int)top, (int)right, (int)bottom);
     }
 
     /*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
@@ -738,11 +780,11 @@
         BufferedImage image = bitmapDelegate.getImage();
 
         if (src == null) {
-            drawBitmap(nativeCanvas, image, nativePaintOrZero,
+            drawBitmap(nativeCanvas, image, bitmapDelegate.getConfig(), nativePaintOrZero,
                     0, 0, image.getWidth(), image.getHeight(),
                     (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
         } else {
-            drawBitmap(nativeCanvas, image, nativePaintOrZero,
+            drawBitmap(nativeCanvas, image, bitmapDelegate.getConfig(), nativePaintOrZero,
                     src.left, src.top, src.width(), src.height(),
                     (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
         }
@@ -763,11 +805,11 @@
         BufferedImage image = bitmapDelegate.getImage();
 
         if (src == null) {
-            drawBitmap(nativeCanvas, image, nativePaintOrZero,
+            drawBitmap(nativeCanvas, image, bitmapDelegate.getConfig(), nativePaintOrZero,
                     0, 0, image.getWidth(), image.getHeight(),
                     dst.left, dst.top, dst.right, dst.bottom);
         } else {
-            drawBitmap(nativeCanvas, image, nativePaintOrZero,
+            drawBitmap(nativeCanvas, image, bitmapDelegate.getConfig(), nativePaintOrZero,
                     src.left, src.top, src.width(), src.height(),
                     dst.left, dst.top, dst.right, dst.bottom);
         }
@@ -998,6 +1040,34 @@
 
     // ---- Private delegate/helper methods ----
 
+    /**
+     * Executes a {@link Drawable} with a given canvas and paint.
+     */
+    private static void draw(int nCanvas, int nPaint, Drawable drawable) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
+        if (canvasDelegate == null) {
+            assert false;
+            return;
+        }
+
+        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
+        if (paintDelegate == null) {
+            assert false;
+            return;
+        }
+
+        // get a Graphics2D object configured with the drawing parameters.
+        Graphics2D g = canvasDelegate.createCustomGraphics(paintDelegate);
+
+        try {
+            drawable.draw(g, paintDelegate);
+        } finally {
+            // dispose Graphics2D object
+            g.dispose();
+        }
+    }
+
     private Canvas_Delegate(BufferedImage image) {
         setBitmap(image);
     }
@@ -1066,137 +1136,103 @@
                     RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
         }
 
-        boolean useColorPaint = true;
-
         // get the shader first, as it'll replace the color if it can be used it.
-        Shader_Delegate shaderDelegate = Shader_Delegate.getDelegate(paint.getShader());
-        if (shaderDelegate != null) {
-            java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
-            assert shaderPaint != null;
-            if (shaderPaint != null) {
-                g.setPaint(shaderPaint);
-                useColorPaint = false;
-            } else {
-                Bridge.getLog().warning(null,
-                        String.format(
-                            "Shader '%1$s' is not supported in the Layout Preview.",
-                            shaderDelegate.getClass().getCanonicalName()));
+        boolean customShader = false;
+        int nativeShader = paint.getShader();
+        if (nativeShader > 0) {
+            Shader_Delegate shaderDelegate = Shader_Delegate.getDelegate(nativeShader);
+            assert shaderDelegate != null;
+            if (shaderDelegate != null) {
+                if (shaderDelegate.isSupported()) {
+                    java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
+                    assert shaderPaint != null;
+                    if (shaderPaint != null) {
+                        g.setPaint(shaderPaint);
+                        customShader = true;
+                    }
+                } else {
+                    Bridge.getLog().fidelityWarning(null,
+                            shaderDelegate.getSupportMessage(),
+                            null);
+                }
             }
         }
 
-        if (useColorPaint) {
+        // if no shader, use the paint color
+        if (customShader == false) {
             g.setColor(new Color(paint.getColor(), true /*hasAlpha*/));
         }
 
-        int style = paint.getStyle();
-        if (style == Paint.Style.STROKE.nativeInt ||
-                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-
-            PathEffect_Delegate effectDelegate = PathEffect_Delegate.getDelegate(
-                    paint.getPathEffect());
-
-            if (effectDelegate instanceof DashPathEffect_Delegate) {
-                DashPathEffect_Delegate dpe = (DashPathEffect_Delegate)effectDelegate;
-                g.setStroke(new BasicStroke(
-                        paint.getStrokeWidth(),
-                        paint.getJavaCap(),
-                        paint.getJavaJoin(),
-                        paint.getStrokeMiter(),
-                        dpe.getIntervals(),
-                        dpe.getPhase()));
-            } else {
-                g.setStroke(new BasicStroke(
-                        paint.getStrokeWidth(),
-                        paint.getJavaCap(),
-                        paint.getJavaJoin(),
-                        paint.getStrokeMiter()));
+        boolean customStroke = false;
+        int pathEffect = paint.getPathEffect();
+        if (pathEffect > 0) {
+            PathEffect_Delegate effectDelegate = PathEffect_Delegate.getDelegate(pathEffect);
+            assert effectDelegate != null;
+            if (effectDelegate != null) {
+                if (effectDelegate.isSupported()) {
+                    Stroke stroke = effectDelegate.getStroke(paint);
+                    assert stroke != null;
+                    if (stroke != null) {
+                        g.setStroke(stroke);
+                        customStroke = true;
+                    }
+                } else {
+                    Bridge.getLog().fidelityWarning(null,
+                            effectDelegate.getSupportMessage(),
+                            null);
+                }
             }
         }
 
-        Xfermode_Delegate xfermodeDelegate = Xfermode_Delegate.getDelegate(paint.getXfermode());
-        if (xfermodeDelegate instanceof PorterDuffXfermode_Delegate) {
-            int mode = ((PorterDuffXfermode_Delegate)xfermodeDelegate).getMode();
+        // if no custom stroke as been set, set the default one.
+        if (customStroke == false) {
+            g.setStroke(new BasicStroke(
+                    paint.getStrokeWidth(),
+                    paint.getJavaCap(),
+                    paint.getJavaJoin(),
+                    paint.getJavaStrokeMiter()));
+        }
 
-            setModeInGraphics(g, mode);
-        } else {
-            // default mode is src_over
-            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
+        // the alpha for the composite. Always opaque if the normal paint color is used since
+        // it contains the alpha
+        int alpha = customShader ? paint.getAlpha() : 0xFF;
 
-            // if xfermode wasn't null, then it's something we don't support. log it.
+        boolean customXfermode = false;
+        int xfermode = paint.getXfermode();
+        if (xfermode > 0) {
+            Xfermode_Delegate xfermodeDelegate = Xfermode_Delegate.getDelegate(paint.getXfermode());
+            assert xfermodeDelegate != null;
             if (xfermodeDelegate != null) {
-                assert false;
-                Bridge.getLog().warning(null,
-                        String.format(
-                            "Xfermode '%1$s' is not supported in the Layout Preview.",
-                            xfermodeDelegate.getClass().getCanonicalName()));
+                if (xfermodeDelegate.isSupported()) {
+                    Composite composite = xfermodeDelegate.getComposite(alpha);
+                    assert composite != null;
+                    if (composite != null) {
+                        g.setComposite(composite);
+                        customXfermode = true;
+                    }
+                } else {
+                    Bridge.getLog().fidelityWarning(null,
+                            xfermodeDelegate.getSupportMessage(),
+                            null);
+                }
             }
         }
 
+        // if there was no custom xfermode, but we have alpha (due to a shader and a non
+        // opaque alpha channel in the paint color), then we create an AlphaComposite anyway
+        // that will handle the alpha.
+        if (customXfermode == false && alpha != 0xFF) {
+            g.setComposite(PorterDuffXfermode_Delegate.getComposite(
+                    PorterDuff.Mode.SRC_OVER, alpha));
+        }
+
         return g;
     }
 
-    private static void setModeInGraphics(Graphics2D g, int mode) {
-        for (PorterDuff.Mode m : PorterDuff.Mode.values()) {
-            if (m.nativeInt == mode) {
-                setModeInGraphics(g, m);
-                return;
-            }
-        }
-    }
-
-    private static void setModeInGraphics(Graphics2D g, PorterDuff.Mode mode) {
-        switch (mode) {
-            case CLEAR:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 1.0f /*alpha*/));
-                break;
-            case DARKEN:
-                break;
-            case DST:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, 1.0f /*alpha*/));
-                break;
-            case DST_ATOP:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 1.0f /*alpha*/));
-                break;
-            case DST_IN:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0f /*alpha*/));
-                break;
-            case DST_OUT:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, 1.0f /*alpha*/));
-                break;
-            case DST_OVER:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, 1.0f /*alpha*/));
-                break;
-            case LIGHTEN:
-                break;
-            case MULTIPLY:
-                break;
-            case SCREEN:
-                break;
-            case SRC:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f /*alpha*/));
-                break;
-            case SRC_ATOP:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f /*alpha*/));
-                break;
-            case SRC_IN:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1.0f /*alpha*/));
-                break;
-            case SRC_OUT:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, 1.0f /*alpha*/));
-                break;
-            case SRC_OVER:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f /*alpha*/));
-                break;
-            case XOR:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, 1.0f /*alpha*/));
-                break;
-        }
-    }
-
-
     private static void drawBitmap(
             int nativeCanvas,
             BufferedImage image,
+            Bitmap.Config mBitmapConfig,
             int nativePaintOrZero,
             int sleft, int stop, int sright, int sbottom,
             int dleft, int dtop, int dright, int dbottom) {
@@ -1217,7 +1253,7 @@
             }
         }
 
-        drawBitmap(canvasDelegate, image, paintDelegate,
+        drawBitmap(canvasDelegate, image, mBitmapConfig, paintDelegate,
                 sleft, stop, sright, sbottom,
                 dleft, dtop, dright, dbottom);
     }
@@ -1225,9 +1261,11 @@
     private static void drawBitmap(
             Canvas_Delegate canvasDelegate,
             BufferedImage image,
+            Bitmap.Config mBitmapConfig,
             Paint_Delegate paintDelegate,
             int sleft, int stop, int sright, int sbottom,
             int dleft, int dtop, int dright, int dbottom) {
+        //FIXME add support for canvas, screen and bitmap densities.
 
         Graphics2D g = canvasDelegate.getGcSnapshot().create();
         try {
@@ -1236,6 +1274,21 @@
                         RenderingHints.VALUE_INTERPOLATION_BILINEAR);
             }
 
+            // if the bitmap config is alpha_8, then we erase all color value from it
+            // before drawing it.
+            if (mBitmapConfig == Bitmap.Config.ALPHA_8) {
+                int w = image.getWidth();
+                int h = image.getHeight();
+                int[] argb = new int[w*h];
+                image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
+
+                final int length = argb.length;
+                for (int i = 0 ; i < length; i++) {
+                    argb[i] &= 0xFF000000;
+                }
+                image.setRGB(0, 0, w, h, argb, 0, w);
+            }
+
             g.drawImage(image, dleft, dtop, dright, dbottom,
                     sleft, stop, sright, sbottom, null);
         } finally {
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
new file mode 100644
index 0000000..954c658
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
@@ -0,0 +1,69 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.ComposePathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of ComposePathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original ComposePathEffect class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class ComposePathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Composte Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    /*package*/ static int nativeCreate(int outerpe, int innerpe) {
+        ComposePathEffect_Delegate newDelegate = new ComposePathEffect_Delegate();
+        return sManager.addDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
new file mode 100644
index 0000000..2853222
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
@@ -0,0 +1,93 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import java.awt.Paint;
+
+/**
+ * Delegate implementing the native methods of android.graphics.ComposeShader
+ *
+ * Through the layoutlib_create tool, the original native methods of ComposeShader have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original ComposeShader class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class ComposeShader_Delegate extends Shader_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Paint getJavaPaint() {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Compose Shader are not supported in Layout Preview mode.";
+    }
+
+
+    // ---- native methods ----
+
+    /*package*/ static int nativeCreate1(int native_shaderA, int native_shaderB,
+            int native_mode) {
+        // FIXME not supported yet.
+        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate();
+        return sManager.addDelegate(newDelegate);
+    }
+
+    /*package*/ static int nativeCreate2(int native_shaderA, int native_shaderB,
+            int porterDuffMode) {
+        // FIXME not supported yet.
+        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate();
+        return sManager.addDelegate(newDelegate);
+    }
+
+    /*package*/ static int nativePostCreate1(int native_shader, int native_skiaShaderA,
+            int native_skiaShaderB, int native_mode) {
+        // pass, not needed.
+        return 0;
+    }
+
+    /*package*/ static int nativePostCreate2(int native_shader, int native_skiaShaderA,
+            int native_skiaShaderB, int porterDuffMode) {
+        // pass, not needed.
+        return 0;
+    }
+
+
+    // ---- Private delegate/helper methods ----
+
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
new file mode 100644
index 0000000..cd08549
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
@@ -0,0 +1,69 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.CornerPathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of CornerPathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original CornerPathEffect class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class CornerPathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Corner Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    /*package*/ static int nativeCreate(float radius) {
+        CornerPathEffect_Delegate newDelegate = new CornerPathEffect_Delegate();
+        return sManager.addDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
index 7ee72d8..5a704a7 100644
--- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
@@ -18,6 +18,9 @@
 
 import com.android.layoutlib.bridge.impl.DelegateManager;
 
+import java.awt.BasicStroke;
+import java.awt.Stroke;
+
 /**
  * Delegate implementing the native methods of android.graphics.DashPathEffect
  *
@@ -32,8 +35,10 @@
  * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
  * {@link PathEffect_Delegate}.
  *
+ * @see PathEffect_Delegate
+ *
  */
-public class DashPathEffect_Delegate extends PathEffect_Delegate {
+public final class DashPathEffect_Delegate extends PathEffect_Delegate {
 
     // ---- delegate data ----
 
@@ -42,12 +47,26 @@
 
     // ---- Public Helper methods ----
 
-    public float[] getIntervals() {
-        return mIntervals;
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        return new BasicStroke(
+                paint.getStrokeWidth(),
+                paint.getJavaCap(),
+                paint.getJavaJoin(),
+                paint.getJavaStrokeMiter(),
+                mIntervals,
+                mPhase);
     }
 
-    public float getPhase() {
-        return mPhase;
+    @Override
+    public boolean isSupported() {
+        return true;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        // no message since isSupported returns true;
+        return null;
     }
 
     // ---- native methods ----
diff --git a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
new file mode 100644
index 0000000..f99ab2b
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
@@ -0,0 +1,69 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.DiscretePathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of DiscretePathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original DiscretePathEffect class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class DiscretePathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Discrete Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    /*package*/ static int nativeCreate(float length, float deviation) {
+        DiscretePathEffect_Delegate newDelegate = new DiscretePathEffect_Delegate();
+        return sManager.addDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
index bc4ccd2..7a0c2f7 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
@@ -26,6 +26,18 @@
     protected final int[] mColors;
     protected final float[] mPositions;
 
+    @Override
+    public boolean isSupported() {
+        // all gradient shaders are supported.
+        return true;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        // all gradient shaders are supported, no need for a gradient support
+        return null;
+    }
+
     /**
      * Creates the base shader and do some basic test on the parameters.
      *
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
index 862b4544..9fb48c80 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
@@ -21,10 +21,6 @@
 
 import android.graphics.Shader.TileMode;
 
-import java.awt.Paint;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-
 /**
  * Delegate implementing the native methods of android.graphics.LinearGradient
  *
@@ -41,7 +37,7 @@
  * @see Shader_Delegate
  *
  */
-public class LinearGradient_Delegate extends Gradient_Delegate {
+public final class LinearGradient_Delegate extends Gradient_Delegate {
 
     // ---- delegate data ----
     private java.awt.Paint mJavaPaint;
@@ -49,7 +45,7 @@
     // ---- Public Helper methods ----
 
     @Override
-    public Paint getJavaPaint() {
+    public java.awt.Paint getJavaPaint() {
         return mJavaPaint;
     }
 
@@ -58,17 +54,8 @@
     /*package*/ static int nativeCreate1(LinearGradient thisGradient,
             float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode) {
-        // figure out the tile
-        TileMode tile = null;
-        for (TileMode tm : TileMode.values()) {
-            if (tm.nativeInt == tileMode) {
-                tile = tm;
-                break;
-            }
-        }
-
         LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(x0, y0, x1, y1,
-                colors, positions, tile);
+                colors, positions, Shader_Delegate.getTileMode(tileMode));
         return sManager.addDelegate(newDelegate);
     }
     /*package*/ static int nativeCreate2(LinearGradient thisGradient,
@@ -144,20 +131,20 @@
                 java.awt.RenderingHints        hints) {
             precomputeGradientColors();
 
-            AffineTransform canvasMatrix;
+            java.awt.geom.AffineTransform canvasMatrix;
             try {
                 canvasMatrix = xform.createInverse();
-            } catch (NoninvertibleTransformException e) {
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
                 Bridge.getLog().error(null, "Unable to inverse matrix in LinearGradient", e);
-                canvasMatrix = new AffineTransform();
+                canvasMatrix = new java.awt.geom.AffineTransform();
             }
 
-            AffineTransform localMatrix = getLocalMatrix();
+            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
             try {
                 localMatrix = localMatrix.createInverse();
-            } catch (NoninvertibleTransformException e) {
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
                 Bridge.getLog().error(null, "Unable to inverse matrix in LinearGradient", e);
-                localMatrix = new AffineTransform();
+                localMatrix = new java.awt.geom.AffineTransform();
             }
 
             return new LinearGradientPaintContext(canvasMatrix, localMatrix, colorModel);
@@ -165,12 +152,14 @@
 
         private class LinearGradientPaintContext implements java.awt.PaintContext {
 
-            private final AffineTransform mCanvasMatrix;
-            private final AffineTransform mLocalMatrix;
+            private final java.awt.geom.AffineTransform mCanvasMatrix;
+            private final java.awt.geom.AffineTransform mLocalMatrix;
             private final java.awt.image.ColorModel mColorModel;
 
-            public LinearGradientPaintContext(AffineTransform canvasMatrix,
-                    AffineTransform localMatrix, java.awt.image.ColorModel colorModel) {
+            private LinearGradientPaintContext(
+                    java.awt.geom.AffineTransform canvasMatrix,
+                    java.awt.geom.AffineTransform localMatrix,
+                    java.awt.image.ColorModel colorModel) {
                 mCanvasMatrix = canvasMatrix;
                 mLocalMatrix = localMatrix;
                 mColorModel = colorModel;
@@ -218,10 +207,17 @@
          * Returns a color for an arbitrary point.
          */
         private int getColor(float x, float y) {
-            // find the x position on the gradient vector.
-            float _x = (mDx*mDy*(y-mY0) + mDy*mDy*mX0 + mDx*mDx*x) / mDSize2;
-            // from it get the position relative to the vector
-            float pos = (float) ((_x - mX0) / mDx);
+            float pos;
+            if (mDx == 0) {
+                pos = (y - mY0) / mDy;
+            } else if (mDy == 0) {
+                pos = (x - mX0) / mDx;
+            } else {
+                // find the x position on the gradient vector.
+                float _x = (mDx*mDy*(y-mY0) + mDy*mDy*mX0 + mDx*mDx*x) / mDSize2;
+                // from it get the position relative to the vector
+                pos = (_x - mX0) / mDx;
+            }
 
             return getGradientColor(pos);
         }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
index b464f66..f6cee5e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
@@ -1052,6 +1052,4 @@
 
         return tmp;
     }
-
-
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
index fe9bef9..b8f76a6 100644
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
@@ -43,7 +43,7 @@
  * around to map int to instance of the delegate.
  *
  */
-public class NinePatch_Delegate {
+public final class NinePatch_Delegate {
 
     /**
      * Cache map for {@link NinePatchChunk}.
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index fa26bcf..0a597ca 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -114,6 +114,10 @@
         return mColor;
     }
 
+    public int getAlpha() {
+        return mColor >>> 24;
+    }
+
     public int getTextAlign() {
         return mTextAlign;
     }
@@ -122,8 +126,11 @@
         return mStrokeWidth;
     }
 
-    public float getStrokeMiter() {
-        return mStrokeMiter;
+    /**
+     * returns the value of stroke miter needed by the java api.
+     */
+    public float getJavaStrokeMiter() {
+        return mStrokeMiter * mStrokeWidth;
     }
 
     public int getJavaCap() {
@@ -256,7 +263,7 @@
             return 0;
         }
 
-        return delegate.mColor >>> 24;
+        return delegate.getAlpha();
     }
 
     /*package*/ static void setAlpha(Paint thisPaint, int a) {
@@ -860,9 +867,9 @@
     private void reset() {
         mFlags = Paint.DEFAULT_PAINT_FLAGS;
         mColor = 0;
-        mStyle = 0;
-        mCap = 0;
-        mJoin = 0;
+        mStyle = Paint.Style.FILL.nativeInt;
+        mCap = Paint.Cap.BUTT.nativeInt;
+        mJoin = Paint.Join.MITER.nativeInt;
         mTextAlign = 0;
         mTypeface = Typeface.sDefaults[0].native_instance;
         mStrokeWidth = 1.f;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path.java b/tools/layoutlib/bridge/src/android/graphics/Path.java
deleted file mode 100644
index c0bc005..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Path.java
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * Copyright (C) 2006 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 android.graphics;
-
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
-
-/**
- * The Path class encapsulates compound (multiple contour) geometric paths
- * consisting of straight line segments, quadratic curves, and cubic curves.
- * It can be drawn with canvas.drawPath(path, paint), either filled or stroked
- * (based on the paint's Style), or it can be used for clipping or to draw
- * text on a path.
- */
-public class Path {
-
-    private FillType mFillType = FillType.WINDING;
-    private GeneralPath mPath = new GeneralPath();
-
-    private float mLastX = 0;
-    private float mLastY = 0;
-
-    //---------- Custom methods ----------
-
-    public Shape getAwtShape() {
-        return mPath;
-    }
-
-    //----------
-
-    /**
-     * Create an empty path
-     */
-    public Path() {
-    }
-
-    /**
-     * Create a new path, copying the contents from the src path.
-     *
-     * @param src The path to copy from when initializing the new path
-     */
-    public Path(Path src) {
-        mPath.append(src.mPath, false /* connect */);
-    }
-
-    /**
-     * Clear any lines and curves from the path, making it empty.
-     * This does NOT change the fill-type setting.
-     */
-    public void reset() {
-        mPath = new GeneralPath();
-    }
-
-    /**
-     * Rewinds the path: clears any lines and curves from the path but
-     * keeps the internal data structure for faster reuse.
-     */
-    public void rewind() {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /** Replace the contents of this with the contents of src.
-    */
-    public void set(Path src) {
-        mPath.append(src.mPath, false /* connect */);
-    }
-
-    /** Enum for the ways a path may be filled
-    */
-    public enum FillType {
-        // these must match the values in SkPath.h
-        WINDING         (GeneralPath.WIND_NON_ZERO, false),
-        EVEN_ODD        (GeneralPath.WIND_EVEN_ODD, false),
-        INVERSE_WINDING (GeneralPath.WIND_NON_ZERO, true),
-        INVERSE_EVEN_ODD(GeneralPath.WIND_EVEN_ODD, true);
-
-        FillType(int rule, boolean inverse) {
-            this.rule = rule;
-            this.inverse = inverse;
-        }
-
-        final int rule;
-        final boolean inverse;
-    }
-
-    /**
-     * Return the path's fill type. This defines how "inside" is
-     * computed. The default value is WINDING.
-     *
-     * @return the path's fill type
-     */
-    public FillType getFillType() {
-        return mFillType;
-    }
-
-    /**
-     * Set the path's fill type. This defines how "inside" is computed.
-     *
-     * @param ft The new fill type for this path
-     */
-    public void setFillType(FillType ft) {
-        mFillType = ft;
-        mPath.setWindingRule(ft.rule);
-    }
-
-    /**
-     * Returns true if the filltype is one of the INVERSE variants
-     *
-     * @return true if the filltype is one of the INVERSE variants
-     */
-    public boolean isInverseFillType() {
-        return mFillType.inverse;
-    }
-
-    /**
-     * Toggles the INVERSE state of the filltype
-     */
-    public void toggleInverseFillType() {
-        switch (mFillType) {
-            case WINDING:
-                mFillType = FillType.INVERSE_WINDING;
-                break;
-            case EVEN_ODD:
-                mFillType = FillType.INVERSE_EVEN_ODD;
-                break;
-            case INVERSE_WINDING:
-                mFillType = FillType.WINDING;
-                break;
-            case INVERSE_EVEN_ODD:
-                mFillType = FillType.EVEN_ODD;
-                break;
-        }
-    }
-
-    /**
-     * Returns true if the path is empty (contains no lines or curves)
-     *
-     * @return true if the path is empty (contains no lines or curves)
-     */
-    public boolean isEmpty() {
-        return mPath.getCurrentPoint() == null;
-    }
-
-    /**
-     * Returns true if the path specifies a rectangle. If so, and if rect is
-     * not null, set rect to the bounds of the path. If the path does not
-     * specify a rectangle, return false and ignore rect.
-     *
-     * @param rect If not null, returns the bounds of the path if it specifies
-     *             a rectangle
-     * @return     true if the path specifies a rectangle
-     */
-    public boolean isRect(RectF rect) {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Compute the bounds of the path, and write the answer into bounds. If the
-     * path contains 0 or 1 points, the bounds is set to (0,0,0,0)
-     *
-     * @param bounds Returns the computed bounds of the path
-     * @param exact If true, return the exact (but slower) bounds, else return
-     *              just the bounds of all control points
-     */
-    public void computeBounds(RectF bounds, boolean exact) {
-        Rectangle2D rect = mPath.getBounds2D();
-        bounds.left = (float)rect.getMinX();
-        bounds.right = (float)rect.getMaxX();
-        bounds.top = (float)rect.getMinY();
-        bounds.bottom = (float)rect.getMaxY();
-    }
-
-    /**
-     * Hint to the path to prepare for adding more points. This can allow the
-     * path to more efficiently allocate its storage.
-     *
-     * @param extraPtCount The number of extra points that may be added to this
-     *                     path
-     */
-    public void incReserve(int extraPtCount) {
-        // pass
-    }
-
-    /**
-     * Set the beginning of the next contour to the point (x,y).
-     *
-     * @param x The x-coordinate of the start of a new contour
-     * @param y The y-coordinate of the start of a new contour
-     */
-    public void moveTo(float x, float y) {
-        mPath.moveTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Set the beginning of the next contour relative to the last point on the
-     * previous contour. If there is no previous contour, this is treated the
-     * same as moveTo().
-     *
-     * @param dx The amount to add to the x-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     * @param dy The amount to add to the y-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     */
-    public void rMoveTo(float dx, float dy) {
-        dx += mLastX;
-        dy += mLastY;
-        mPath.moveTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a line from the last point to the specified point (x,y).
-     * If no moveTo() call has been made for this contour, the first point is
-     * automatically set to (0,0).
-     *
-     * @param x The x-coordinate of the end of a line
-     * @param y The y-coordinate of the end of a line
-     */
-    public void lineTo(float x, float y) {
-        mPath.lineTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Same as lineTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx The amount to add to the x-coordinate of the previous point on
-     *           this contour, to specify a line
-     * @param dy The amount to add to the y-coordinate of the previous point on
-     *           this contour, to specify a line
-     */
-    public void rLineTo(float dx, float dy) {
-        if (isEmpty()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx += mLastX;
-        dy += mLastY;
-        mPath.lineTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a quadratic bezier from the last point, approaching control point
-     * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
-     * this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the control point on a quadratic curve
-     * @param y1 The y-coordinate of the control point on a quadratic curve
-     * @param x2 The x-coordinate of the end point on a quadratic curve
-     * @param y2 The y-coordinate of the end point on a quadratic curve
-     */
-    public void quadTo(float x1, float y1, float x2, float y2) {
-        mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
-    }
-
-    /**
-     * Same as quadTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx1 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dy1 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dx2 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     * @param dy2 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     */
-    public void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
-        if (isEmpty()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
-    }
-
-    /**
-     * Add a cubic bezier from the last point, approaching control points
-     * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
-     * made for this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the 1st control point on a cubic curve
-     * @param y1 The y-coordinate of the 1st control point on a cubic curve
-     * @param x2 The x-coordinate of the 2nd control point on a cubic curve
-     * @param y2 The y-coordinate of the 2nd control point on a cubic curve
-     * @param x3 The x-coordinate of the end point on a cubic curve
-     * @param y3 The y-coordinate of the end point on a cubic curve
-     */
-    public void cubicTo(float x1, float y1, float x2, float y2,
-                        float x3, float y3) {
-        mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
-    }
-
-    /**
-     * Same as cubicTo, but the coordinates are considered relative to the
-     * current point on this contour. If there is no previous point, then a
-     * moveTo(0,0) is inserted automatically.
-     */
-    public void rCubicTo(float dx1, float dy1, float dx2, float dy2,
-                         float dx3, float dy3) {
-        if (isEmpty()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        dx3 += mLastX;
-        dy3 += mLastY;
-        mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
-    }
-
-    /**
-     * Append the specified arc to the path as a new contour. If the start of
-     * the path is different from the path's current last point, then an
-     * automatic lineTo() is added to connect the current contour to the
-     * start of the arc. However, if the path is empty, then we call moveTo()
-     * with the first point of the arc. The sweep angle is tread mod 360.
-     *
-     * @param oval        The bounds of oval defining shape and size of the arc
-     * @param startAngle  Starting angle (in degrees) where the arc begins
-     * @param sweepAngle  Sweep angle (in degrees) measured clockwise, treated
-     *                    mod 360.
-     * @param forceMoveTo If true, always begin a new contour with the arc
-     */
-    public void arcTo(RectF oval, float startAngle, float sweepAngle,
-                      boolean forceMoveTo) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Append the specified arc to the path as a new contour. If the start of
-     * the path is different from the path's current last point, then an
-     * automatic lineTo() is added to connect the current contour to the
-     * start of the arc. However, if the path is empty, then we call moveTo()
-     * with the first point of the arc.
-     *
-     * @param oval        The bounds of oval defining shape and size of the arc
-     * @param startAngle  Starting angle (in degrees) where the arc begins
-     * @param sweepAngle  Sweep angle (in degrees) measured clockwise
-     */
-    public void arcTo(RectF oval, float startAngle, float sweepAngle) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Close the current contour. If the current point is not equal to the
-     * first point of the contour, a line segment is automatically added.
-     */
-    public void close() {
-        mPath.closePath();
-    }
-
-    /**
-     * Specifies how closed shapes (e.g. rects, ovals) are oriented when they
-     * are added to a path.
-     */
-    public enum Direction {
-        /** clockwise */
-        CW  (0),    // must match enum in SkPath.h
-        /** counter-clockwise */
-        CCW (1);    // must match enum in SkPath.h
-
-        Direction(int ni) {
-            nativeInt = ni;
-        }
-        final int nativeInt;
-    }
-
-    /**
-     * Add a closed rectangle contour to the path
-     *
-     * @param rect The rectangle to add as a closed contour to the path
-     * @param dir  The direction to wind the rectangle's contour
-     */
-    public void addRect(RectF rect, Direction dir) {
-        if (rect == null) {
-            throw new NullPointerException("need rect parameter");
-        }
-
-        addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
-    }
-
-    /**
-     * Add a closed rectangle contour to the path
-     *
-     * @param left   The left side of a rectangle to add to the path
-     * @param top    The top of a rectangle to add to the path
-     * @param right  The right side of a rectangle to add to the path
-     * @param bottom The bottom of a rectangle to add to the path
-     * @param dir    The direction to wind the rectangle's contour
-     */
-    public void addRect(float left, float top, float right, float bottom,
-                        Direction dir) {
-        moveTo(left, top);
-
-        switch (dir) {
-            case CW:
-                lineTo(right, top);
-                lineTo(right, bottom);
-                lineTo(left, bottom);
-                break;
-            case CCW:
-                lineTo(left, bottom);
-                lineTo(right, bottom);
-                lineTo(right, top);
-                break;
-        }
-
-        close();
-    }
-
-    /**
-     * Add a closed oval contour to the path
-     *
-     * @param oval The bounds of the oval to add as a closed contour to the path
-     * @param dir  The direction to wind the oval's contour
-     */
-    public void addOval(RectF oval, Direction dir) {
-        if (oval == null) {
-            throw new NullPointerException("need oval parameter");
-        }
-
-        // FIXME Need to support direction
-        Ellipse2D ovalShape = new Ellipse2D.Float(oval.left, oval.top, oval.width(), oval.height());
-
-        mPath.append(ovalShape, false /* connect */);
-    }
-
-    /**
-     * Add a closed circle contour to the path
-     *
-     * @param x   The x-coordinate of the center of a circle to add to the path
-     * @param y   The y-coordinate of the center of a circle to add to the path
-     * @param radius The radius of a circle to add to the path
-     * @param dir    The direction to wind the circle's contour
-     */
-    public void addCircle(float x, float y, float radius, Direction dir) {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Add the specified arc to the path as a new contour.
-     *
-     * @param oval The bounds of oval defining the shape and size of the arc
-     * @param startAngle Starting angle (in degrees) where the arc begins
-     * @param sweepAngle Sweep angle (in degrees) measured clockwise
-     */
-    public void addArc(RectF oval, float startAngle, float sweepAngle) {
-        if (oval == null) {
-            throw new NullPointerException("need oval parameter");
-        }
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-        * Add a closed round-rectangle contour to the path
-     *
-     * @param rect The bounds of a round-rectangle to add to the path
-     * @param rx   The x-radius of the rounded corners on the round-rectangle
-     * @param ry   The y-radius of the rounded corners on the round-rectangle
-     * @param dir  The direction to wind the round-rectangle's contour
-     */
-    public void addRoundRect(RectF rect, float rx, float ry, Direction dir) {
-        if (rect == null) {
-            throw new NullPointerException("need rect parameter");
-        }
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Add a closed round-rectangle contour to the path. Each corner receives
-     * two radius values [X, Y]. The corners are ordered top-left, top-right,
-     * bottom-right, bottom-left
-     *
-     * @param rect The bounds of a round-rectangle to add to the path
-     * @param radii Array of 8 values, 4 pairs of [X,Y] radii
-     * @param dir  The direction to wind the round-rectangle's contour
-     */
-    public void addRoundRect(RectF rect, float[] radii, Direction dir) {
-        if (rect == null) {
-            throw new NullPointerException("need rect parameter");
-        }
-        if (radii.length < 8) {
-            throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values");
-        }
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Add a copy of src to the path, offset by (dx,dy)
-     *
-     * @param src The path to add as a new contour
-     * @param dx  The amount to translate the path in X as it is added
-     */
-    public void addPath(Path src, float dx, float dy) {
-        PathIterator iterator = src.mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
-        mPath.append(iterator, false /* connect */);
-    }
-
-    /**
-     * Add a copy of src to the path
-     *
-     * @param src The path that is appended to the current path
-     */
-    public void addPath(Path src) {
-        addPath(src, 0, 0);
-    }
-
-    /**
-     * Add a copy of src to the path, transformed by matrix
-     *
-     * @param src The path to add as a new contour
-     */
-    public void addPath(Path src, Matrix matrix) {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Offset the path by (dx,dy), returning true on success
-     *
-     * @param dx  The amount in the X direction to offset the entire path
-     * @param dy  The amount in the Y direction to offset the entire path
-     * @param dst The translated path is written here. If this is null, then
-     *            the original path is modified.
-     */
-    public void offset(float dx, float dy, Path dst) {
-        GeneralPath newPath = new GeneralPath();
-
-        PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
-
-        newPath.append(iterator, false /* connect */);
-
-        if (dst != null) {
-            dst.mPath = newPath;
-        } else {
-            mPath = newPath;
-        }
-    }
-
-    /**
-     * Offset the path by (dx,dy), returning true on success
-     *
-     * @param dx The amount in the X direction to offset the entire path
-     * @param dy The amount in the Y direction to offset the entire path
-     */
-    public void offset(float dx, float dy) {
-        offset(dx, dy, null /* dst */);
-    }
-
-    /**
-     * Sets the last point of the path.
-     *
-     * @param dx The new X coordinate for the last point
-     * @param dy The new Y coordinate for the last point
-     */
-    public void setLastPoint(float dx, float dy) {
-        mLastX = dx;
-        mLastY = dy;
-    }
-
-    /**
-     * Transform the points in this path by matrix, and write the answer
-     * into dst. If dst is null, then the the original path is modified.
-     *
-     * @param matrix The matrix to apply to the path
-     * @param dst    The transformed path is written here. If dst is null,
-     *               then the the original path is modified
-     */
-    public void transform(Matrix matrix, Path dst) {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Transform the points in this path by matrix.
-     *
-     * @param matrix The matrix to apply to the path
-     */
-    public void transform(Matrix matrix) {
-        transform(matrix, null /* dst */);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
new file mode 100644
index 0000000..3777ac9
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
@@ -0,0 +1,70 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PathDashPathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of PathDashPathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PathDashPathEffect class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class PathDashPathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Path Dash Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    /*package*/ static int nativeCreate(int native_path, float advance, float phase,
+            int native_style) {
+        PathDashPathEffect_Delegate newDelegate = new PathDashPathEffect_Delegate();
+        return sManager.addDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
index ce7eef0..c588423 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
@@ -18,6 +18,8 @@
 
 import com.android.layoutlib.bridge.impl.DelegateManager;
 
+import java.awt.Stroke;
+
 /**
  * Delegate implementing the native methods of android.graphics.PathEffect
  *
@@ -33,7 +35,7 @@
  * @see DelegateManager
  *
  */
-public class PathEffect_Delegate {
+public abstract class PathEffect_Delegate {
 
     // ---- delegate manager ----
     protected static final DelegateManager<PathEffect_Delegate> sManager =
@@ -49,6 +51,11 @@
         return sManager.getDelegate(nativeShader);
     }
 
+    public abstract Stroke getStroke(Paint_Delegate paint);
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
+
+
     // ---- native methods ----
 
     /*package*/ static void nativeDestructor(int native_patheffect) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
new file mode 100644
index 0000000..811f0f6
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -0,0 +1,748 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import android.graphics.Path.Direction;
+import android.graphics.Path.FillType;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Path
+ *
+ * Through the layoutlib_create tool, the original native methods of Path have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Path class.
+ *
+ * @see DelegateManager
+ *
+ */
+public final class Path_Delegate {
+
+    // ---- delegate manager ----
+    private static final DelegateManager<Path_Delegate> sManager =
+            new DelegateManager<Path_Delegate>();
+
+    // ---- delegate data ----
+    private FillType mFillType = FillType.WINDING;
+    private GeneralPath mPath = new GeneralPath();
+
+    private float mLastX = 0;
+    private float mLastY = 0;
+
+    // ---- Public Helper methods ----
+
+    public static Path_Delegate getDelegate(int nPath) {
+        return sManager.getDelegate(nPath);
+    }
+
+    public Shape getJavaShape() {
+        return mPath;
+    }
+
+    // ---- native methods ----
+
+    /*package*/ static int init1() {
+        // create the delegate
+        Path_Delegate newDelegate = new Path_Delegate();
+
+        return sManager.addDelegate(newDelegate);
+    }
+
+    /*package*/ static int init2(int nPath) {
+        // create the delegate
+        Path_Delegate newDelegate = new Path_Delegate();
+
+        // get the delegate to copy
+        if (nPath > 0) {
+            Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+            if (pathDelegate == null) {
+                assert false;
+                return 0;
+            }
+
+            newDelegate.set(pathDelegate);
+        }
+
+        return sManager.addDelegate(newDelegate);
+    }
+
+    /*package*/ static void native_reset(int nPath) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.mPath.reset();
+    }
+
+    /*package*/ static void native_rewind(int nPath) {
+        // call out to reset since there's nothing to optimize in
+        // terms of data structs.
+        native_reset(nPath);
+    }
+
+    /*package*/ static void native_set(int native_dst, int native_src) {
+        Path_Delegate pathDstDelegate = sManager.getDelegate(native_dst);
+        if (pathDstDelegate == null) {
+            assert false;
+            return;
+        }
+
+        Path_Delegate pathSrcDelegate = sManager.getDelegate(native_src);
+        if (pathSrcDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDstDelegate.set(pathSrcDelegate);
+    }
+
+    /*package*/ static int native_getFillType(int nPath) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return 0;
+        }
+
+        return pathDelegate.mFillType.nativeInt;
+    }
+
+    /*package*/ static void native_setFillType(int nPath, int ft) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.mFillType = Path.sFillTypeArray[ft];
+    }
+
+    /*package*/ static boolean native_isEmpty(int nPath) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return true;
+        }
+
+        return pathDelegate.isEmpty();
+    }
+
+    /*package*/ static boolean native_isRect(int nPath, RectF rect) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return false;
+        }
+
+        // create an Area that can test if the path is a rect
+        Area area = new Area(pathDelegate.mPath);
+        if (area.isRectangular()) {
+            if (rect != null) {
+                pathDelegate.fillBounds(rect);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /*package*/ static void native_computeBounds(int nPath, RectF bounds) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.fillBounds(bounds);
+    }
+
+    /*package*/ static void native_incReserve(int nPath, int extraPtCount) {
+        // since we use a java2D path, there's no way to pre-allocate new points,
+        // so we do nothing.
+    }
+
+    /*package*/ static void native_moveTo(int nPath, float x, float y) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.moveTo(x, y);
+    }
+
+    /*package*/ static void native_rMoveTo(int nPath, float dx, float dy) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.rMoveTo(dx, dy);
+    }
+
+    /*package*/ static void native_lineTo(int nPath, float x, float y) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.lineTo(x, y);
+    }
+
+    /*package*/ static void native_rLineTo(int nPath, float dx, float dy) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.rLineTo(dx, dy);
+    }
+
+    /*package*/ static void native_quadTo(int nPath, float x1, float y1, float x2, float y2) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.quadTo(x1, y1, x2, y2);
+    }
+
+    /*package*/ static void native_rQuadTo(int nPath, float dx1, float dy1,
+                                              float dx2, float dy2) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.rQuadTo(dx1, dy1, dx2, dy2);
+    }
+
+    /*package*/ static void native_cubicTo(int nPath, float x1, float y1,
+                float x2, float y2, float x3, float y3) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.cubicTo(x1, y1, x2, y2, x3, y3);
+    }
+
+    /*package*/ static void native_rCubicTo(int nPath, float x1, float y1,
+                float x2, float y2, float x3, float y3) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.rCubicTo(x1, y1, x2, y2, x3, y3);
+    }
+
+    /*package*/ static void native_arcTo(int nPath, RectF oval,
+                    float startAngle, float sweepAngle, boolean forceMoveTo) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
+    }
+
+    /*package*/ static void native_close(int nPath) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.close();
+    }
+
+    /*package*/ static void native_addRect(int nPath, RectF rect, int dir) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
+    }
+
+    /*package*/ static void native_addRect(int nPath, float left, float top,
+                                            float right, float bottom, int dir) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.addRect(left, top, right, bottom, dir);
+    }
+
+    /*package*/ static void native_addOval(int nPath, RectF oval, int dir) {
+        // FIXME
+        throw new UnsupportedOperationException();
+    }
+
+    /*package*/ static void native_addCircle(int nPath, float x, float y,
+                                                float radius, int dir) {
+        // FIXME
+        throw new UnsupportedOperationException();
+    }
+
+    /*package*/ static void native_addArc(int nPath, RectF oval,
+                                            float startAngle, float sweepAngle) {
+        // FIXME
+        throw new UnsupportedOperationException();
+    }
+
+    /*package*/ static void native_addRoundRect(int nPath, RectF rect,
+                                                   float rx, float ry, int dir) {
+        // FIXME
+        throw new UnsupportedOperationException();
+    }
+
+    /*package*/ static void native_addRoundRect(int nPath, RectF r,
+                                                   float[] radii, int dir) {
+        // FIXME
+        throw new UnsupportedOperationException();
+    }
+
+    /*package*/ static void native_addPath(int nPath, int src, float dx,
+                                              float dy) {
+        // FIXME
+        throw new UnsupportedOperationException();
+    }
+
+    /*package*/ static void native_addPath(int nPath, int src) {
+        // FIXME
+        throw new UnsupportedOperationException();
+    }
+
+    /*package*/ static void native_addPath(int nPath, int src, int matrix) {
+        // FIXME
+        throw new UnsupportedOperationException();
+    }
+
+    /*package*/ static void native_offset(int nPath, float dx, float dy,
+                                             int dst_path) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        Path_Delegate dstDelegate = null;
+        if (dst_path > 0) {
+            dstDelegate = sManager.getDelegate(dst_path);
+            if (dstDelegate == null) {
+                assert false;
+                return;
+            }
+        }
+
+        pathDelegate.offset(dx, dy, dstDelegate);
+    }
+
+    /*package*/ static void native_offset(int nPath, float dx, float dy) {
+        native_offset(nPath, dx, dy, 0);
+    }
+
+    /*package*/ static void native_setLastPoint(int nPath, float dx, float dy) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        pathDelegate.mLastX = dx;
+        pathDelegate.mLastY = dy;
+    }
+
+    /*package*/ static void native_transform(int nPath, int matrix,
+                                                int dst_path) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            assert false;
+            return;
+        }
+
+        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
+        if (matrixDelegate == null) {
+            assert false;
+            return;
+        }
+
+        Path_Delegate dstDelegate = null;
+        if (dst_path > 0) {
+            dstDelegate = sManager.getDelegate(dst_path);
+            if (dstDelegate == null) {
+                assert false;
+                return;
+            }
+        }
+
+        pathDelegate.transform(matrixDelegate, dstDelegate);
+    }
+
+    /*package*/ static void native_transform(int nPath, int matrix) {
+        native_transform(nPath, matrix, 0);
+    }
+
+    /*package*/ static void finalizer(int nPath) {
+        sManager.removeDelegate(nPath);
+    }
+
+
+    // ---- Private helper methods ----
+
+    private void set(Path_Delegate delegate) {
+        mPath.reset();
+        setFillType(delegate.mFillType);
+        mPath.append(delegate.mPath, false /*connect*/);
+    }
+
+    private void setFillType(FillType fillType) {
+        mFillType = fillType;
+        mPath.setWindingRule(getWindingRule(fillType));
+    }
+
+    /**
+     * Returns the Java2D winding rules matching a given Android {@link FillType}.
+     * @param type the android fill type
+     * @return the matching java2d winding rule.
+     */
+    private static int getWindingRule(FillType type) {
+        switch (type) {
+            case WINDING:
+            case INVERSE_WINDING:
+                return GeneralPath.WIND_NON_ZERO;
+            case EVEN_ODD:
+            case INVERSE_EVEN_ODD:
+                return GeneralPath.WIND_EVEN_ODD;
+        }
+
+        assert false;
+        throw new IllegalArgumentException();
+    }
+
+    private static Direction getDirection(int direction) {
+        for (Direction d : Direction.values()) {
+            if (direction == d.nativeInt) {
+                return d;
+            }
+        }
+
+        assert false;
+        return null;
+    }
+
+    /**
+     * Returns whether the path is empty.
+     * @return true if the path is empty.
+     */
+    private boolean isEmpty() {
+        return mPath.getCurrentPoint() == null;
+    }
+
+    /**
+     * Fills the given {@link RectF} with the path bounds.
+     * @param bounds the RectF to be filled.
+     */
+    private void fillBounds(RectF bounds) {
+        Rectangle2D rect = mPath.getBounds2D();
+        bounds.left = (float)rect.getMinX();
+        bounds.right = (float)rect.getMaxX();
+        bounds.top = (float)rect.getMinY();
+        bounds.bottom = (float)rect.getMaxY();
+    }
+
+    /**
+     * Set the beginning of the next contour to the point (x,y).
+     *
+     * @param x The x-coordinate of the start of a new contour
+     * @param y The y-coordinate of the start of a new contour
+     */
+    private void moveTo(float x, float y) {
+        mPath.moveTo(mLastX = x, mLastY = y);
+    }
+
+    /**
+     * Set the beginning of the next contour relative to the last point on the
+     * previous contour. If there is no previous contour, this is treated the
+     * same as moveTo().
+     *
+     * @param dx The amount to add to the x-coordinate of the end of the
+     *           previous contour, to specify the start of a new contour
+     * @param dy The amount to add to the y-coordinate of the end of the
+     *           previous contour, to specify the start of a new contour
+     */
+    private void rMoveTo(float dx, float dy) {
+        dx += mLastX;
+        dy += mLastY;
+        mPath.moveTo(mLastX = dx, mLastY = dy);
+    }
+
+    /**
+     * Add a line from the last point to the specified point (x,y).
+     * If no moveTo() call has been made for this contour, the first point is
+     * automatically set to (0,0).
+     *
+     * @param x The x-coordinate of the end of a line
+     * @param y The y-coordinate of the end of a line
+     */
+    private void lineTo(float x, float y) {
+        mPath.lineTo(mLastX = x, mLastY = y);
+    }
+
+    /**
+     * Same as lineTo, but the coordinates are considered relative to the last
+     * point on this contour. If there is no previous point, then a moveTo(0,0)
+     * is inserted automatically.
+     *
+     * @param dx The amount to add to the x-coordinate of the previous point on
+     *           this contour, to specify a line
+     * @param dy The amount to add to the y-coordinate of the previous point on
+     *           this contour, to specify a line
+     */
+    private void rLineTo(float dx, float dy) {
+        if (isEmpty()) {
+            mPath.moveTo(mLastX = 0, mLastY = 0);
+        }
+        dx += mLastX;
+        dy += mLastY;
+        mPath.lineTo(mLastX = dx, mLastY = dy);
+    }
+
+    /**
+     * Add a quadratic bezier from the last point, approaching control point
+     * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
+     * this contour, the first point is automatically set to (0,0).
+     *
+     * @param x1 The x-coordinate of the control point on a quadratic curve
+     * @param y1 The y-coordinate of the control point on a quadratic curve
+     * @param x2 The x-coordinate of the end point on a quadratic curve
+     * @param y2 The y-coordinate of the end point on a quadratic curve
+     */
+    private void quadTo(float x1, float y1, float x2, float y2) {
+        mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
+    }
+
+    /**
+     * Same as quadTo, but the coordinates are considered relative to the last
+     * point on this contour. If there is no previous point, then a moveTo(0,0)
+     * is inserted automatically.
+     *
+     * @param dx1 The amount to add to the x-coordinate of the last point on
+     *            this contour, for the control point of a quadratic curve
+     * @param dy1 The amount to add to the y-coordinate of the last point on
+     *            this contour, for the control point of a quadratic curve
+     * @param dx2 The amount to add to the x-coordinate of the last point on
+     *            this contour, for the end point of a quadratic curve
+     * @param dy2 The amount to add to the y-coordinate of the last point on
+     *            this contour, for the end point of a quadratic curve
+     */
+    private void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
+        if (isEmpty()) {
+            mPath.moveTo(mLastX = 0, mLastY = 0);
+        }
+        dx1 += mLastX;
+        dy1 += mLastY;
+        dx2 += mLastX;
+        dy2 += mLastY;
+        mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
+    }
+
+    /**
+     * Add a cubic bezier from the last point, approaching control points
+     * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
+     * made for this contour, the first point is automatically set to (0,0).
+     *
+     * @param x1 The x-coordinate of the 1st control point on a cubic curve
+     * @param y1 The y-coordinate of the 1st control point on a cubic curve
+     * @param x2 The x-coordinate of the 2nd control point on a cubic curve
+     * @param y2 The y-coordinate of the 2nd control point on a cubic curve
+     * @param x3 The x-coordinate of the end point on a cubic curve
+     * @param y3 The y-coordinate of the end point on a cubic curve
+     */
+    private void cubicTo(float x1, float y1, float x2, float y2,
+                        float x3, float y3) {
+        mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
+    }
+
+    /**
+     * Same as cubicTo, but the coordinates are considered relative to the
+     * current point on this contour. If there is no previous point, then a
+     * moveTo(0,0) is inserted automatically.
+     */
+    private void rCubicTo(float dx1, float dy1, float dx2, float dy2,
+                         float dx3, float dy3) {
+        if (isEmpty()) {
+            mPath.moveTo(mLastX = 0, mLastY = 0);
+        }
+        dx1 += mLastX;
+        dy1 += mLastY;
+        dx2 += mLastX;
+        dy2 += mLastY;
+        dx3 += mLastX;
+        dy3 += mLastY;
+        mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
+    }
+
+    /**
+     * Append the specified arc to the path as a new contour. If the start of
+     * the path is different from the path's current last point, then an
+     * automatic lineTo() is added to connect the current contour to the
+     * start of the arc. However, if the path is empty, then we call moveTo()
+     * with the first point of the arc. The sweep angle is tread mod 360.
+     *
+     * @param oval        The bounds of oval defining shape and size of the arc
+     * @param startAngle  Starting angle (in degrees) where the arc begins
+     * @param sweepAngle  Sweep angle (in degrees) measured clockwise, treated
+     *                    mod 360.
+     * @param forceMoveTo If true, always begin a new contour with the arc
+     */
+    private void arcTo(RectF oval, float startAngle, float sweepAngle,
+                      boolean forceMoveTo) {
+        Arc2D arc = new Arc2D.Float(oval.left, oval.top, oval.width(), oval.height(), startAngle,
+                sweepAngle, Arc2D.OPEN);
+        mPath.append(arc, true /*connect*/);
+
+        resetLastPointFromPath();
+    }
+
+    /**
+     * Close the current contour. If the current point is not equal to the
+     * first point of the contour, a line segment is automatically added.
+     */
+    private void close() {
+        mPath.closePath();
+    }
+
+    private void resetLastPointFromPath() {
+        Point2D last = mPath.getCurrentPoint();
+        mLastX = (float) last.getX();
+        mLastY = (float) last.getY();
+    }
+
+    /**
+     * Add a closed rectangle contour to the path
+     *
+     * @param left   The left side of a rectangle to add to the path
+     * @param top    The top of a rectangle to add to the path
+     * @param right  The right side of a rectangle to add to the path
+     * @param bottom The bottom of a rectangle to add to the path
+     * @param dir    The direction to wind the rectangle's contour
+     */
+    private void addRect(float left, float top, float right, float bottom,
+                        int dir) {
+        moveTo(left, top);
+
+        Direction direction = getDirection(dir);
+
+        switch (direction) {
+            case CW:
+                lineTo(right, top);
+                lineTo(right, bottom);
+                lineTo(left, bottom);
+                break;
+            case CCW:
+                lineTo(left, bottom);
+                lineTo(right, bottom);
+                lineTo(right, top);
+                break;
+        }
+
+        close();
+
+        resetLastPointFromPath();
+    }
+
+    /**
+     * Offset the path by (dx,dy), returning true on success
+     *
+     * @param dx  The amount in the X direction to offset the entire path
+     * @param dy  The amount in the Y direction to offset the entire path
+     * @param dst The translated path is written here. If this is null, then
+     *            the original path is modified.
+     */
+    public void offset(float dx, float dy, Path_Delegate dst) {
+        GeneralPath newPath = new GeneralPath();
+
+        PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
+
+        newPath.append(iterator, false /*connect*/);
+
+        if (dst != null) {
+            dst.mPath = newPath;
+        } else {
+            mPath = newPath;
+        }
+    }
+
+    /**
+     * Transform the points in this path by matrix, and write the answer
+     * into dst. If dst is null, then the the original path is modified.
+     *
+     * @param matrix The matrix to apply to the path
+     * @param dst    The transformed path is written here. If dst is null,
+     *               then the the original path is modified
+     */
+    public void transform(Matrix_Delegate matrix, Path_Delegate dst) {
+        if (matrix.hasPerspective()) {
+            assert false;
+            Bridge.getLog().fidelityWarning(null,
+                    "android.graphics.Path#transform() only " +
+                    "supports affine transformations in the Layout Preview.", null);
+        }
+
+        GeneralPath newPath = new GeneralPath();
+
+        PathIterator iterator = mPath.getPathIterator(matrix.getAffineTransform());
+
+        newPath.append(iterator, false /*connect*/);
+
+        if (dst != null) {
+            dst.mPath = newPath;
+        } else {
+            mPath = newPath;
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java
new file mode 100644
index 0000000..516a2b9
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java
@@ -0,0 +1,68 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import java.awt.Composite;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PixelXorXfermode
+ *
+ * Through the layoutlib_create tool, the original native methods of PixelXorXfermode have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PixelXorXfermode class.
+ *
+ * Because this extends {@link Xfermode_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
+ * {@link Xfermode_Delegate}.
+ *
+ * @see Xfermode_Delegate
+ */
+public class PixelXorXfermode_Delegate extends Xfermode_Delegate {
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Composite getComposite(int alpha) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Pixel XOR Xfermodes are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    /*package*/ static int nativeCreate(int opColor) {
+        PixelXorXfermode_Delegate newDelegate = new PixelXorXfermode_Delegate();
+        return sManager.addDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
index a5885ea..097dfce 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
@@ -16,8 +16,12 @@
 
 package android.graphics;
 
+import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 
+import java.awt.AlphaComposite;
+import java.awt.Composite;
+
 /**
  * Delegate implementing the native methods of android.graphics.PorterDuffXfermode
  *
@@ -41,8 +45,76 @@
 
     // ---- Public Helper methods ----
 
-    public int getMode() {
-        return mMode;
+    @Override
+    public Composite getComposite(int alpha) {
+        return getComposite(getPorterDuffMode(mMode), alpha);
+    }
+
+    @Override
+    public boolean isSupported() {
+        return true;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        // no message since isSupported returns true;
+        return null;
+    }
+
+    public static PorterDuff.Mode getPorterDuffMode(int mode) {
+        for (PorterDuff.Mode m : PorterDuff.Mode.values()) {
+            if (m.nativeInt == mode) {
+                return m;
+            }
+        }
+
+        Bridge.getLog().error(null, String.format("Unknown PorterDuff.Mode: %d", mode));
+        assert false;
+        return PorterDuff.Mode.SRC_OVER;
+    }
+
+    public static Composite getComposite(PorterDuff.Mode mode, int alpha) {
+        float falpha = alpha != 0xFF ? (float)alpha / 255.f : 1.f;
+        switch (mode) {
+            case CLEAR:
+                return AlphaComposite.getInstance(AlphaComposite.CLEAR, falpha);
+            case DARKEN:
+                break;
+            case DST:
+                return AlphaComposite.getInstance(AlphaComposite.DST, falpha);
+            case DST_ATOP:
+                return AlphaComposite.getInstance(AlphaComposite.DST_ATOP, falpha);
+            case DST_IN:
+                return AlphaComposite.getInstance(AlphaComposite.DST_IN, falpha);
+            case DST_OUT:
+                return AlphaComposite.getInstance(AlphaComposite.DST_OUT, falpha);
+            case DST_OVER:
+                return AlphaComposite.getInstance(AlphaComposite.DST_OVER, falpha);
+            case LIGHTEN:
+                break;
+            case MULTIPLY:
+                break;
+            case SCREEN:
+                break;
+            case SRC:
+                return AlphaComposite.getInstance(AlphaComposite.SRC, falpha);
+            case SRC_ATOP:
+                return AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, falpha);
+            case SRC_IN:
+                return AlphaComposite.getInstance(AlphaComposite.SRC_IN, falpha);
+            case SRC_OUT:
+                return AlphaComposite.getInstance(AlphaComposite.SRC_OUT, falpha);
+            case SRC_OVER:
+                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha);
+            case XOR:
+                return AlphaComposite.getInstance(AlphaComposite.XOR, falpha);
+        }
+
+        Bridge.getLog().fidelityWarning(null,
+                String.format("Unsupported PorterDuff Mode: %s", mode.name()),
+                null);
+
+        return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha);
     }
 
     // ---- native methods ----
@@ -57,5 +129,4 @@
     private PorterDuffXfermode_Delegate(int mode) {
         mMode = mode;
     }
-
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
index eebf378..1f6f4b4 100644
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -21,10 +21,6 @@
 
 import android.graphics.Shader.TileMode;
 
-import java.awt.Paint;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-
 /**
  * Delegate implementing the native methods of android.graphics.RadialGradient
  *
@@ -49,7 +45,7 @@
     // ---- Public Helper methods ----
 
     @Override
-    public Paint getJavaPaint() {
+    public java.awt.Paint getJavaPaint() {
         return mJavaPaint;
     }
 
@@ -57,17 +53,8 @@
 
     /*package*/ static int nativeCreate1(float x, float y, float radius,
             int colors[], float positions[], int tileMode) {
-        // figure out the tile
-        TileMode tile = null;
-        for (TileMode tm : TileMode.values()) {
-            if (tm.nativeInt == tileMode) {
-                tile = tm;
-                break;
-            }
-        }
-
         RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(x, y, radius,
-                colors, positions, tile);
+                colors, positions, Shader_Delegate.getTileMode(tileMode));
         return sManager.addDelegate(newDelegate);
     }
 
@@ -133,20 +120,20 @@
                 java.awt.RenderingHints       hints) {
             precomputeGradientColors();
 
-            AffineTransform canvasMatrix;
+            java.awt.geom.AffineTransform canvasMatrix;
             try {
                 canvasMatrix = xform.createInverse();
-            } catch (NoninvertibleTransformException e) {
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
                 Bridge.getLog().error(null, "Unable to inverse matrix in RadialGradient", e);
-                canvasMatrix = new AffineTransform();
+                canvasMatrix = new java.awt.geom.AffineTransform();
             }
 
-            AffineTransform localMatrix = getLocalMatrix();
+            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
             try {
                 localMatrix = localMatrix.createInverse();
-            } catch (NoninvertibleTransformException e) {
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
                 Bridge.getLog().error(null, "Unable to inverse matrix in RadialGradient", e);
-                localMatrix = new AffineTransform();
+                localMatrix = new java.awt.geom.AffineTransform();
             }
 
             return new RadialGradientPaintContext(canvasMatrix, localMatrix, colorModel);
@@ -154,12 +141,14 @@
 
         private class RadialGradientPaintContext implements java.awt.PaintContext {
 
-            private final AffineTransform mCanvasMatrix;
-            private final AffineTransform mLocalMatrix;
+            private final java.awt.geom.AffineTransform mCanvasMatrix;
+            private final java.awt.geom.AffineTransform mLocalMatrix;
             private final java.awt.image.ColorModel mColorModel;
 
-            public RadialGradientPaintContext(AffineTransform canvasMatrix,
-                    AffineTransform localMatrix, java.awt.image.ColorModel colorModel) {
+            public RadialGradientPaintContext(
+                    java.awt.geom.AffineTransform canvasMatrix,
+                    java.awt.geom.AffineTransform localMatrix,
+                    java.awt.image.ColorModel colorModel) {
                 mCanvasMatrix = canvasMatrix;
                 mLocalMatrix = localMatrix;
                 mColorModel = colorModel;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 7bf1443..3759b26 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -18,7 +18,7 @@
 
 import com.android.layoutlib.bridge.impl.DelegateManager;
 
-import java.awt.geom.AffineTransform;
+import android.graphics.Shader.TileMode;
 
 /**
  * Delegate implementing the native methods of android.graphics.Shader
@@ -52,7 +52,25 @@
         return sManager.getDelegate(nativeShader);
     }
 
+    /**
+     * Returns the {@link TileMode} matching the given int.
+     * @param tileMode the tile mode int value
+     * @return the TileMode enum.
+     */
+    public static TileMode getTileMode(int tileMode) {
+        for (TileMode tm : TileMode.values()) {
+            if (tm.nativeInt == tileMode) {
+                return tm;
+            }
+        }
+
+        assert false;
+        return TileMode.CLAMP;
+    }
+
     public abstract java.awt.Paint getJavaPaint();
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
 
     // ---- native methods ----
 
@@ -111,19 +129,19 @@
 
     // ---- Private delegate/helper methods ----
 
-    protected AffineTransform getLocalMatrix() {
+    protected java.awt.geom.AffineTransform getLocalMatrix() {
         Matrix_Delegate localMatrixDelegate = null;
         if (mLocalMatrix > 0) {
             localMatrixDelegate = Matrix_Delegate.getDelegate(mLocalMatrix);
             if (localMatrixDelegate == null) {
                 assert false;
-                return new AffineTransform();
+                return new java.awt.geom.AffineTransform();
             }
 
             return localMatrixDelegate.getAffineTransform();
         }
 
-        return new AffineTransform();
+        return new java.awt.geom.AffineTransform();
     }
 
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
new file mode 100644
index 0000000..b02f9c5
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
@@ -0,0 +1,69 @@
+/*
+ * 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 android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.SumPathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of SumPathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original SumPathEffect class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class SumPathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Sum Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    /*package*/ static int nativeCreate(int first, int second) {
+        SumPathEffect_Delegate newDelegate = new SumPathEffect_Delegate();
+        return sManager.addDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
index 97c3cfd..970e781 100644
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
@@ -19,10 +19,6 @@
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 
-import java.awt.Paint;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-
 /**
  * Delegate implementing the native methods of android.graphics.SweepGradient
  *
@@ -47,7 +43,7 @@
     // ---- Public Helper methods ----
 
     @Override
-    public Paint getJavaPaint() {
+    public java.awt.Paint getJavaPaint() {
         return mJavaPaint;
     }
 
@@ -116,20 +112,20 @@
                 java.awt.RenderingHints       hints) {
             precomputeGradientColors();
 
-            AffineTransform canvasMatrix;
+            java.awt.geom.AffineTransform canvasMatrix;
             try {
                 canvasMatrix = xform.createInverse();
-            } catch (NoninvertibleTransformException e) {
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
                 Bridge.getLog().error(null, "Unable to inverse matrix in SweepGradient", e);
-                canvasMatrix = new AffineTransform();
+                canvasMatrix = new java.awt.geom.AffineTransform();
             }
 
-            AffineTransform localMatrix = getLocalMatrix();
+            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
             try {
                 localMatrix = localMatrix.createInverse();
-            } catch (NoninvertibleTransformException e) {
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
                 Bridge.getLog().error(null, "Unable to inverse matrix in SweepGradient", e);
-                localMatrix = new AffineTransform();
+                localMatrix = new java.awt.geom.AffineTransform();
             }
 
             return new SweepGradientPaintContext(canvasMatrix, localMatrix, colorModel);
@@ -137,12 +133,14 @@
 
         private class SweepGradientPaintContext implements java.awt.PaintContext {
 
-            private final AffineTransform mCanvasMatrix;
-            private final AffineTransform mLocalMatrix;
+            private final java.awt.geom.AffineTransform mCanvasMatrix;
+            private final java.awt.geom.AffineTransform mLocalMatrix;
             private final java.awt.image.ColorModel mColorModel;
 
-            public SweepGradientPaintContext(AffineTransform canvasMatrix,
-                    AffineTransform localMatrix, java.awt.image.ColorModel colorModel) {
+            public SweepGradientPaintContext(
+                    java.awt.geom.AffineTransform canvasMatrix,
+                    java.awt.geom.AffineTransform localMatrix,
+                    java.awt.image.ColorModel colorModel) {
                 mCanvasMatrix = canvasMatrix;
                 mLocalMatrix = localMatrix;
                 mColorModel = colorModel;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
index 0c1170d..312318a 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
@@ -18,6 +18,8 @@
 
 import com.android.layoutlib.bridge.impl.DelegateManager;
 
+import java.awt.Composite;
+
 /**
  * Delegate implementing the native methods of android.graphics.Xfermode
  *
@@ -33,7 +35,7 @@
  * @see DelegateManager
  *
  */
-public class Xfermode_Delegate {
+public abstract class Xfermode_Delegate {
 
     // ---- delegate manager ----
     protected static final DelegateManager<Xfermode_Delegate> sManager =
@@ -49,6 +51,11 @@
         return sManager.getDelegate(native_instance);
     }
 
+    public abstract Composite getComposite(int alpha);
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
+
+
     // ---- native methods ----
 
     /*package*/ static void finalizer(int native_instance) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 9de6e8f..5f40854 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,15 +16,17 @@
 
 package com.android.layoutlib.bridge;
 
-import com.android.layoutlib.api.Capability;
-import com.android.layoutlib.api.LayoutBridge;
-import com.android.layoutlib.api.LayoutLog;
-import com.android.layoutlib.api.SceneParams;
-import com.android.layoutlib.api.SceneResult;
-import com.android.layoutlib.api.SceneResult.SceneStatus;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
+import com.android.ide.common.rendering.api.Capability;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.Params;
+import com.android.ide.common.rendering.api.RenderSession;
+import com.android.ide.common.rendering.api.Result;
 import com.android.layoutlib.bridge.android.BridgeAssetManager;
 import com.android.layoutlib.bridge.impl.FontLoader;
-import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
+import com.android.layoutlib.bridge.impl.RenderSessionImpl;
 import com.android.ninepatch.NinePatchChunk;
 import com.android.tools.layoutlib.create.MethodAdapter;
 import com.android.tools.layoutlib.create.OverrideMethod;
@@ -32,8 +34,8 @@
 import android.graphics.Bitmap;
 import android.graphics.Typeface_Delegate;
 import android.os.Looper;
-import android.util.Finalizers;
 
+import java.io.File;
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
@@ -48,7 +50,7 @@
  * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
  * {@link #createScene(SceneParams)}
  */
-public final class Bridge extends LayoutBridge {
+public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
 
     public static class StaticMethodNotImplementedException extends RuntimeException {
         private static final long serialVersionUID = 1L;
@@ -170,7 +172,7 @@
 
     @Override
     public int getApiLevel() {
-        return LayoutBridge.API_CURRENT;
+        return com.android.ide.common.rendering.api.Bridge.API_CURRENT;
     }
 
     @Override
@@ -180,10 +182,10 @@
 
     /*
      * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutLibBridge#init(java.lang.String, java.util.Map)
+     * @see com.android.layoutlib.api.ILayoutLibBridge#init(java.io.File, java.util.Map)
      */
     @Override
-    public boolean init(String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) {
+    public boolean init(File fontLocation, Map<String, Map<String, Integer>> enumValueMap) {
         sEnumValueMap = enumValueMap;
 
         // don't use EnumSet.allOf(), because the bridge doesn't come with its specific version
@@ -198,8 +200,6 @@
                 Capability.ANIMATE);
 
 
-        Finalizers.init();
-
         BridgeAssetManager.initSystem();
 
         // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
@@ -232,7 +232,7 @@
         }
 
         // load the fonts.
-        FontLoader fontLoader = FontLoader.create(fontOsLocation);
+        FontLoader fontLoader = FontLoader.create(fontLocation.getAbsolutePath());
         if (fontLoader != null) {
             Typeface_Delegate.init(fontLoader);
         } else {
@@ -302,10 +302,10 @@
      * @since 5
      */
     @Override
-    public BridgeLayoutScene createScene(SceneParams params) {
+    public RenderSession createSession(Params params) {
         try {
-            SceneResult lastResult = SceneStatus.SUCCESS.createResult();
-            LayoutSceneImpl scene = new LayoutSceneImpl(params);
+            Result lastResult = SUCCESS.createResult();
+            RenderSessionImpl scene = new RenderSessionImpl(params);
             try {
                 prepareThread();
                 lastResult = scene.init(params.getTimeout());
@@ -320,15 +320,15 @@
                 cleanupThread();
             }
 
-            return new BridgeLayoutScene(scene, lastResult);
+            return new BridgeRenderSession(scene, lastResult);
         } catch (Throwable t) {
             // get the real cause of the exception.
             Throwable t2 = t;
             while (t2.getCause() != null) {
                 t2 = t.getCause();
             }
-            return new BridgeLayoutScene(null,
-                    SceneStatus.ERROR_UNKNOWN.createResult(t2.getMessage(), t2));
+            return new BridgeRenderSession(null,
+                    ERROR_UNKNOWN.createResult(t2.getMessage(), t2));
         }
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
deleted file mode 100644
index f43559f..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.layoutlib.bridge;
-
-import com.android.layoutlib.api.IXmlPullParser;
-import com.android.layoutlib.api.LayoutScene;
-import com.android.layoutlib.api.SceneParams;
-import com.android.layoutlib.api.SceneResult;
-import com.android.layoutlib.api.ViewInfo;
-import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
-
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.awt.image.BufferedImage;
-import java.util.Map;
-
-/**
- * An implementation of {@link LayoutScene}.
- *
- * This is a pretty basic class that does almost nothing. All of the work is done in
- * {@link LayoutSceneImpl}.
- *
- */
-public class BridgeLayoutScene extends LayoutScene {
-
-    private final LayoutSceneImpl mScene;
-    private SceneResult mLastResult;
-
-    @Override
-    public SceneResult getResult() {
-        return mLastResult;
-    }
-
-    @Override
-    public BufferedImage getImage() {
-        return mScene.getImage();
-    }
-
-    @Override
-    public ViewInfo getRootView() {
-        return mScene.getViewInfo();
-    }
-
-    @Override
-    public Map<String, String> getDefaultViewPropertyValues(Object viewObject) {
-        return mScene.getDefaultViewPropertyValues(viewObject);
-    }
-
-    @Override
-    public SceneResult render(long timeout) {
-        try {
-            Bridge.prepareThread();
-            mLastResult = mScene.acquire(timeout);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mScene.render();
-            }
-        } finally {
-            mScene.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public SceneResult animate(Object targetObject, String animationName,
-            boolean isFrameworkAnimation, IAnimationListener listener) {
-        try {
-            Bridge.prepareThread();
-            mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mScene.animate(targetObject, animationName, isFrameworkAnimation,
-                        listener);
-            }
-        } finally {
-            mScene.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public SceneResult insertChild(Object parentView, IXmlPullParser childXml, int index,
-            IAnimationListener listener) {
-        if (parentView instanceof ViewGroup == false) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-
-        try {
-            Bridge.prepareThread();
-            mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mScene.insertChild((ViewGroup) parentView, childXml, index, listener);
-            }
-        } finally {
-            mScene.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-
-    @Override
-    public SceneResult moveChild(Object parentView, Object childView, int index,
-            Map<String, String> layoutParams, IAnimationListener listener) {
-        if (parentView instanceof ViewGroup == false) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-        if (childView instanceof View == false) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        try {
-            Bridge.prepareThread();
-            mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mScene.moveChild((ViewGroup) parentView, (View) childView, index,
-                        layoutParams, listener);
-            }
-        } finally {
-            mScene.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public SceneResult removeChild(Object childView, IAnimationListener listener) {
-        if (childView instanceof View == false) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        try {
-            Bridge.prepareThread();
-            mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
-            if (mLastResult.isSuccess()) {
-                mLastResult = mScene.removeChild((View) childView, listener);
-            }
-        } finally {
-            mScene.release();
-            Bridge.cleanupThread();
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public void dispose() {
-    }
-
-    /*package*/ BridgeLayoutScene(LayoutSceneImpl scene, SceneResult lastResult) {
-        mScene = scene;
-        mScene.setScene(this);
-        mLastResult = lastResult;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
new file mode 100644
index 0000000..a09524c
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
@@ -0,0 +1,175 @@
+/*
+ * 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.layoutlib.bridge;
+
+import com.android.ide.common.rendering.api.IAnimationListener;
+import com.android.ide.common.rendering.api.ILayoutPullParser;
+import com.android.ide.common.rendering.api.Params;
+import com.android.ide.common.rendering.api.RenderSession;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.ViewInfo;
+import com.android.layoutlib.bridge.impl.RenderSessionImpl;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.awt.image.BufferedImage;
+import java.util.Map;
+
+/**
+ * An implementation of {@link RenderSession}.
+ *
+ * This is a pretty basic class that does almost nothing. All of the work is done in
+ * {@link RenderSessionImpl}.
+ *
+ */
+public class BridgeRenderSession extends RenderSession {
+
+    private final RenderSessionImpl mSession;
+    private Result mLastResult;
+
+    @Override
+    public Result getResult() {
+        return mLastResult;
+    }
+
+    @Override
+    public BufferedImage getImage() {
+        return mSession.getImage();
+    }
+
+    @Override
+    public ViewInfo getRootView() {
+        return mSession.getViewInfo();
+    }
+
+    @Override
+    public Map<String, String> getDefaultProperties(Object viewObject) {
+        return mSession.getDefaultProperties(viewObject);
+    }
+
+    @Override
+    public Result render(long timeout) {
+        try {
+            Bridge.prepareThread();
+            mLastResult = mSession.acquire(timeout);
+            if (mLastResult.isSuccess()) {
+                mLastResult = mSession.render();
+            }
+        } finally {
+            mSession.release();
+            Bridge.cleanupThread();
+        }
+
+        return mLastResult;
+    }
+
+    @Override
+    public Result animate(Object targetObject, String animationName,
+            boolean isFrameworkAnimation, IAnimationListener listener) {
+        try {
+            Bridge.prepareThread();
+            mLastResult = mSession.acquire(Params.DEFAULT_TIMEOUT);
+            if (mLastResult.isSuccess()) {
+                mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
+                        listener);
+            }
+        } finally {
+            mSession.release();
+            Bridge.cleanupThread();
+        }
+
+        return mLastResult;
+    }
+
+    @Override
+    public Result insertChild(Object parentView, ILayoutPullParser childXml, int index,
+            IAnimationListener listener) {
+        if (parentView instanceof ViewGroup == false) {
+            throw new IllegalArgumentException("parentView is not a ViewGroup");
+        }
+
+        try {
+            Bridge.prepareThread();
+            mLastResult = mSession.acquire(Params.DEFAULT_TIMEOUT);
+            if (mLastResult.isSuccess()) {
+                mLastResult = mSession.insertChild((ViewGroup) parentView, childXml, index, listener);
+            }
+        } finally {
+            mSession.release();
+            Bridge.cleanupThread();
+        }
+
+        return mLastResult;
+    }
+
+
+    @Override
+    public Result moveChild(Object parentView, Object childView, int index,
+            Map<String, String> layoutParams, IAnimationListener listener) {
+        if (parentView instanceof ViewGroup == false) {
+            throw new IllegalArgumentException("parentView is not a ViewGroup");
+        }
+        if (childView instanceof View == false) {
+            throw new IllegalArgumentException("childView is not a View");
+        }
+
+        try {
+            Bridge.prepareThread();
+            mLastResult = mSession.acquire(Params.DEFAULT_TIMEOUT);
+            if (mLastResult.isSuccess()) {
+                mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
+                        layoutParams, listener);
+            }
+        } finally {
+            mSession.release();
+            Bridge.cleanupThread();
+        }
+
+        return mLastResult;
+    }
+
+    @Override
+    public Result removeChild(Object childView, IAnimationListener listener) {
+        if (childView instanceof View == false) {
+            throw new IllegalArgumentException("childView is not a View");
+        }
+
+        try {
+            Bridge.prepareThread();
+            mLastResult = mSession.acquire(Params.DEFAULT_TIMEOUT);
+            if (mLastResult.isSuccess()) {
+                mLastResult = mSession.removeChild((View) childView, listener);
+            }
+        } finally {
+            mSession.release();
+            Bridge.cleanupThread();
+        }
+
+        return mLastResult;
+    }
+
+    @Override
+    public void dispose() {
+    }
+
+    /*package*/ BridgeRenderSession(RenderSessionImpl scene, Result lastResult) {
+        mSession = scene;
+        mSession.setScene(this);
+        mLastResult = lastResult;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index f484e7a..7269227 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -16,9 +16,9 @@
 
 package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.ResourceValue;
-import com.android.layoutlib.api.StyleResourceValue;
+import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.StyleResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
 import com.android.layoutlib.bridge.impl.Stack;
@@ -105,11 +105,11 @@
      * @param themeName The name of the theme to use.
      * @param projectResources the resources of the project. The map contains (String, map) pairs
      * where the string is the type of the resource reference used in the layout file, and the
-     * map contains (String, {@link IResourceValue}) pairs where the key is the resource name,
+     * map contains (String, {@link }) pairs where the key is the resource name,
      * and the value is the resource value.
      * @param frameworkResources the framework resources. The map contains (String, map) pairs
      * where the string is the type of the resource reference used in the layout file, and the map
-     * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
+     * contains (String, {@link ResourceValue}) pairs where the key is the resource name, and the
      * value is the resource value.
      * @param styleInheritanceMap
      * @param projectCallback
@@ -321,7 +321,7 @@
 
             isPlatformFile = parser.isPlatformFile();
 
-            Object key = parser.getViewKey();
+            Object key = parser.getViewCookie();
             if (key != null) {
                 defaultPropMap = mDefaultPropMaps.get(key);
                 if (defaultPropMap == null) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
index dbf83e7..1b59621 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
@@ -16,8 +16,8 @@
 
 package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.ResourceValue;
+import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
 
@@ -217,14 +217,14 @@
                 BridgeXmlBlockParser parser = (BridgeXmlBlockParser) attrs;
 
                 // get the view key
-                Object viewKey = parser.getViewKey();
+                Object viewKey = parser.getViewCookie();
 
                 // if there's no view key and the depth is 1 (ie this is the first tag),
                 // look for a previous parser in the context, and check if this one has a viewkey.
                 if (viewKey == null && parser.getDepth() == 1) {
                     BridgeXmlBlockParser previousParser = bc.getPreviousParser();
                     if (previousParser != null) {
-                        viewKey = previousParser.getViewKey();
+                        viewKey = previousParser.getViewCookie();
                     }
                 }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
index c1e2046..2ea5281 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
@@ -16,8 +16,8 @@
 
 package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.ResourceValue;
+import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index fcbf5fa..6ae7e03 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -16,9 +16,9 @@
 
 package com.android.layoutlib.bridge.android;
 
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.StyleResourceValue;
 import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.api.ResourceValue;
-import com.android.layoutlib.api.StyleResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
@@ -66,7 +66,7 @@
     }
 
     /**
-     * Seals the array after all calls to {@link #bridgeSetValue(int, String, IResourceValue)} have
+     * Seals the array after all calls to {@link #bridgeSetValue(int, String, ResourceValue)} have
      * been done.
      * <p/>This allows to compute the list of non default values, permitting
      * {@link #getIndexCount()} to return the proper value.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
index 73bee96..38800da 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
@@ -16,7 +16,8 @@
 
 package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.api.IXmlPullParser;
+
+import com.android.ide.common.rendering.api.ILayoutPullParser;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -65,17 +66,17 @@
         return mPlatformFile;
     }
 
-    public IXmlPullParser getParser(String layoutName) {
-        if (mParser instanceof IXmlPullParser) {
-            return ((IXmlPullParser)mParser).getParser(layoutName);
+    public ILayoutPullParser getParser(String layoutName) {
+        if (mParser instanceof ILayoutPullParser) {
+            return ((ILayoutPullParser)mParser).getParser(layoutName);
         }
 
         return null;
     }
 
-    public Object getViewKey() {
-        if (mParser instanceof IXmlPullParser) {
-            return ((IXmlPullParser)mParser).getViewKey();
+    public Object getViewCookie() {
+        if (mParser instanceof ILayoutPullParser) {
+            return ((ILayoutPullParser)mParser).getViewCookie();
         }
 
         return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
index 92b98e5..ba45217 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.api.ResourceValue;
+import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java
index 4ee813c..1651d6a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java
@@ -16,10 +16,10 @@
 
 package com.android.layoutlib.bridge.impl;
 
-import com.android.layoutlib.api.LayoutScene;
-import com.android.layoutlib.api.SceneResult;
-import com.android.layoutlib.api.LayoutScene.IAnimationListener;
-import com.android.layoutlib.api.SceneResult.SceneStatus;
+import com.android.ide.common.rendering.api.IAnimationListener;
+import com.android.ide.common.rendering.api.RenderSession;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.Result.Status;
 import com.android.layoutlib.bridge.Bridge;
 
 import android.animation.ValueAnimator;
@@ -57,18 +57,19 @@
         }
     }
 
-    private final LayoutSceneImpl mScene;
+    private final RenderSessionImpl mSession;
 
     Queue<MessageBundle> mQueue = new LinkedList<MessageBundle>();
     private final IAnimationListener mListener;
 
-    public AnimationThread(LayoutSceneImpl scene, String threadName, IAnimationListener listener) {
+    public AnimationThread(RenderSessionImpl scene, String threadName,
+            IAnimationListener listener) {
         super(threadName);
-        mScene = scene;
+        mSession = scene;
         mListener = listener;
     }
 
-    public abstract SceneResult preAnimation();
+    public abstract Result preAnimation();
     public abstract void postAnimation();
 
     @Override
@@ -87,13 +88,13 @@
             });
 
             // call out to the pre-animation work, which should start an animation or more.
-            SceneResult result = preAnimation();
+            Result result = preAnimation();
             if (result.isSuccess() == false) {
                 mListener.done(result);
             }
 
             // loop the animation
-            LayoutScene scene = mScene.getScene();
+            RenderSession session = mSession.getSession();
             do {
                 // check early.
                 if (mListener.isCanceled()) {
@@ -123,7 +124,7 @@
                 }
 
                 // ready to do the work, acquire the scene.
-                result = mScene.acquire(250);
+                result = mSession.acquire(250);
                 if (result.isSuccess() == false) {
                     mListener.done(result);
                     return;
@@ -138,15 +139,15 @@
                     }
 
                     bundle.mTarget.handleMessage(bundle.mMessage);
-                    if (mScene.render().isSuccess()) {
-                        mListener.onNewFrame(scene);
+                    if (mSession.render().isSuccess()) {
+                        mListener.onNewFrame(session);
                     }
                 } finally {
-                    mScene.release();
+                    mSession.release();
                 }
             } while (mListener.isCanceled() == false && mQueue.size() > 0);
 
-            mListener.done(SceneStatus.SUCCESS.createResult());
+            mListener.done(Status.SUCCESS.createResult());
         } finally {
             postAnimation();
             Handler_Delegate.setCallback(null);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
index 2e2c5f4..35e5987 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
@@ -16,9 +16,9 @@
 
 package com.android.layoutlib.bridge.impl;
 
-import com.android.layoutlib.api.SceneResult;
-import com.android.layoutlib.api.LayoutScene.IAnimationListener;
-import com.android.layoutlib.api.SceneResult.SceneStatus;
+import com.android.ide.common.rendering.api.IAnimationListener;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.Result.Status;
 
 import android.animation.Animator;
 
@@ -26,19 +26,19 @@
 
     private final Animator mAnimator;
 
-    public PlayAnimationThread(Animator animator, LayoutSceneImpl scene, String animName,
+    public PlayAnimationThread(Animator animator, RenderSessionImpl scene, String animName,
             IAnimationListener listener) {
         super(scene, animName, listener);
         mAnimator = animator;
     }
 
     @Override
-    public SceneResult preAnimation() {
+    public Result preAnimation() {
         // start the animation. This will send a message to the handler right away, so
         // the queue is filled when this method returns.
         mAnimator.start();
 
-        return SceneStatus.SUCCESS.createResult();
+        return Status.SUCCESS.createResult();
     }
 
     @Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
similarity index 87%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 24cf380..5f86c92d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -16,24 +16,28 @@
 
 package com.android.layoutlib.bridge.impl;
 
-import static com.android.layoutlib.api.SceneResult.SceneStatus.ERROR_LOCK_INTERRUPTED;
-import static com.android.layoutlib.api.SceneResult.SceneStatus.ERROR_TIMEOUT;
-import static com.android.layoutlib.api.SceneResult.SceneStatus.SUCCESS;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
 
+import com.android.ide.common.rendering.api.IAnimationListener;
+import com.android.ide.common.rendering.api.ILayoutPullParser;
+import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.Params;
+import com.android.ide.common.rendering.api.RenderSession;
+import com.android.ide.common.rendering.api.ResourceDensity;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.StyleResourceValue;
+import com.android.ide.common.rendering.api.ViewInfo;
+import com.android.ide.common.rendering.api.Params.RenderingMode;
+import com.android.ide.common.rendering.api.Result.Status;
 import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.IXmlPullParser;
-import com.android.layoutlib.api.LayoutBridge;
-import com.android.layoutlib.api.LayoutScene;
-import com.android.layoutlib.api.ResourceDensity;
-import com.android.layoutlib.api.ResourceValue;
-import com.android.layoutlib.api.SceneParams;
-import com.android.layoutlib.api.SceneResult;
-import com.android.layoutlib.api.StyleResourceValue;
-import com.android.layoutlib.api.ViewInfo;
-import com.android.layoutlib.api.LayoutScene.IAnimationListener;
-import com.android.layoutlib.api.SceneParams.RenderingMode;
-import com.android.layoutlib.api.SceneResult.SceneStatus;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
 import com.android.layoutlib.bridge.android.BridgeContext;
@@ -75,14 +79,14 @@
 import java.util.concurrent.locks.ReentrantLock;
 
 /**
- * Class managing a layout "scene".
+ * Class implementing the render session.
  *
- * A scene is a stateful representation of a layout file. It is initialized with data coming through
- * the {@link LayoutBridge} API to inflate the layout. Further actions and rendering can then
+ * A session is a stateful representation of a layout file. It is initialized with data coming
+ * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then
  * be done on the layout.
  *
  */
-public class LayoutSceneImpl {
+public class RenderSessionImpl {
 
     private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
     private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
@@ -93,10 +97,10 @@
      */
     private static BridgeContext sCurrentContext = null;
 
-    private final SceneParams mParams;
+    private final Params mParams;
 
     // scene state
-    private LayoutScene mScene;
+    private RenderSession mScene;
     private BridgeContext mContext;
     private BridgeXmlBlockParser mBlockParser;
     private BridgeInflater mInflater;
@@ -123,14 +127,14 @@
     /**
      * Creates a layout scene with all the information coming from the layout bridge API.
      * <p>
-     * This <b>must</b> be followed by a call to {@link LayoutSceneImpl#init()}, which act as a
-     * call to {@link LayoutSceneImpl#acquire(long)}
+     * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init()}, which act as a
+     * call to {@link RenderSessionImpl#acquire(long)}
      *
      * @see LayoutBridge#createScene(com.android.layoutlib.api.SceneParams)
      */
-    public LayoutSceneImpl(SceneParams params) {
+    public RenderSessionImpl(Params params) {
         // copy the params.
-        mParams = new SceneParams(params);
+        mParams = new Params(params);
     }
 
     /**
@@ -144,10 +148,10 @@
      * @see #acquire(long)
      * @see #release()
      */
-    public SceneResult init(long timeout) {
+    public Result init(long timeout) {
         // acquire the lock. if the result is null, lock was just acquired, otherwise, return
         // the result.
-        SceneResult result = acquireLock(timeout);
+        Result result = acquireLock(timeout);
         if (result != null) {
             return result;
         }
@@ -168,7 +172,7 @@
         Map<StyleResourceValue, StyleResourceValue> styleParentMap =
             new HashMap<StyleResourceValue, StyleResourceValue>();
 
-        mCurrentTheme = computeStyleMaps(mParams.getThemeName(), mParams.getIsProjectTheme(),
+        mCurrentTheme = computeStyleMaps(mParams.getThemeName(), mParams.isProjectTheme(),
                 mParams.getProjectResources().get(BridgeConstants.RES_STYLE),
                 mParams.getFrameworkResources().get(BridgeConstants.RES_STYLE), styleParentMap);
 
@@ -187,7 +191,7 @@
         // get the screen offset and window-background resource
         mWindowBackground = null;
         mScreenOffset = 0;
-        if (mCurrentTheme != null && mParams.isCustomBackgroundEnabled() == false) {
+        if (mCurrentTheme != null && mParams.isBgColorOverridden() == false) {
             mWindowBackground = mContext.findItemInStyle(mCurrentTheme, "windowBackground");
             mWindowBackground = mContext.resolveResValue(mWindowBackground);
 
@@ -203,7 +207,7 @@
         mBlockParser = new BridgeXmlBlockParser(mParams.getLayoutDescription(),
                 mContext, false /* platformResourceFlag */);
 
-        return SceneStatus.SUCCESS.createResult();
+        return SUCCESS.createResult();
     }
 
     /**
@@ -215,7 +219,7 @@
      * The preparation can fail if another rendering took too long and the timeout was elapsed.
      *
      * More than one call to this from the same thread will have no effect and will return
-     * {@link SceneResult#SUCCESS}.
+     * {@link Result#SUCCESS}.
      *
      * After scene actions have taken place, only one call to {@link #release()} must be
      * done.
@@ -228,14 +232,14 @@
      *
      * @throws IllegalStateException if {@link #init(long)} was never called.
      */
-    public SceneResult acquire(long timeout) {
+    public Result acquire(long timeout) {
         if (mContext == null) {
             throw new IllegalStateException("After scene creation, #init() must be called");
         }
 
         // acquire the lock. if the result is null, lock was just acquired, otherwise, return
         // the result.
-        SceneResult result = acquireLock(timeout);
+        Result result = acquireLock(timeout);
         if (result != null) {
             return result;
         }
@@ -253,8 +257,8 @@
      * Acquire the lock so that the scene can be acted upon.
      * <p>
      * This returns null if the lock was just acquired, otherwise it returns
-     * {@link SceneResult#SUCCESS} if the lock already belonged to that thread, or another
-     * instance (see {@link SceneResult#getStatus()}) if an error occurred.
+     * {@link Result#SUCCESS} if the lock already belonged to that thread, or another
+     * instance (see {@link Result#getStatus()}) if an error occurred.
      *
      * @param timeout the time to wait if another rendering is happening.
      * @return null if the lock was just acquire or another result depending on the state.
@@ -262,7 +266,7 @@
      * @throws IllegalStateException if the current context is different than the one owned by
      *      the scene.
      */
-    private SceneResult acquireLock(long timeout) {
+    private Result acquireLock(long timeout) {
         ReentrantLock lock = Bridge.getLock();
         if (lock.isHeldByCurrentThread() == false) {
             try {
@@ -314,7 +318,7 @@
      * @throws IllegalStateException if the current context is different than the one owned by
      *      the scene, or if {@link #init(long)} was not called.
      */
-    public SceneResult inflate() {
+    public Result inflate() {
         checkLock();
 
         try {
@@ -347,9 +351,9 @@
                 mViewRoot.setBackgroundDrawable(d);
             }
 
-            return SceneStatus.SUCCESS.createResult();
+            return SUCCESS.createResult();
         } catch (PostInflateException e) {
-            return SceneStatus.ERROR_INFLATION.createResult(e.getMessage(), e);
+            return ERROR_INFLATION.createResult(e.getMessage(), e);
         } catch (Throwable e) {
             // get the real cause of the exception.
             Throwable t = e;
@@ -360,7 +364,7 @@
             // log it
             mParams.getLog().error("Scene inflate failed", t);
 
-            return SceneStatus.ERROR_INFLATION.createResult(t.getMessage(), t);
+            return ERROR_INFLATION.createResult(t.getMessage(), t);
         }
     }
 
@@ -375,12 +379,12 @@
      * @see SceneParams#getRenderingMode()
      * @see LayoutScene#render(long)
      */
-    public SceneResult render() {
+    public Result render() {
         checkLock();
 
         try {
             if (mViewRoot == null) {
-                return SceneStatus.ERROR_NOT_INFLATED.createResult();
+                return ERROR_NOT_INFLATED.createResult();
             }
             // measure the views
             int w_spec, h_spec;
@@ -443,9 +447,9 @@
                             mMeasuredScreenHeight - mScreenOffset, BufferedImage.TYPE_INT_ARGB);
                 }
 
-                if (mParams.isCustomBackgroundEnabled()) {
+                if (mParams.isBgColorOverridden()) {
                     Graphics2D gc = mImage.createGraphics();
-                    gc.setColor(new Color(mParams.getCustomBackgroundColor(), true));
+                    gc.setColor(new Color(mParams.getOverrideBgColor(), true));
                     gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight - mScreenOffset);
                     gc.dispose();
                 }
@@ -465,7 +469,7 @@
             mViewInfo = visit(((ViewGroup)mViewRoot).getChildAt(0), mContext);
 
             // success!
-            return SceneStatus.SUCCESS.createResult();
+            return SUCCESS.createResult();
         } catch (Throwable e) {
             // get the real cause of the exception.
             Throwable t = e;
@@ -476,7 +480,7 @@
             // log it
             mParams.getLog().error("Scene Render failed", t);
 
-            return SceneStatus.ERROR_UNKNOWN.createResult(t.getMessage(), t);
+            return ERROR_UNKNOWN.createResult(t.getMessage(), t);
         }
     }
 
@@ -490,7 +494,7 @@
      *
      * @see LayoutScene#animate(Object, String, boolean, IAnimationListener)
      */
-    public SceneResult animate(Object targetObject, String animationName,
+    public Result animate(Object targetObject, String animationName,
             boolean isFrameworkAnimation, IAnimationListener listener) {
         checkLock();
 
@@ -517,7 +521,7 @@
 
                     new PlayAnimationThread(anim, this, animationName, listener).start();
 
-                    return SceneStatus.SUCCESS.createResult();
+                    return SUCCESS.createResult();
                 }
             } catch (Exception e) {
                 // get the real cause of the exception.
@@ -526,11 +530,11 @@
                     t = t.getCause();
                 }
 
-                return SceneStatus.ERROR_UNKNOWN.createResult(t.getMessage(), t);
+                return ERROR_UNKNOWN.createResult(t.getMessage(), t);
             }
         }
 
-        return SceneStatus.ERROR_ANIM_NOT_FOUND.createResult();
+        return ERROR_ANIM_NOT_FOUND.createResult();
     }
 
     /**
@@ -541,9 +545,9 @@
      * @throws IllegalStateException if the current context is different than the one owned by
      *      the scene, or if {@link #acquire(long)} was not called.
      *
-     * @see LayoutScene#insertChild(Object, IXmlPullParser, int, IAnimationListener)
+     * @see LayoutScene#insertChild(Object, ILayoutPullParser, int, IAnimationListener)
      */
-    public SceneResult insertChild(final ViewGroup parentView, IXmlPullParser childXml,
+    public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml,
             final int index, IAnimationListener listener) {
         checkLock();
 
@@ -562,7 +566,7 @@
             new AnimationThread(this, "insertChild", listener) {
 
                 @Override
-                public SceneResult preAnimation() {
+                public Result preAnimation() {
                     parentView.setLayoutTransition(new LayoutTransition());
                     return addView(parentView, child, index);
                 }
@@ -574,11 +578,11 @@
             }.start();
 
             // always return success since the real status will come through the listener.
-            return SceneStatus.SUCCESS.createResult(child);
+            return SUCCESS.createResult(child);
         }
 
         // add it to the parentView in the correct location
-        SceneResult result = addView(parentView, child, index);
+        Result result = addView(parentView, child, index);
         if (result.isSuccess() == false) {
             return result;
         }
@@ -598,17 +602,17 @@
      * @param view the view to add to the parent
      * @param index the index where to do the add.
      *
-     * @return a SceneResult with {@link SceneStatus#SUCCESS} or
-     *     {@link SceneStatus#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
+     * @return a Result with {@link Status#SUCCESS} or
+     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
      *     adding views.
      */
-    private SceneResult addView(ViewGroup parent, View view, int index) {
+    private Result addView(ViewGroup parent, View view, int index) {
         try {
             parent.addView(view, index);
-            return SceneStatus.SUCCESS.createResult();
+            return SUCCESS.createResult();
         } catch (UnsupportedOperationException e) {
             // looks like this is a view class that doesn't support children manipulation!
-            return SceneStatus.ERROR_VIEWGROUP_NO_CHILDREN.createResult();
+            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
         }
     }
 
@@ -622,7 +626,7 @@
      *
      * @see LayoutScene#moveChild(Object, Object, int, Map, IAnimationListener)
      */
-    public SceneResult moveChild(final ViewGroup parentView, final View childView, final int index,
+    public Result moveChild(final ViewGroup parentView, final View childView, final int index,
             Map<String, String> layoutParamsMap, IAnimationListener listener) {
         checkLock();
 
@@ -640,7 +644,7 @@
             new AnimationThread(this, "moveChild", listener) {
 
                 @Override
-                public SceneResult preAnimation() {
+                public Result preAnimation() {
                     parentView.setLayoutTransition(new LayoutTransition());
                     return moveView(parentView, childView, index, params);
                 }
@@ -652,10 +656,10 @@
             }.start();
 
             // always return success since the real status will come through the listener.
-            return SceneStatus.SUCCESS.createResult(layoutParams);
+            return SUCCESS.createResult(layoutParams);
         }
 
-        SceneResult result = moveView(parentView, childView, index, layoutParams);
+        Result result = moveView(parentView, childView, index, layoutParams);
         if (result.isSuccess() == false) {
             return result;
         }
@@ -677,11 +681,11 @@
      * @param index the new location in the new parent
      * @param params an option (can be null) {@link LayoutParams} instance.
      *
-     * @return a SceneResult with {@link SceneStatus#SUCCESS} or
-     *     {@link SceneStatus#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
+     * @return a Result with {@link Status#SUCCESS} or
+     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
      *     adding views.
      */
-    private SceneResult moveView(ViewGroup parent, View view, int index, LayoutParams params) {
+    private Result moveView(ViewGroup parent, View view, int index, LayoutParams params) {
         try {
             ViewGroup previousParent = (ViewGroup) view.getParent();
             previousParent.removeView(view);
@@ -694,10 +698,10 @@
                 parent.addView(view, index);
             }
 
-            return SceneStatus.SUCCESS.createResult();
+            return SUCCESS.createResult();
         } catch (UnsupportedOperationException e) {
             // looks like this is a view class that doesn't support children manipulation!
-            return SceneStatus.ERROR_VIEWGROUP_NO_CHILDREN.createResult();
+            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
         }
     }
 
@@ -711,7 +715,7 @@
      *
      * @see LayoutScene#removeChild(Object, IAnimationListener)
      */
-    public SceneResult removeChild(final View childView, IAnimationListener listener) {
+    public Result removeChild(final View childView, IAnimationListener listener) {
         checkLock();
 
         invalidateRenderingSize();
@@ -722,7 +726,7 @@
             new AnimationThread(this, "moveChild", listener) {
 
                 @Override
-                public SceneResult preAnimation() {
+                public Result preAnimation() {
                     parent.setLayoutTransition(new LayoutTransition());
                     return removeView(parent, childView);
                 }
@@ -734,10 +738,10 @@
             }.start();
 
             // always return success since the real status will come through the listener.
-            return SceneStatus.SUCCESS.createResult();
+            return SUCCESS.createResult();
         }
 
-        SceneResult result = removeView(parent, childView);
+        Result result = removeView(parent, childView);
         if (result.isSuccess() == false) {
             return result;
         }
@@ -750,17 +754,17 @@
      *
      * @param view the view to remove from its parent
      *
-     * @return a SceneResult with {@link SceneStatus#SUCCESS} or
-     *     {@link SceneStatus#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
+     * @return a Result with {@link Status#SUCCESS} or
+     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
      *     adding views.
      */
-    private SceneResult removeView(ViewGroup parent, View view) {
+    private Result removeView(ViewGroup parent, View view) {
         try {
             parent.removeView(view);
-            return SceneStatus.SUCCESS.createResult();
+            return SUCCESS.createResult();
         } catch (UnsupportedOperationException e) {
             // looks like this is a view class that doesn't support children manipulation!
-            return SceneStatus.ERROR_VIEWGROUP_NO_CHILDREN.createResult();
+            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
         }
     }
 
@@ -791,7 +795,7 @@
      * @param inProjectStyleMap the project style map
      * @param inFrameworkStyleMap the framework style map
      * @param outInheritanceMap the map of style inheritance. This is filled by the method
-     * @return the {@link IStyleResourceValue} matching <var>themeName</var>
+     * @return the {@link StyleResourceValue} matching <var>themeName</var>
      */
     private StyleResourceValue computeStyleMaps(
             String themeName, boolean isProjectTheme, Map<String,
@@ -865,7 +869,7 @@
     }
 
     /**
-     * Searches for and returns the {@link IStyleResourceValue} from a given name.
+     * Searches for and returns the {@link StyleResourceValue} from a given name.
      * <p/>The format of the name can be:
      * <ul>
      * <li>[android:]&lt;name&gt;</li>
@@ -875,7 +879,7 @@
      * @param parentName the name of the style.
      * @param inProjectStyleMap the project style map. Can be <code>null</code>
      * @param inFrameworkStyleMap the framework style map.
-     * @return The matching {@link IStyleResourceValue} object or <code>null</code> if not found.
+     * @return The matching {@link StyleResourceValue} object or <code>null</code> if not found.
      */
     private StyleResourceValue getStyle(String parentName,
             Map<String, ResourceValue> inProjectStyleMap,
@@ -1143,15 +1147,15 @@
         return mViewInfo;
     }
 
-    public Map<String, String> getDefaultViewPropertyValues(Object viewObject) {
+    public Map<String, String> getDefaultProperties(Object viewObject) {
         return mContext.getDefaultPropMap(viewObject);
     }
 
-    public void setScene(LayoutScene scene) {
-        mScene = scene;
+    public void setScene(RenderSession session) {
+        mScene = session;
     }
 
-    public LayoutScene getScene() {
+    public RenderSession getSession() {
         return mScene;
     }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index f03931f..5427f142 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -16,9 +16,9 @@
 
 package com.android.layoutlib.bridge.impl;
 
-import com.android.layoutlib.api.DensityBasedResourceValue;
-import com.android.layoutlib.api.ResourceDensity;
-import com.android.layoutlib.api.ResourceValue;
+import com.android.ide.common.rendering.api.DensityBasedResourceValue;
+import com.android.ide.common.rendering.api.ResourceDensity;
+import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 1d40d33..baa4f06 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -106,17 +106,27 @@
      */
     private final static String[] DELEGATE_CLASS_NATIVES = new String[] {
         "android.animation.PropertyValuesHolder",
+        "android.graphics.AvoidXfermode",
         "android.graphics.Bitmap",
+        "android.graphics.BitmapShader",
         "android.graphics.Canvas",
+        "android.graphics.ComposePathEffect",
+        "android.graphics.ComposeShader",
+        "android.graphics.CornerPathEffect",
         "android.graphics.DashPathEffect",
+        "android.graphics.DiscretePathEffect",
         "android.graphics.LinearGradient",
         "android.graphics.Matrix",
         "android.graphics.NinePatch",
         "android.graphics.Paint",
+        "android.graphics.Path",
+        "android.graphics.PathDashPathEffect",
         "android.graphics.PathEffect",
+        "android.graphics.PixelXorXfermode",
         "android.graphics.PorterDuffXfermode",
         "android.graphics.RadialGradient",
         "android.graphics.Shader",
+        "android.graphics.SumPathEffect",
         "android.graphics.SweepGradient",
         "android.graphics.Typeface",
         "android.graphics.Xfermode",
@@ -140,7 +150,6 @@
     private final static String[] RENAMED_CLASSES =
         new String[] {
             "android.graphics.BitmapFactory",       "android.graphics._Original_BitmapFactory",
-            "android.graphics.Path",                "android.graphics._Original_Path",
             "android.os.ServiceManager",            "android.os._Original_ServiceManager",
             "android.view.SurfaceView",             "android.view._Original_SurfaceView",
             "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
diff --git a/voip/java/android/net/sip/SipAudioCall.java b/voip/java/android/net/sip/SipAudioCall.java
index 51236fe..ce18ec5 100644
--- a/voip/java/android/net/sip/SipAudioCall.java
+++ b/voip/java/android/net/sip/SipAudioCall.java
@@ -519,10 +519,15 @@
      * @param session the session that receives the incoming call
      * @param sessionDescription the session description of the incoming call
      * @throws SipException if the SIP service fails to attach this object to
-     *        the session
+     *        the session or VOIP API is not supported by the device
+     * @see SipManager#isVoipSupported
      */
     public void attachCall(SipSession session, String sessionDescription)
             throws SipException {
+        if (!SipManager.isVoipSupported(mContext)) {
+            throw new SipException("VOIP API is not supported");
+        }
+
         synchronized (this) {
             mSipSession = session;
             mPeerSd = sessionDescription;
@@ -548,10 +553,15 @@
      *        SIP protocol) is used if {@code timeout} is zero or negative.
      * @see Listener#onError
      * @throws SipException if the SIP service fails to create a session for the
-     *        call
+     *        call or VOIP API is not supported by the device
+     * @see SipManager#isVoipSupported
      */
     public void makeCall(SipProfile peerProfile, SipSession sipSession,
             int timeout) throws SipException {
+        if (!SipManager.isVoipSupported(mContext)) {
+            throw new SipException("VOIP API is not supported");
+        }
+
         synchronized (this) {
             mSipSession = sipSession;
             try {
@@ -595,6 +605,9 @@
     public void holdCall(int timeout) throws SipException {
         synchronized (this) {
             if (mHold) return;
+            if (mSipSession == null) {
+                throw new SipException("Not in a call to hold call");
+            }
             mSipSession.changeCall(createHoldOffer().encode(), timeout);
             mHold = true;
             setAudioGroupMode();
@@ -614,6 +627,9 @@
      */
     public void answerCall(int timeout) throws SipException {
         synchronized (this) {
+            if (mSipSession == null) {
+                throw new SipException("No call to answer");
+            }
             try {
                 mAudioStream = new AudioStream(InetAddress.getByName(
                         getLocalIp()));
diff --git a/voip/java/android/net/sip/SipManager.java b/voip/java/android/net/sip/SipManager.java
index 2e386620..dce46fe 100644
--- a/voip/java/android/net/sip/SipManager.java
+++ b/voip/java/android/net/sip/SipManager.java
@@ -133,7 +133,7 @@
     }
 
     /**
-     * Returns true if the system supports SIP-based VoIP.
+     * Returns true if the system supports SIP-based VOIP API.
      */
     public static boolean isVoipSupported(Context context) {
         return context.getPackageManager().hasSystemFeature(
@@ -305,12 +305,17 @@
      * @param timeout the timeout value in seconds. Default value (defined by
      *        SIP protocol) is used if {@code timeout} is zero or negative.
      * @return a {@link SipAudioCall} object
-     * @throws SipException if calling the SIP service results in an error
+     * @throws SipException if calling the SIP service results in an error or
+     *      VOIP API is not supported by the device
      * @see SipAudioCall.Listener#onError
+     * @see #isVoipSupported
      */
     public SipAudioCall makeAudioCall(SipProfile localProfile,
             SipProfile peerProfile, SipAudioCall.Listener listener, int timeout)
             throws SipException {
+        if (!isVoipSupported(mContext)) {
+            throw new SipException("VOIP API is not supported");
+        }
         SipAudioCall call = new SipAudioCall(mContext, localProfile);
         call.setListener(listener);
         SipSession s = createSipSession(localProfile, null);
@@ -332,12 +337,17 @@
      * @param timeout the timeout value in seconds. Default value (defined by
      *        SIP protocol) is used if {@code timeout} is zero or negative.
      * @return a {@link SipAudioCall} object
-     * @throws SipException if calling the SIP service results in an error
+     * @throws SipException if calling the SIP service results in an error or
+     *      VOIP API is not supported by the device
      * @see SipAudioCall.Listener#onError
+     * @see #isVoipSupported
      */
     public SipAudioCall makeAudioCall(String localProfileUri,
             String peerProfileUri, SipAudioCall.Listener listener, int timeout)
             throws SipException {
+        if (!isVoipSupported(mContext)) {
+            throw new SipException("VOIP API is not supported");
+        }
         try {
             return makeAudioCall(
                     new SipProfile.Builder(localProfileUri).build(),