Rename several animation classes

Change-Id: I6a4544875090db485163c8d56de8718f56d267c7
diff --git a/api/current.xml b/api/current.xml
index d393930..b43a8c2 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -19810,7 +19810,7 @@
 </package>
 <package name="android.animation"
 >
-<class name="Animatable"
+<class name="Animator"
  extends="java.lang.Object"
  abstract="true"
  static="false"
@@ -19820,8 +19820,8 @@
 >
 <implements name="java.lang.Cloneable">
 </implements>
-<constructor name="Animatable"
- type="android.animation.Animatable"
+<constructor name="Animator"
+ type="android.animation.Animator"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -19838,7 +19838,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="listener" type="android.animation.Animatable.AnimatableListener">
+<parameter name="listener" type="android.animation.Animator.AnimatorListener">
 </parameter>
 </method>
 <method name="cancel"
@@ -19853,7 +19853,7 @@
 >
 </method>
 <method name="clone"
- return="android.animation.Animatable"
+ return="android.animation.Animator"
  abstract="false"
  native="false"
  synchronized="false"
@@ -19886,7 +19886,7 @@
 >
 </method>
 <method name="getListeners"
- return="java.util.ArrayList&lt;android.animation.Animatable.AnimatableListener&gt;"
+ return="java.util.ArrayList&lt;android.animation.Animator.AnimatorListener&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -19939,7 +19939,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="listener" type="android.animation.Animatable.AnimatableListener">
+<parameter name="listener" type="android.animation.Animator.AnimatorListener">
 </parameter>
 </method>
 <method name="setDuration"
@@ -20028,7 +20028,7 @@
 >
 </method>
 </class>
-<interface name="Animatable.AnimatableListener"
+<interface name="Animator.AnimatorListener"
  abstract="true"
  static="true"
  final="false"
@@ -20045,7 +20045,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="animation" type="android.animation.Animatable">
+<parameter name="animation" type="android.animation.Animator">
 </parameter>
 </method>
 <method name="onAnimationEnd"
@@ -20058,7 +20058,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="animation" type="android.animation.Animatable">
+<parameter name="animation" type="android.animation.Animator">
 </parameter>
 </method>
 <method name="onAnimationRepeat"
@@ -20071,7 +20071,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="animation" type="android.animation.Animatable">
+<parameter name="animation" type="android.animation.Animator">
 </parameter>
 </method>
 <method name="onAnimationStart"
@@ -20084,11 +20084,11 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="animation" type="android.animation.Animatable">
+<parameter name="animation" type="android.animation.Animator">
 </parameter>
 </method>
 </interface>
-<class name="AnimatableInflater"
+<class name="AnimatorInflater"
  extends="java.lang.Object"
  abstract="false"
  static="false"
@@ -20096,16 +20096,16 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="AnimatableInflater"
- type="android.animation.AnimatableInflater"
+<constructor name="AnimatorInflater"
+ type="android.animation.AnimatorInflater"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
 </constructor>
-<method name="loadAnimatable"
- return="android.animation.Animatable"
+<method name="loadAnimator"
+ return="android.animation.Animator"
  abstract="false"
  native="false"
  synchronized="false"
@@ -20122,7 +20122,7 @@
 </exception>
 </method>
 </class>
-<class name="AnimatableListenerAdapter"
+<class name="AnimatorListenerAdapter"
  extends="java.lang.Object"
  abstract="true"
  static="false"
@@ -20130,10 +20130,10 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<implements name="android.animation.Animatable.AnimatableListener">
+<implements name="android.animation.Animator.AnimatorListener">
 </implements>
-<constructor name="AnimatableListenerAdapter"
- type="android.animation.AnimatableListenerAdapter"
+<constructor name="AnimatorListenerAdapter"
+ type="android.animation.AnimatorListenerAdapter"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -20150,7 +20150,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="animation" type="android.animation.Animatable">
+<parameter name="animation" type="android.animation.Animator">
 </parameter>
 </method>
 <method name="onAnimationEnd"
@@ -20163,7 +20163,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="animation" type="android.animation.Animatable">
+<parameter name="animation" type="android.animation.Animator">
 </parameter>
 </method>
 <method name="onAnimationRepeat"
@@ -20176,7 +20176,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="animation" type="android.animation.Animatable">
+<parameter name="animation" type="android.animation.Animator">
 </parameter>
 </method>
 <method name="onAnimationStart"
@@ -20189,77 +20189,28 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="animation" type="android.animation.Animatable">
+<parameter name="animation" type="android.animation.Animator">
 </parameter>
 </method>
 </class>
-<class name="Animator"
- extends="android.animation.Animatable"
+<class name="AnimatorSet"
+ extends="android.animation.Animator"
  abstract="false"
  static="false"
- final="false"
+ final="true"
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="Animator"
- type="android.animation.Animator"
+<constructor name="AnimatorSet"
+ type="android.animation.AnimatorSet"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
 </constructor>
-<constructor name="Animator"
- type="android.animation.Animator"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="duration" type="long">
-</parameter>
-<parameter name="values" type="T...">
-</parameter>
-</constructor>
-<method name="addUpdateListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.animation.Animator.AnimatorUpdateListener">
-</parameter>
-</method>
-<method name="getAnimatedValue"
- return="java.lang.Object"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getAnimatedValue"
- return="java.lang.Object"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="propertyName" type="java.lang.String">
-</parameter>
-</method>
-<method name="getCurrentPlayTime"
- return="long"
+<method name="getChildAnimations"
+ return="java.util.ArrayList&lt;android.animation.Animator&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -20280,50 +20231,6 @@
  visibility="public"
 >
 </method>
-<method name="getFrameDelay"
- return="long"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getInterpolator"
- return="android.view.animation.Interpolator"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getRepeatCount"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getRepeatMode"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="getStartDelay"
  return="long"
  abstract="false"
@@ -20335,17 +20242,6 @@
  visibility="public"
 >
 </method>
-<method name="getValues"
- return="android.animation.PropertyValuesHolder[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="isRunning"
  return="boolean"
  abstract="false"
@@ -20357,8 +20253,8 @@
  visibility="public"
 >
 </method>
-<method name="removeUpdateListener"
- return="void"
+<method name="play"
+ return="android.animation.AnimatorSet.Builder"
  abstract="false"
  native="false"
  synchronized="false"
@@ -20367,10 +20263,10 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="listener" type="android.animation.Animator.AnimatorUpdateListener">
+<parameter name="anim" type="android.animation.Animator">
 </parameter>
 </method>
-<method name="reverse"
+<method name="playSequentially"
  return="void"
  abstract="false"
  native="false"
@@ -20380,8 +20276,10 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="items" type="android.animation.Animator...">
+</parameter>
 </method>
-<method name="setCurrentPlayTime"
+<method name="playTogether"
  return="void"
  abstract="false"
  native="false"
@@ -20391,7 +20289,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="playTime" type="long">
+<parameter name="items" type="android.animation.Animator...">
 </parameter>
 </method>
 <method name="setDuration"
@@ -20407,32 +20305,6 @@
 <parameter name="duration" type="long">
 </parameter>
 </method>
-<method name="setEvaluator"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="value" type="android.animation.TypeEvaluator">
-</parameter>
-</method>
-<method name="setFrameDelay"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="frameDelay" type="long">
-</parameter>
-</method>
 <method name="setInterpolator"
  return="void"
  abstract="false"
@@ -20443,33 +20315,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="value" type="android.view.animation.Interpolator">
-</parameter>
-</method>
-<method name="setRepeatCount"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="value" type="int">
-</parameter>
-</method>
-<method name="setRepeatMode"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="value" type="int">
+<parameter name="interpolator" type="android.view.animation.Interpolator">
 </parameter>
 </method>
 <method name="setStartDelay"
@@ -20485,76 +20331,18 @@
 <parameter name="startDelay" type="long">
 </parameter>
 </method>
-<method name="setValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="android.animation.PropertyValuesHolder...">
-</parameter>
-</method>
-<method name="setValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="T...">
-</parameter>
-</method>
-<field name="INFINITE"
- type="int"
- transient="false"
- volatile="false"
- value="-1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="RESTART"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="REVERSE"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 </class>
-<interface name="Animator.AnimatorUpdateListener"
- abstract="true"
- static="true"
+<class name="AnimatorSet.Builder"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<method name="onAnimationUpdate"
+<method name="after"
  return="void"
- abstract="true"
+ abstract="false"
  native="false"
  synchronized="false"
  static="false"
@@ -20562,10 +20350,49 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="animation" type="android.animation.Animator">
+<parameter name="anim" type="android.animation.Animator">
 </parameter>
 </method>
-</interface>
+<method name="after"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="delay" type="long">
+</parameter>
+</method>
+<method name="before"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="anim" type="android.animation.Animator">
+</parameter>
+</method>
+<method name="with"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="anim" type="android.animation.Animator">
+</parameter>
+</method>
+</class>
 <class name="DoubleEvaluator"
  extends="java.lang.Object"
  abstract="false"
@@ -20922,8 +20749,8 @@
 <parameter name="child" type="android.view.View">
 </parameter>
 </method>
-<method name="getAnimatable"
- return="android.animation.Animatable"
+<method name="getAnimator"
+ return="android.animation.Animator"
  abstract="false"
  native="false"
  synchronized="false"
@@ -21011,7 +20838,7 @@
 <parameter name="listener" type="android.animation.LayoutTransition.TransitionListener">
 </parameter>
 </method>
-<method name="setAnimatable"
+<method name="setAnimator"
  return="void"
  abstract="false"
  native="false"
@@ -21023,7 +20850,7 @@
 >
 <parameter name="transitionType" type="int">
 </parameter>
-<parameter name="animatable" type="android.animation.Animatable">
+<parameter name="animator" type="android.animation.Animator">
 </parameter>
 </method>
 <method name="setDuration"
@@ -21190,24 +21017,24 @@
 </parameter>
 </method>
 </interface>
-<class name="PropertyAnimator"
- extends="android.animation.Animator"
+<class name="ObjectAnimator"
+ extends="android.animation.ValueAnimator"
  abstract="false"
  static="false"
  final="true"
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="PropertyAnimator"
- type="android.animation.PropertyAnimator"
+<constructor name="ObjectAnimator"
+ type="android.animation.ObjectAnimator"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
 </constructor>
-<constructor name="PropertyAnimator"
- type="android.animation.PropertyAnimator"
+<constructor name="ObjectAnimator"
+ type="android.animation.ObjectAnimator"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -21222,8 +21049,8 @@
 <parameter name="values" type="T...">
 </parameter>
 </constructor>
-<constructor name="PropertyAnimator"
- type="android.animation.PropertyAnimator"
+<constructor name="ObjectAnimator"
+ type="android.animation.ObjectAnimator"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -21450,206 +21277,6 @@
 </parameter>
 </method>
 </class>
-<class name="Sequencer"
- extends="android.animation.Animatable"
- abstract="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="Sequencer"
- type="android.animation.Sequencer"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="getChildAnimations"
- return="java.util.ArrayList&lt;android.animation.Animatable&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getDuration"
- return="long"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getStartDelay"
- return="long"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="isRunning"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="play"
- return="android.animation.Sequencer.Builder"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="anim" type="android.animation.Animatable">
-</parameter>
-</method>
-<method name="playSequentially"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="sequenceItems" type="android.animation.Animatable...">
-</parameter>
-</method>
-<method name="playTogether"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="sequenceItems" type="android.animation.Animatable...">
-</parameter>
-</method>
-<method name="setDuration"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="duration" type="long">
-</parameter>
-</method>
-<method name="setInterpolator"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="interpolator" type="android.view.animation.Interpolator">
-</parameter>
-</method>
-<method name="setStartDelay"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="startDelay" type="long">
-</parameter>
-</method>
-</class>
-<class name="Sequencer.Builder"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="after"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="anim" type="android.animation.Animatable">
-</parameter>
-</method>
-<method name="after"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="delay" type="long">
-</parameter>
-</method>
-<method name="before"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="anim" type="android.animation.Animatable">
-</parameter>
-</method>
-<method name="with"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="anim" type="android.animation.Animatable">
-</parameter>
-</method>
-</class>
 <interface name="TypeEvaluator"
  abstract="true"
  static="false"
@@ -21675,6 +21302,379 @@
 </parameter>
 </method>
 </interface>
+<class name="ValueAnimator"
+ extends="android.animation.Animator"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="ValueAnimator"
+ type="android.animation.ValueAnimator"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<constructor name="ValueAnimator"
+ type="android.animation.ValueAnimator"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="duration" type="long">
+</parameter>
+<parameter name="values" type="T...">
+</parameter>
+</constructor>
+<method name="addUpdateListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.animation.ValueAnimator.AnimatorUpdateListener">
+</parameter>
+</method>
+<method name="getAnimatedValue"
+ return="java.lang.Object"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getAnimatedValue"
+ return="java.lang.Object"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="propertyName" type="java.lang.String">
+</parameter>
+</method>
+<method name="getCurrentPlayTime"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getDuration"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFrameDelay"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getInterpolator"
+ return="android.view.animation.Interpolator"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getRepeatCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getRepeatMode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStartDelay"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getValues"
+ return="android.animation.PropertyValuesHolder[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isRunning"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="removeUpdateListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.animation.ValueAnimator.AnimatorUpdateListener">
+</parameter>
+</method>
+<method name="reverse"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setCurrentPlayTime"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="playTime" type="long">
+</parameter>
+</method>
+<method name="setDuration"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="duration" type="long">
+</parameter>
+</method>
+<method name="setEvaluator"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="android.animation.TypeEvaluator">
+</parameter>
+</method>
+<method name="setFrameDelay"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="frameDelay" type="long">
+</parameter>
+</method>
+<method name="setInterpolator"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="android.view.animation.Interpolator">
+</parameter>
+</method>
+<method name="setRepeatCount"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="int">
+</parameter>
+</method>
+<method name="setRepeatMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="int">
+</parameter>
+</method>
+<method name="setStartDelay"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startDelay" type="long">
+</parameter>
+</method>
+<method name="setValues"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="values" type="android.animation.PropertyValuesHolder...">
+</parameter>
+</method>
+<method name="setValues"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="values" type="T...">
+</parameter>
+</method>
+<field name="INFINITE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="RESTART"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="REVERSE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="ValueAnimator.AnimatorUpdateListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onAnimationUpdate"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="animation" type="android.animation.ValueAnimator">
+</parameter>
+</method>
+</interface>
 </package>
 <package name="android.app"
 >
@@ -28759,8 +28759,8 @@
 <parameter name="savedInstanceState" type="android.os.Bundle">
 </parameter>
 </method>
-<method name="onCreateAnimatable"
- return="android.animation.Animatable"
+<method name="onCreateAnimator"
+ return="android.animation.Animator"
  abstract="false"
  native="false"
  synchronized="false"
diff --git a/core/java/android/animation/Animatable.java b/core/java/android/animation/Animatable.java
deleted file mode 100644
index 3fdf200..0000000
--- a/core/java/android/animation/Animatable.java
+++ /dev/null
@@ -1,248 +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.animation;
-
-import android.view.animation.Interpolator;
-
-import java.util.ArrayList;
-
-/**
- * This is the superclass for classes which provide basic support for animations which can be
- * started, ended, and have <code>AnimatableListeners</code> added to them.
- */
-public abstract class Animatable implements Cloneable {
-
-
-    /**
-     * The set of listeners to be sent events through the life of an animation.
-     */
-    ArrayList<AnimatableListener> mListeners = null;
-
-    /**
-     * Starts this animation. If the animation has a nonzero startDelay, the animation will start
-     * running after that delay elapses. Note that the animation does not start synchronously with
-     * this call, because all animation events are posted to a central timing loop so that animation
-     * times are all synchronized on a single timing pulse on the UI thread. So the animation will
-     * start the next time that event handler processes events.
-     */
-    public void start() {
-    }
-
-    /**
-     * Cancels the animation. Unlike {@link #end()}, <code>cancel()</code> causes the animation to
-     * stop in its tracks, sending an {@link AnimatableListener#onAnimationCancel(Animatable)} to
-     * its listeners, followed by an {@link AnimatableListener#onAnimationEnd(Animatable)} message.
-     */
-    public void cancel() {
-    }
-
-    /**
-     * Ends the animation. This causes the animation to assign the end value of the property being
-     * animated, then calling the {@link AnimatableListener#onAnimationEnd(Animatable)} method on
-     * its listeners.
-     */
-    public void end() {
-    }
-
-    /**
-     * The amount of time, in milliseconds, to delay starting the animation after
-     * {@link #start()} is called.
-     *
-     * @return the number of milliseconds to delay running the animation
-     */
-    public abstract long getStartDelay();
-
-    /**
-     * The amount of time, in milliseconds, to delay starting the animation after
-     * {@link #start()} is called.
-
-     * @param startDelay The amount of the delay, in milliseconds
-     */
-    public abstract void setStartDelay(long startDelay);
-
-
-    /**
-     * Sets the length of the animation.
-     *
-     * @param duration The length of the animation, in milliseconds.
-     */
-    public abstract void setDuration(long duration);
-
-    /**
-     * Gets the length of the animation.
-     *
-     * @return The length of the animation, in milliseconds.
-     */
-    public abstract long getDuration();
-
-    /**
-     * The time interpolator used in calculating the elapsed fraction of this animation. The
-     * interpolator determines whether the animation runs with linear or non-linear motion,
-     * such as acceleration and deceleration. The default value is
-     * {@link android.view.animation.AccelerateDecelerateInterpolator}
-     *
-     * @param value the interpolator to be used by this animation
-     */
-    public abstract void setInterpolator(Interpolator value);
-
-    /**
-     * Returns whether this Animatable is currently running (having been started and not yet ended).
-     * @return Whether the Animatable is running.
-     */
-    public abstract boolean isRunning();
-
-    /**
-     * Adds a listener to the set of listeners that are sent events through the life of an
-     * animation, such as start, repeat, and end.
-     *
-     * @param listener the listener to be added to the current set of listeners for this animation.
-     */
-    public void addListener(AnimatableListener listener) {
-        if (mListeners == null) {
-            mListeners = new ArrayList<AnimatableListener>();
-        }
-        mListeners.add(listener);
-    }
-
-    /**
-     * Removes a listener from the set listening to this animation.
-     *
-     * @param listener the listener to be removed from the current set of listeners for this
-     *                 animation.
-     */
-    public void removeListener(AnimatableListener listener) {
-        if (mListeners == null) {
-            return;
-        }
-        mListeners.remove(listener);
-        if (mListeners.size() == 0) {
-            mListeners = null;
-        }
-    }
-
-    /**
-     * Gets the set of {@link AnimatableListener} objects that are currently
-     * listening for events on this <code>Animatable</code> object.
-     *
-     * @return ArrayList<AnimatableListener> The set of listeners.
-     */
-    public ArrayList<AnimatableListener> getListeners() {
-        return mListeners;
-    }
-
-    /**
-     * Removes all listeners from this object. This is equivalent to calling
-     * <code>getListeners()</code> followed by calling <code>clear()</code> on the
-     * returned list of listeners.
-     */
-    public void removeAllListeners() {
-        if (mListeners != null) {
-            mListeners.clear();
-            mListeners = null;
-        }
-    }
-
-    @Override
-    public Animatable clone() {
-        try {
-            final Animatable anim = (Animatable) super.clone();
-            if (mListeners != null) {
-                ArrayList<AnimatableListener> oldListeners = mListeners;
-                anim.mListeners = new ArrayList<AnimatableListener>();
-                int numListeners = oldListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    anim.mListeners.add(oldListeners.get(i));
-                }
-            }
-            return anim;
-        } catch (CloneNotSupportedException e) {
-           throw new AssertionError();
-        }
-    }
-
-    /**
-     * This method tells the object to use appropriate information to extract
-     * starting values for the animation. For example, a Sequencer object will pass
-     * this call to its child objects to tell them to set up the values. A
-     * PropertyAnimator object will use the information it has about its target object
-     * and PropertyValuesHolder objects to get the start values for its properties.
-     * An Animator object will ignore the request since it does not have enough
-     * information (such as a target object) to gather these values.
-     */
-    public void setupStartValues() {
-    }
-
-    /**
-     * This method tells the object to use appropriate information to extract
-     * ending values for the animation. For example, a Sequencer object will pass
-     * this call to its child objects to tell them to set up the values. A
-     * PropertyAnimator object will use the information it has about its target object
-     * and PropertyValuesHolder objects to get the start values for its properties.
-     * An Animator object will ignore the request since it does not have enough
-     * information (such as a target object) to gather these values.
-     */
-    public void setupEndValues() {
-    }
-
-    /**
-     * Sets the target object whose property will be animated by this animation. Not all subclasses
-     * operate on target objects (for example, {@link android.animation.Animator}, but this method
-     * is on the superclass for the convenience of dealing generically with those subclasses
-     * that do handle targets.
-     *
-     * @param target The object being animated
-     */
-    public void setTarget(Object target) {
-    }
-
-    /**
-     * <p>An animation listener receives notifications from an animation.
-     * Notifications indicate animation related events, such as the end or the
-     * repetition of the animation.</p>
-     */
-    public static interface AnimatableListener {
-        /**
-         * <p>Notifies the start of the animation.</p>
-         *
-         * @param animation The started animation.
-         */
-        void onAnimationStart(Animatable animation);
-
-        /**
-         * <p>Notifies the end of the animation. This callback is not invoked
-         * for animations with repeat count set to INFINITE.</p>
-         *
-         * @param animation The animation which reached its end.
-         */
-        void onAnimationEnd(Animatable animation);
-
-        /**
-         * <p>Notifies the cancellation of the animation. This callback is not invoked
-         * for animations with repeat count set to INFINITE.</p>
-         *
-         * @param animation The animation which was canceled.
-         */
-        void onAnimationCancel(Animatable animation);
-
-        /**
-         * <p>Notifies the repetition of the animation.</p>
-         *
-         * @param animation The animation which was repeated.
-         */
-        void onAnimationRepeat(Animatable animation);
-    }
-}
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
old mode 100755
new mode 100644
index 8e947ec..2ada6d6
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -16,461 +16,46 @@
 
 package android.animation;
 
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 
 /**
- * This class provides a simple timing engine for running animations
- * which calculate animated values and set them on target objects.
- *
- * <p>There is a single timing pulse that all animations use. It runs in a
- * custom handler to ensure that property changes happen on the UI thread.</p>
- *
- * <p>By default, Animator uses non-linear time interpolation, via the
- * {@link AccelerateDecelerateInterpolator} class, which accelerates into and decelerates
- * out of an animation. This behavior can be changed by calling
- * {@link Animator#setInterpolator(Interpolator)}.</p>
+ * This is the superclass for classes which provide basic support for animations which can be
+ * started, ended, and have <code>AnimatorListeners</code> added to them.
  */
-public class Animator<T> extends Animatable {
+public abstract class Animator implements Cloneable {
 
-    /**
-     * Internal constants
-     */
-
-    /*
-     * The default amount of time in ms between animation frames
-     */
-    private static final long DEFAULT_FRAME_DELAY = 30;
-
-    /**
-     * Messages sent to timing handler: START is sent when an animation first begins, FRAME is sent
-     * by the handler to itself to process the next animation frame
-     */
-    private static final int ANIMATION_START = 0;
-    private static final int ANIMATION_FRAME = 1;
-
-    /**
-     * Values used with internal variable mPlayingState to indicate the current state of an
-     * animation.
-     */
-    private static final int STOPPED    = 0; // Not yet playing
-    private static final int RUNNING    = 1; // Playing normally
-    private static final int CANCELED   = 2; // cancel() called - need to end it
-    private static final int ENDED      = 3; // end() called - need to end it
-    private static final int SEEKED     = 4; // Seeked to some time value
-
-    /**
-     * Internal variables
-     * NOTE: This object implements the clone() method, making a deep copy of any referenced
-     * objects. As other non-trivial fields are added to this class, make sure to add logic
-     * to clone() to make deep copies of them.
-     */
-
-    // The first time that the animation's animateFrame() method is called. This time is used to
-    // determine elapsed time (and therefore the elapsed fraction) in subsequent calls
-    // to animateFrame()
-    private long mStartTime;
-
-    /**
-     * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked
-     * to a value.
-     */
-    private long mSeekTime = -1;
-
-    // The static sAnimationHandler processes the internal timing loop on which all animations
-    // are based
-    private static AnimationHandler sAnimationHandler;
-
-    // The static list of all active animations
-    private static final ArrayList<Animator> sAnimations = new ArrayList<Animator>();
-
-    // The set of animations to be started on the next animation frame
-    private static final ArrayList<Animator> sPendingAnimations = new ArrayList<Animator>();
-
-    // The time interpolator to be used if none is set on the animation
-    private static final Interpolator sDefaultInterpolator = new AccelerateDecelerateInterpolator();
-
-    // type evaluators for the three primitive types handled by this implementation
-    private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
-    private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator();
-    private static final TypeEvaluator sDoubleEvaluator = new DoubleEvaluator();
-
-    /**
-     * Used to indicate whether the animation is currently playing in reverse. This causes the
-     * elapsed fraction to be inverted to calculate the appropriate values.
-     */
-    private boolean mPlayingBackwards = false;
-
-    /**
-     * This variable tracks the current iteration that is playing. When mCurrentIteration exceeds the
-     * repeatCount (if repeatCount!=INFINITE), the animation ends
-     */
-    private int mCurrentIteration = 0;
-
-    /**
-     * Tracks whether a startDelay'd animation has begun playing through the startDelay.
-     */
-    private boolean mStartedDelay = false;
-
-    /**
-     * Tracks the time at which the animation began playing through its startDelay. This is
-     * different from the mStartTime variable, which is used to track when the animation became
-     * active (which is when the startDelay expired and the animation was added to the active
-     * animations list).
-     */
-    private long mDelayStartTime;
-
-    /**
-     * Flag that represents the current state of the animation. Used to figure out when to start
-     * an animation (if state == STOPPED). Also used to end an animation that
-     * has been cancel()'d or end()'d since the last animation frame. Possible values are
-     * STOPPED, RUNNING, ENDED, CANCELED.
-     */
-    private int mPlayingState = STOPPED;
-
-    /**
-     * Internal collections used to avoid set collisions as animations start and end while being
-     * processed.
-     */
-    private static final ArrayList<Animator> sEndingAnims = new ArrayList<Animator>();
-    private static final ArrayList<Animator> sDelayedAnims = new ArrayList<Animator>();
-    private static final ArrayList<Animator> sReadyAnims = new ArrayList<Animator>();
-
-    /**
-     * Flag that denotes whether the animation is set up and ready to go. Used to
-     * set up animation that has not yet been started.
-     */
-    boolean mInitialized = false;
-
-    //
-    // Backing variables
-    //
-
-    // How long the animation should last in ms
-    private long mDuration;
-
-    // The amount of time in ms to delay starting the animation after start() is called
-    private long mStartDelay = 0;
-
-    // The number of milliseconds between animation frames
-    private static long sFrameDelay = DEFAULT_FRAME_DELAY;
-
-    // The number of times the animation will repeat. The default is 0, which means the animation
-    // will play only once
-    private int mRepeatCount = 0;
-
-    /**
-     * The type of repetition that will occur when repeatMode is nonzero. RESTART means the
-     * animation will start from the beginning on every new cycle. REVERSE means the animation
-     * will reverse directions on each iteration.
-     */
-    private int mRepeatMode = RESTART;
-
-    /**
-     * The time interpolator to be used. The elapsed fraction of the animation will be passed
-     * through this interpolator to calculate the interpolated fraction, which is then used to
-     * calculate the animated values.
-     */
-    private Interpolator mInterpolator = sDefaultInterpolator;
 
     /**
      * The set of listeners to be sent events through the life of an animation.
      */
-    private ArrayList<AnimatorUpdateListener> mUpdateListeners = null;
+    ArrayList<AnimatorListener> mListeners = null;
 
     /**
-     * The property/value sets being animated.
+     * Starts this animation. If the animation has a nonzero startDelay, the animation will start
+     * running after that delay elapses. Note that the animation does not start synchronously with
+     * this call, because all animation events are posted to a central timing loop so that animation
+     * times are all synchronized on a single timing pulse on the UI thread. So the animation will
+     * start the next time that event handler processes events.
      */
-    PropertyValuesHolder[] mValues;
-
-    /**
-     * A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values
-     * by property name during calls to getAnimatedValue(String).
-     */
-    HashMap<String, PropertyValuesHolder> mValuesMap;
-
-    /**
-     * Public constants
-     */
-
-    /**
-     * When the animation reaches the end and <code>repeatCount</code> is INFINITE
-     * or a positive value, the animation restarts from the beginning.
-     */
-    public static final int RESTART = 1;
-    /**
-     * When the animation reaches the end and <code>repeatCount</code> is INFINITE
-     * or a positive value, the animation reverses direction on every iteration.
-     */
-    public static final int REVERSE = 2;
-    /**
-     * This value used used with the {@link #setRepeatCount(int)} property to repeat
-     * the animation indefinitely.
-     */
-    public static final int INFINITE = -1;
-
-    /**
-     * Creates a new Animator object. This default constructor is primarily for
-     * use internally; the other constructors which take parameters are more generally
-     * useful.
-     */
-    public Animator() {
+    public void start() {
     }
 
     /**
-     * Constructs an Animator object with the specified duration and set of
-     * values. If the values are a set of PropertyValuesHolder objects, then these objects
-     * define the potentially multiple properties being animated and the values the properties are
-     * animated between. Otherwise, the values define a single set of values animated between.
-     *
-     * @param duration The length of the animation, in milliseconds.
-     * @param values The set of values to animate between. If these values are not
-     * PropertyValuesHolder objects, then there should be more than one value, since the values
-     * determine the interval to animate between.
+     * Cancels the animation. Unlike {@link #end()}, <code>cancel()</code> causes the animation to
+     * stop in its tracks, sending an {@link android.animation.Animator.AnimatorListener#onAnimationCancel(Animator)} to
+     * its listeners, followed by an {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} message.
      */
-    public Animator(long duration, T...values) {
-        mDuration = duration;
-        if (values.length > 0) {
-            setValues(values);
-        }
+    public void cancel() {
     }
 
     /**
-     * Sets the values, per property, being animated between. This function is called internally
-     * by the constructors of Animator that take a list of values. But an Animator can
-     * be constructed without values and this method can be called to set the values manually
-     * instead.
-     *
-     * @param values The set of values, per property, being animated between.
+     * Ends the animation. This causes the animation to assign the end value of the property being
+     * animated, then calling the {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} method on
+     * its listeners.
      */
-    public void setValues(PropertyValuesHolder... values) {
-        int numValues = values.length;
-        mValues = values;
-        mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
-        for (int i = 0; i < numValues; ++i) {
-            PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
-            mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
-        }
-    }
-
-    /**
-     * Returns the values that this Animator animates between. These values are stored in
-     * PropertyValuesHolder objects, even if the Animator was created with a simple list
-     * of value objects instead.
-     *
-     * @return PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the
-     * values, per property, that define the animation.
-     */
-    public PropertyValuesHolder[] getValues() {
-        return mValues;
-    }
-
-    /**
-     * Sets the values to animate between for this animation. If <code>values</code> is
-     * a set of PropertyValuesHolder objects, these objects will become the set of properties
-     * animated and the values that those properties are animated between. Otherwise, this method
-     * will set only one set of values for the Animator. Also, if the values are not
-     * PropertyValuesHolder objects and if there are already multiple sets of
-     * values defined for this Animator via
-     * more than one PropertyValuesHolder objects, this method will set the values for
-     * the first of those objects.
-     *
-     * @param values The set of values to animate between.
-     */
-    public void setValues(T... values) {
-        if (mValues == null || mValues.length == 0) {
-            setValues(new PropertyValuesHolder[]{
-                    new PropertyValuesHolder("", (Object[])values)});
-        } else {
-            PropertyValuesHolder valuesHolder = mValues[0];
-            valuesHolder.setValues(values);
-        }
-    }
-
-    /**
-     * This function is called immediately before processing the first animation
-     * frame of an animation. If there is a nonzero <code>startDelay</code>, the
-     * function is called after that delay ends.
-     * It takes care of the final initialization steps for the
-     * animation.
-     *
-     *  <p>Overrides of this method should call the superclass method to ensure
-     *  that internal mechanisms for the animation are set up correctly.</p>
-     */
-    void initAnimation() {
-        if (!mInitialized) {
-            int numValues = mValues.length;
-            for (int i = 0; i < numValues; ++i) {
-                mValues[i].init();
-            }
-            mCurrentIteration = 0;
-            mInitialized = true;
-        }
-    }
-
-
-    /**
-     * Sets the length of the animation.
-     *
-     * @param duration The length of the animation, in milliseconds.
-     */
-    public void setDuration(long duration) {
-        mDuration = duration;
-    }
-
-    /**
-     * Gets the length of the animation.
-     *
-     * @return The length of the animation, in milliseconds.
-     */
-    public long getDuration() {
-        return mDuration;
-    }
-
-    /**
-     * Sets the position of the animation to the specified point in time. This time should
-     * be between 0 and the total duration of the animation, including any repetition. If
-     * the animation has not yet been started, then it will not advance forward after it is
-     * set to this time; it will simply set the time to this value and perform any appropriate
-     * actions based on that time. If the animation is already running, then setCurrentPlayTime()
-     * will set the current playing time to this value and continue playing from that point.
-     *
-     * @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
-     */
-    public void setCurrentPlayTime(long playTime) {
-        initAnimation();
-        long currentTime = AnimationUtils.currentAnimationTimeMillis();
-        if (mPlayingState != RUNNING) {
-            mSeekTime = playTime;
-            mPlayingState = SEEKED;
-        }
-        mStartTime = currentTime - playTime;
-        animationFrame(currentTime);
-    }
-
-    /**
-     * Gets the current position of the animation in time, which is equal to the current
-     * time minus the time that the animation started. An animation that is not yet started will
-     * return a value of zero.
-     *
-     * @return The current position in time of the animation.
-     */
-    public long getCurrentPlayTime() {
-        if (!mInitialized || mPlayingState == STOPPED) {
-            return 0;
-        }
-        return AnimationUtils.currentAnimationTimeMillis() - mStartTime;
-    }
-
-    /**
-     * This custom, static handler handles the timing pulse that is shared by
-     * all active animations. This approach ensures that the setting of animation
-     * values will happen on the UI thread and that all animations will share
-     * the same times for calculating their values, which makes synchronizing
-     * animations possible.
-     *
-     */
-    private static class AnimationHandler extends Handler {
-        /**
-         * There are only two messages that we care about: ANIMATION_START and
-         * ANIMATION_FRAME. The START message is sent when an animation's start()
-         * method is called. It cannot start synchronously when start() is called
-         * because the call may be on the wrong thread, and it would also not be
-         * synchronized with other animations because it would not start on a common
-         * timing pulse. So each animation sends a START message to the handler, which
-         * causes the handler to place the animation on the active animations queue and
-         * start processing frames for that animation.
-         * The FRAME message is the one that is sent over and over while there are any
-         * active animations to process.
-         */
-        @Override
-        public void handleMessage(Message msg) {
-            boolean callAgain = true;
-            switch (msg.what) {
-                // TODO: should we avoid sending frame message when starting if we
-                // were already running?
-                case ANIMATION_START:
-                    if (sAnimations.size() > 0 || sDelayedAnims.size() > 0) {
-                        callAgain = false;
-                    }
-                    // pendingAnims holds any animations that have requested to be started
-                    // We're going to clear sPendingAnimations, but starting animation may
-                    // cause more to be added to the pending list (for example, if one animation
-                    // starting triggers another starting). So we loop until sPendingAnimations
-                    // is empty.
-                    while (sPendingAnimations.size() > 0) {
-                        ArrayList<Animator> pendingCopy =
-                                (ArrayList<Animator>) sPendingAnimations.clone();
-                        sPendingAnimations.clear();
-                        int count = pendingCopy.size();
-                        for (int i = 0; i < count; ++i) {
-                            Animator anim = pendingCopy.get(i);
-                            // If the animation has a startDelay, place it on the delayed list
-                            if (anim.mStartDelay == 0 || anim.mPlayingState == ENDED ||
-                                    anim.mPlayingState == CANCELED) {
-                                anim.startAnimation();
-                            } else {
-                                sDelayedAnims.add(anim);
-                            }
-                        }
-                    }
-                    // fall through to process first frame of new animations
-                case ANIMATION_FRAME:
-                    // currentTime holds the common time for all animations processed
-                    // during this frame
-                    long currentTime = AnimationUtils.currentAnimationTimeMillis();
-
-                    // First, process animations currently sitting on the delayed queue, adding
-                    // them to the active animations if they are ready
-                    int numDelayedAnims = sDelayedAnims.size();
-                    for (int i = 0; i < numDelayedAnims; ++i) {
-                        Animator anim = sDelayedAnims.get(i);
-                        if (anim.delayedAnimationFrame(currentTime)) {
-                            sReadyAnims.add(anim);
-                        }
-                    }
-                    int numReadyAnims = sReadyAnims.size();
-                    if (numReadyAnims > 0) {
-                        for (int i = 0; i < numReadyAnims; ++i) {
-                            Animator anim = sReadyAnims.get(i);
-                            anim.startAnimation();
-                            sDelayedAnims.remove(anim);
-                        }
-                        sReadyAnims.clear();
-                    }
-
-                    // Now process all active animations. The return value from animationFrame()
-                    // tells the handler whether it should now be ended
-                    int numAnims = sAnimations.size();
-                    for (int i = 0; i < numAnims; ++i) {
-                        Animator anim = sAnimations.get(i);
-                        if (anim.animationFrame(currentTime)) {
-                            sEndingAnims.add(anim);
-                        }
-                    }
-                    if (sEndingAnims.size() > 0) {
-                        for (int i = 0; i < sEndingAnims.size(); ++i) {
-                            sEndingAnims.get(i).endAnimation();
-                        }
-                        sEndingAnims.clear();
-                    }
-
-                    // If there are still active or delayed animations, call the handler again
-                    // after the frameDelay
-                    if (callAgain && (!sAnimations.isEmpty() || !sDelayedAnims.isEmpty())) {
-                        sendEmptyMessageDelayed(ANIMATION_FRAME, sFrameDelay);
-                    }
-                    break;
-            }
-        }
+    public void end() {
     }
 
     /**
@@ -479,9 +64,7 @@
      *
      * @return the number of milliseconds to delay running the animation
      */
-    public long getStartDelay() {
-        return mStartDelay;
-    }
+    public abstract long getStartDelay();
 
     /**
      * The amount of time, in milliseconds, to delay starting the animation after
@@ -489,147 +72,22 @@
 
      * @param startDelay The amount of the delay, in milliseconds
      */
-    public void setStartDelay(long startDelay) {
-        this.mStartDelay = startDelay;
-    }
+    public abstract void setStartDelay(long startDelay);
+
 
     /**
-     * The amount of time, in milliseconds, between each frame of the animation. This is a
-     * requested time that the animation will attempt to honor, but the actual delay between
-     * frames may be different, depending on system load and capabilities. This is a static
-     * function because the same delay will be applied to all animations, since they are all
-     * run off of a single timing loop.
+     * Sets the length of the animation.
      *
-     * @return the requested time between frames, in milliseconds
+     * @param duration The length of the animation, in milliseconds.
      */
-    public static long getFrameDelay() {
-        return sFrameDelay;
-    }
+    public abstract void setDuration(long duration);
 
     /**
-     * The amount of time, in milliseconds, between each frame of the animation. This is a
-     * requested time that the animation will attempt to honor, but the actual delay between
-     * frames may be different, depending on system load and capabilities. This is a static
-     * function because the same delay will be applied to all animations, since they are all
-     * run off of a single timing loop.
+     * Gets the length of the animation.
      *
-     * @param frameDelay the requested time between frames, in milliseconds
+     * @return The length of the animation, in milliseconds.
      */
-    public static void setFrameDelay(long frameDelay) {
-        sFrameDelay = frameDelay;
-    }
-
-    /**
-     * The most recent value calculated by this <code>Animator</code> when there is just one
-     * property being animated. This value is only sensible while the animation is running. The main
-     * purpose for this read-only property is to retrieve the value from the <code>Animator</code>
-     * during a call to {@link AnimatorUpdateListener#onAnimationUpdate(Animator)}, which
-     * is called during each animation frame, immediately after the value is calculated.
-     *
-     * @return animatedValue The value most recently calculated by this <code>Animator</code> for
-     * the single property being animated. If there are several properties being animated
-     * (specified by several PropertyValuesHolder objects in the constructor), this function
-     * returns the animated value for the first of those objects.
-     */
-    public Object getAnimatedValue() {
-        if (mValues != null && mValues.length > 0) {
-            return mValues[0].getAnimatedValue();
-        }
-        // Shouldn't get here; should always have values unless Animator was set up wrong
-        return null;
-    }
-
-    /**
-     * The most recent value calculated by this <code>Animator</code> for <code>propertyName</code>.
-     * The main purpose for this read-only property is to retrieve the value from the
-     * <code>Animator</code> during a call to
-     * {@link AnimatorUpdateListener#onAnimationUpdate(Animator)}, which
-     * is called during each animation frame, immediately after the value is calculated.
-     *
-     * @return animatedValue The value most recently calculated for the named property
-     * by this <code>Animator</code>.
-     */
-    public Object getAnimatedValue(String propertyName) {
-        PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
-        if (valuesHolder != null) {
-            return valuesHolder.getAnimatedValue();
-        } else {
-            // At least avoid crashing if called with bogus propertyName
-            return null;
-        }
-    }
-
-    /**
-     * Sets how many times the animation should be repeated. If the repeat
-     * count is 0, the animation is never repeated. If the repeat count is
-     * greater than 0 or {@link #INFINITE}, the repeat mode will be taken
-     * into account. The repeat count is 0 by default.
-     *
-     * @param value the number of times the animation should be repeated
-     */
-    public void setRepeatCount(int value) {
-        mRepeatCount = value;
-    }
-    /**
-     * Defines how many times the animation should repeat. The default value
-     * is 0.
-     *
-     * @return the number of times the animation should repeat, or {@link #INFINITE}
-     */
-    public int getRepeatCount() {
-        return mRepeatCount;
-    }
-
-    /**
-     * Defines what this animation should do when it reaches the end. This
-     * setting is applied only when the repeat count is either greater than
-     * 0 or {@link #INFINITE}. Defaults to {@link #RESTART}.
-     *
-     * @param value {@link #RESTART} or {@link #REVERSE}
-     */
-    public void setRepeatMode(int value) {
-        mRepeatMode = value;
-    }
-
-    /**
-     * Defines what this animation should do when it reaches the end.
-     *
-     * @return either one of {@link #REVERSE} or {@link #RESTART}
-     */
-    public int getRepeatMode() {
-        return mRepeatMode;
-    }
-
-    /**
-     * Adds a listener to the set of listeners that are sent update events through the life of
-     * an animation. This method is called on all listeners for every frame of the animation,
-     * after the values for the animation have been calculated.
-     *
-     * @param listener the listener to be added to the current set of listeners for this animation.
-     */
-    public void addUpdateListener(AnimatorUpdateListener listener) {
-        if (mUpdateListeners == null) {
-            mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
-        }
-        mUpdateListeners.add(listener);
-    }
-
-    /**
-     * Removes a listener from the set listening to frame updates for this animation.
-     *
-     * @param listener the listener to be removed from the current set of update listeners
-     * for this animation.
-     */
-    public void removeUpdateListener(AnimatorUpdateListener listener) {
-        if (mUpdateListeners == null) {
-            return;
-        }
-        mUpdateListeners.remove(listener);
-        if (mUpdateListeners.size() == 0) {
-            mUpdateListeners = null;
-        }
-    }
-
+    public abstract long getDuration();
 
     /**
      * The time interpolator used in calculating the elapsed fraction of this animation. The
@@ -639,335 +97,152 @@
      *
      * @param value the interpolator to be used by this animation
      */
-    @Override
-    public void setInterpolator(Interpolator value) {
-        if (value != null) {
-            mInterpolator = value;
+    public abstract void setInterpolator(Interpolator value);
+
+    /**
+     * Returns whether this Animator is currently running (having been started and not yet ended).
+     * @return Whether the Animator is running.
+     */
+    public abstract boolean isRunning();
+
+    /**
+     * Adds a listener to the set of listeners that are sent events through the life of an
+     * animation, such as start, repeat, and end.
+     *
+     * @param listener the listener to be added to the current set of listeners for this animation.
+     */
+    public void addListener(AnimatorListener listener) {
+        if (mListeners == null) {
+            mListeners = new ArrayList<AnimatorListener>();
+        }
+        mListeners.add(listener);
+    }
+
+    /**
+     * Removes a listener from the set listening to this animation.
+     *
+     * @param listener the listener to be removed from the current set of listeners for this
+     *                 animation.
+     */
+    public void removeListener(AnimatorListener listener) {
+        if (mListeners == null) {
+            return;
+        }
+        mListeners.remove(listener);
+        if (mListeners.size() == 0) {
+            mListeners = null;
         }
     }
 
     /**
-     * Returns the timing interpolator that this Animator uses.
+     * Gets the set of {@link android.animation.Animator.AnimatorListener} objects that are currently
+     * listening for events on this <code>Animator</code> object.
      *
-     * @return The timing interpolator for this Animator.
+     * @return ArrayList<AnimatorListener> The set of listeners.
      */
-    public Interpolator getInterpolator() {
-        return mInterpolator;
+    public ArrayList<AnimatorListener> getListeners() {
+        return mListeners;
     }
 
     /**
-     * The type evaluator to be used when calculating the animated values of this animation.
-     * The system will automatically assign a float, int, or double evaluator based on the type
-     * of <code>startValue</code> and <code>endValue</code> in the constructor. But if these values
-     * are not one of these primitive types, or if different evaluation is desired (such as is
-     * necessary with int values that represent colors), a custom evaluator needs to be assigned.
-     * For example, when running an animation on color values, the {@link RGBEvaluator}
-     * should be used to get correct RGB color interpolation.
-     *
-     * <p>If this Animator has only one set of values being animated between, this evaluator
-     * will be used for that set. If there are several sets of values being animated, which is
-     * the case if PropertyValuesHOlder objects were set on the Animator, then the evaluator
-     * is assigned just to the first PropertyValuesHolder object.</p>
-     *
-     * @param value the evaluator to be used this animation
+     * Removes all listeners from this object. This is equivalent to calling
+     * <code>getListeners()</code> followed by calling <code>clear()</code> on the
+     * returned list of listeners.
      */
-    public void setEvaluator(TypeEvaluator value) {
-        if (value != null && mValues != null && mValues.length > 0) {
-            mValues[0].setEvaluator(value);
-        }
-    }
-
-    /**
-     * Start the animation playing. This version of start() takes a boolean flag that indicates
-     * whether the animation should play in reverse. The flag is usually false, but may be set
-     * to true if called from the reverse() method/
-     *
-     * @param playBackwards Whether the Animator should start playing in reverse.
-     */
-    private void start(boolean playBackwards) {
-        mPlayingBackwards = playBackwards;
-        if ((mStartDelay == 0) && (Thread.currentThread() == Looper.getMainLooper().getThread())) {
-            // This sets the initial value of the animation, prior to actually starting it running
-            setCurrentPlayTime(getCurrentPlayTime());
-        }
-        mPlayingState = STOPPED;
-        mStartedDelay = false;
-        sPendingAnimations.add(this);
-        if (sAnimationHandler == null) {
-            sAnimationHandler = new AnimationHandler();
-        }
-        // TODO: does this put too many messages on the queue if the handler
-        // is already running?
-        sAnimationHandler.sendEmptyMessage(ANIMATION_START);
-    }
-
-    @Override
-    public void start() {
-        start(false);
-    }
-
-    @Override
-    public void cancel() {
+    public void removeAllListeners() {
         if (mListeners != null) {
-            ArrayList<AnimatableListener> tmpListeners =
-                    (ArrayList<AnimatableListener>) mListeners.clone();
-            for (AnimatableListener listener : tmpListeners) {
-                listener.onAnimationCancel(this);
-            }
-        }
-        // Just set the CANCELED flag - this causes the animation to end the next time a frame
-        // is processed.
-        mPlayingState = CANCELED;
-    }
-
-    @Override
-    public void end() {
-        if (!sAnimations.contains(this) && !sPendingAnimations.contains(this)) {
-            // Special case if the animation has not yet started; get it ready for ending
-            mStartedDelay = false;
-            sPendingAnimations.add(this);
-            if (sAnimationHandler == null) {
-                sAnimationHandler = new AnimationHandler();
-            }
-            sAnimationHandler.sendEmptyMessage(ANIMATION_START);
-        }
-        // Just set the ENDED flag - this causes the animation to end the next time a frame
-        // is processed.
-        mPlayingState = ENDED;
-    }
-
-    @Override
-    public boolean isRunning() {
-        // ENDED or CANCELED indicate that it has been ended or canceled, but not processed yet
-        return (mPlayingState == RUNNING || mPlayingState == ENDED || mPlayingState == CANCELED);
-    }
-
-    /**
-     * Plays the Animator in reverse. If the animation is already running,
-     * it will stop itself and play backwards from the point reached when reverse was called.
-     * If the animation is not currently running, then it will start from the end and
-     * play backwards. This behavior is only set for the current animation; future playing
-     * of the animation will use the default behavior of playing forward.
-     */
-    public void reverse() {
-        mPlayingBackwards = !mPlayingBackwards;
-        if (mPlayingState == RUNNING) {
-            long currentTime = AnimationUtils.currentAnimationTimeMillis();
-            long currentPlayTime = currentTime - mStartTime;
-            long timeLeft = mDuration - currentPlayTime;
-            mStartTime = currentTime - timeLeft;
-        } else {
-            start(true);
-        }
-    }
-
-    /**
-     * Called internally to end an animation by removing it from the animations list. Must be
-     * called on the UI thread.
-     */
-    private void endAnimation() {
-        sAnimations.remove(this);
-        mPlayingState = STOPPED;
-        if (mListeners != null) {
-            ArrayList<AnimatableListener> tmpListeners =
-                    (ArrayList<AnimatableListener>) mListeners.clone();
-            for (AnimatableListener listener : tmpListeners) {
-                listener.onAnimationEnd(this);
-            }
-        }
-    }
-
-    /**
-     * Called internally to start an animation by adding it to the active animations list. Must be
-     * called on the UI thread.
-     */
-    private void startAnimation() {
-        initAnimation();
-        sAnimations.add(this);
-        if (mListeners != null) {
-            ArrayList<AnimatableListener> tmpListeners =
-                    (ArrayList<AnimatableListener>) mListeners.clone();
-            for (AnimatableListener listener : tmpListeners) {
-                listener.onAnimationStart(this);
-            }
-        }
-    }
-
-    /**
-     * Internal function called to process an animation frame on an animation that is currently
-     * sleeping through its <code>startDelay</code> phase. The return value indicates whether it
-     * should be woken up and put on the active animations queue.
-     *
-     * @param currentTime The current animation time, used to calculate whether the animation
-     * has exceeded its <code>startDelay</code> and should be started.
-     * @return True if the animation's <code>startDelay</code> has been exceeded and the animation
-     * should be added to the set of active animations.
-     */
-    private boolean delayedAnimationFrame(long currentTime) {
-        if (mPlayingState == CANCELED || mPlayingState == ENDED) {
-            // end the delay, process an animation frame to actually cancel it
-            return true;
-        }
-        if (!mStartedDelay) {
-            mStartedDelay = true;
-            mDelayStartTime = currentTime;
-        } else {
-            long deltaTime = currentTime - mDelayStartTime;
-            if (deltaTime > mStartDelay) {
-                // startDelay ended - start the anim and record the
-                // mStartTime appropriately
-                mStartTime = currentTime - (deltaTime - mStartDelay);
-                mPlayingState = RUNNING;
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * This internal function processes a single animation frame for a given animation. The
-     * currentTime parameter is the timing pulse sent by the handler, used to calculate the
-     * elapsed duration, and therefore
-     * the elapsed fraction, of the animation. The return value indicates whether the animation
-     * should be ended (which happens when the elapsed time of the animation exceeds the
-     * animation's duration, including the repeatCount).
-     *
-     * @param currentTime The current time, as tracked by the static timing handler
-     * @return true if the animation's duration, including any repetitions due to
-     * <code>repeatCount</code> has been exceeded and the animation should be ended.
-     */
-    private boolean animationFrame(long currentTime) {
-        boolean done = false;
-
-        if (mPlayingState == STOPPED) {
-            mPlayingState = RUNNING;
-            if (mSeekTime < 0) {
-                mStartTime = currentTime;
-            } else {
-                mStartTime = currentTime - mSeekTime;
-                // Now that we're playing, reset the seek time
-                mSeekTime = -1;
-            }
-        }
-        switch (mPlayingState) {
-        case RUNNING:
-        case SEEKED:
-            float fraction = (float)(currentTime - mStartTime) / mDuration;
-            if (fraction >= 1f) {
-                if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
-                    // Time to repeat
-                    if (mListeners != null) {
-                        for (AnimatableListener listener : mListeners) {
-                            listener.onAnimationRepeat(this);
-                        }
-                    }
-                    ++mCurrentIteration;
-                    if (mRepeatMode == REVERSE) {
-                        mPlayingBackwards = mPlayingBackwards ? false : true;
-                    }
-                    // TODO: doesn't account for fraction going Wayyyyy over 1, like 2+
-                    fraction = fraction - 1f;
-                    mStartTime += mDuration;
-                } else {
-                    done = true;
-                    fraction = Math.min(fraction, 1.0f);
-                }
-            }
-            if (mPlayingBackwards) {
-                fraction = 1f - fraction;
-            }
-            animateValue(fraction);
-            break;
-        case ENDED:
-            // The final value set on the target varies, depending on whether the animation
-            // was supposed to repeat an odd number of times
-            if (mRepeatCount > 0 && (mRepeatCount & 0x01) == 1) {
-                animateValue(0f);
-            } else {
-                animateValue(1f);
-            }
-            // Fall through to set done flag
-        case CANCELED:
-            done = true;
-            mPlayingState = STOPPED;
-            break;
-        }
-
-        return done;
-    }
-
-    /**
-     * This method is called with the elapsed fraction of the animation during every
-     * animation frame. This function turns the elapsed fraction into an interpolated fraction
-     * and then into an animated value (from the evaluator. The function is called mostly during
-     * animation updates, but it is also called when the <code>end()</code>
-     * function is called, to set the final value on the property.
-     *
-     * <p>Overrides of this method must call the superclass to perform the calculation
-     * of the animated value.</p>
-     *
-     * @param fraction The elapsed fraction of the animation.
-     */
-    void animateValue(float fraction) {
-        fraction = mInterpolator.getInterpolation(fraction);
-        int numValues = mValues.length;
-        for (int i = 0; i < numValues; ++i) {
-            mValues[i].calculateValue(fraction);
-        }
-        if (mUpdateListeners != null) {
-            int numListeners = mUpdateListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                mUpdateListeners.get(i).onAnimationUpdate(this);
-            }
+            mListeners.clear();
+            mListeners = null;
         }
     }
 
     @Override
     public Animator clone() {
-        final Animator anim = (Animator) super.clone();
-        if (mUpdateListeners != null) {
-            ArrayList<AnimatorUpdateListener> oldListeners = mUpdateListeners;
-            anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
-            int numListeners = oldListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                anim.mUpdateListeners.add(oldListeners.get(i));
+        try {
+            final Animator anim = (Animator) super.clone();
+            if (mListeners != null) {
+                ArrayList<AnimatorListener> oldListeners = mListeners;
+                anim.mListeners = new ArrayList<AnimatorListener>();
+                int numListeners = oldListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    anim.mListeners.add(oldListeners.get(i));
+                }
             }
+            return anim;
+        } catch (CloneNotSupportedException e) {
+           throw new AssertionError();
         }
-        anim.mSeekTime = -1;
-        anim.mPlayingBackwards = false;
-        anim.mCurrentIteration = 0;
-        anim.mInitialized = false;
-        anim.mPlayingState = STOPPED;
-        anim.mStartedDelay = false;
-        PropertyValuesHolder[] oldValues = mValues;
-        if (oldValues != null) {
-            int numValues = oldValues.length;
-            anim.mValues = new PropertyValuesHolder[numValues];
-            for (int i = 0; i < numValues; ++i) {
-                anim.mValues[i] = oldValues[i].clone();
-            }
-            anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
-            for (int i = 0; i < numValues; ++i) {
-                PropertyValuesHolder valuesHolder = mValues[i];
-                anim.mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
-            }
-        }
-        return anim;
     }
 
     /**
-     * Implementors of this interface can add themselves as update listeners
-     * to an <code>Animator</code> instance to receive callbacks on every animation
-     * frame, after the current frame's values have been calculated for that
-     * <code>Animator</code>.
+     * This method tells the object to use appropriate information to extract
+     * starting values for the animation. For example, a AnimatorSet object will pass
+     * this call to its child objects to tell them to set up the values. A
+     * ObjectAnimator object will use the information it has about its target object
+     * and PropertyValuesHolder objects to get the start values for its properties.
+     * An ValueAnimator object will ignore the request since it does not have enough
+     * information (such as a target object) to gather these values.
      */
-    public static interface AnimatorUpdateListener {
+    public void setupStartValues() {
+    }
+
+    /**
+     * This method tells the object to use appropriate information to extract
+     * ending values for the animation. For example, a AnimatorSet object will pass
+     * this call to its child objects to tell them to set up the values. A
+     * ObjectAnimator object will use the information it has about its target object
+     * and PropertyValuesHolder objects to get the start values for its properties.
+     * An ValueAnimator object will ignore the request since it does not have enough
+     * information (such as a target object) to gather these values.
+     */
+    public void setupEndValues() {
+    }
+
+    /**
+     * Sets the target object whose property will be animated by this animation. Not all subclasses
+     * operate on target objects (for example, {@link ValueAnimator}, but this method
+     * is on the superclass for the convenience of dealing generically with those subclasses
+     * that do handle targets.
+     *
+     * @param target The object being animated
+     */
+    public void setTarget(Object target) {
+    }
+
+    /**
+     * <p>An animation listener receives notifications from an animation.
+     * Notifications indicate animation related events, such as the end or the
+     * repetition of the animation.</p>
+     */
+    public static interface AnimatorListener {
         /**
-         * <p>Notifies the occurrence of another frame of the animation.</p>
+         * <p>Notifies the start of the animation.</p>
+         *
+         * @param animation The started animation.
+         */
+        void onAnimationStart(Animator animation);
+
+        /**
+         * <p>Notifies the end of the animation. This callback is not invoked
+         * for animations with repeat count set to INFINITE.</p>
+         *
+         * @param animation The animation which reached its end.
+         */
+        void onAnimationEnd(Animator animation);
+
+        /**
+         * <p>Notifies the cancellation of the animation. This callback is not invoked
+         * for animations with repeat count set to INFINITE.</p>
+         *
+         * @param animation The animation which was canceled.
+         */
+        void onAnimationCancel(Animator animation);
+
+        /**
+         * <p>Notifies the repetition of the animation.</p>
          *
          * @param animation The animation which was repeated.
          */
-        void onAnimationUpdate(Animator animation);
-
+        void onAnimationRepeat(Animator animation);
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/animation/AnimatableInflater.java b/core/java/android/animation/AnimatorInflater.java
similarity index 83%
rename from core/java/android/animation/AnimatableInflater.java
rename to core/java/android/animation/AnimatorInflater.java
index 88fa77e..0016459 100644
--- a/core/java/android/animation/AnimatableInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -30,7 +30,7 @@
 import java.util.ArrayList;
 
 /**
- * This class is used to instantiate menu XML files into Animatable objects.
+ * This class is used to instantiate menu XML files into Animator objects.
  * <p>
  * For performance reasons, menu inflation relies heavily on pre-processing of
  * XML files that is done at build time. Therefore, it is not currently possible
@@ -38,10 +38,10 @@
  * it only works with an XmlPullParser returned from a compiled resource (R.
  * <em>something</em> file.)
  */
-public class AnimatableInflater {
+public class AnimatorInflater {
 
     /**
-     * These flags are used when parsing Sequencer objects
+     * These flags are used when parsing AnimatorSet objects
      */
     private static final int TOGETHER = 0;
     private static final int SEQUENTIALLY = 1;
@@ -56,20 +56,20 @@
     private static final int VALUE_TYPE_CUSTOM      = 4;
 
     /**
-     * Loads an {@link Animatable} object from a resource
+     * Loads an {@link Animator} object from a resource
      *
      * @param context Application context used to access resources
      * @param id The resource id of the animation to load
-     * @return The animatable object reference by the specified id
+     * @return The animator object reference by the specified id
      * @throws android.content.res.Resources.NotFoundException when the animation cannot be loaded
      */
-    public static Animatable loadAnimatable(Context context, int id)
+    public static Animator loadAnimator(Context context, int id)
             throws NotFoundException {
 
         XmlResourceParser parser = null;
         try {
             parser = context.getResources().getAnimation(id);
-            return createAnimatableFromXml(context, parser);
+            return createAnimatorFromXml(context, parser);
         } catch (XmlPullParserException ex) {
             Resources.NotFoundException rnf =
                     new Resources.NotFoundException("Can't load animation resource ID #0x" +
@@ -87,18 +87,18 @@
         }
     }
 
-    private static Animatable createAnimatableFromXml(Context c, XmlPullParser parser)
+    private static Animator createAnimatorFromXml(Context c, XmlPullParser parser)
             throws XmlPullParserException, IOException {
 
-        return createAnimatableFromXml(c, parser, Xml.asAttributeSet(parser), null, 0);
+        return createAnimatorFromXml(c, parser, Xml.asAttributeSet(parser), null, 0);
     }
 
-    private static Animatable createAnimatableFromXml(Context c, XmlPullParser parser,
-            AttributeSet attrs, Sequencer parent, int sequenceOrdering)
+    private static Animator createAnimatorFromXml(Context c, XmlPullParser parser,
+            AttributeSet attrs, AnimatorSet parent, int sequenceOrdering)
             throws XmlPullParserException, IOException {
 
-        Animatable anim = null;
-        ArrayList<Animatable> childAnims = null;
+        Animator anim = null;
+        ArrayList<Animator> childAnims = null;
 
         // Make sure we are on a start tag.
         int type;
@@ -113,17 +113,17 @@
 
             String  name = parser.getName();
 
-            if (name.equals("property")) {
-                anim = loadPropertyAnimator(c, attrs);
+            if (name.equals("objectAnimator")) {
+                anim = loadObjectAnimator(c, attrs);
             } else if (name.equals("animator")) {
                 anim = loadAnimator(c, attrs, null);
-            } else if (name.equals("sequencer")) {
-                anim = new Sequencer();
+            } else if (name.equals("set")) {
+                anim = new AnimatorSet();
                 TypedArray a = c.obtainStyledAttributes(attrs,
-                        com.android.internal.R.styleable.Sequencer);
-                int ordering = a.getInt(com.android.internal.R.styleable.Sequencer_ordering,
+                        com.android.internal.R.styleable.AnimatorSet);
+                int ordering = a.getInt(com.android.internal.R.styleable.AnimatorSet_ordering,
                         TOGETHER);
-                createAnimatableFromXml(c, parser, attrs, (Sequencer) anim,  ordering);
+                createAnimatorFromXml(c, parser, attrs, (AnimatorSet) anim,  ordering);
                 a.recycle();
             } else {
                 throw new RuntimeException("Unknown animator name: " + parser.getName());
@@ -131,15 +131,15 @@
 
             if (parent != null) {
                 if (childAnims == null) {
-                    childAnims = new ArrayList<Animatable>();
+                    childAnims = new ArrayList<Animator>();
                 }
                 childAnims.add(anim);
             }
         }
         if (parent != null && childAnims != null) {
-            Animatable[] animsArray = new Animatable[childAnims.size()];
+            Animator[] animsArray = new Animator[childAnims.size()];
             int index = 0;
-            for (Animatable a : childAnims) {
+            for (Animator a : childAnims) {
                 animsArray[index++] = a;
             }
             if (sequenceOrdering == TOGETHER) {
@@ -153,10 +153,10 @@
 
     }
 
-    private static PropertyAnimator loadPropertyAnimator(Context context, AttributeSet attrs)
+    private static ObjectAnimator loadObjectAnimator(Context context, AttributeSet attrs)
             throws NotFoundException {
 
-        PropertyAnimator anim = new PropertyAnimator();
+        ObjectAnimator anim = new ObjectAnimator();
 
         loadAnimator(context, attrs, anim);
 
@@ -179,7 +179,7 @@
      * @param context the application environment
      * @param attrs the set of attributes holding the animation parameters
      */
-    private static Animator loadAnimator(Context context, AttributeSet attrs, Animator anim)
+    private static ValueAnimator loadAnimator(Context context, AttributeSet attrs, ValueAnimator anim)
             throws NotFoundException {
 
         TypedArray a =
@@ -236,7 +236,7 @@
         }
 
         if (anim == null) {
-            anim = new Animator(duration, valueFrom, valueTo);
+            anim = new ValueAnimator(duration, valueFrom, valueTo);
         } else {
             anim.setDuration(duration);
             anim.setValues(valueFrom, valueTo);
@@ -251,7 +251,7 @@
         if (a.hasValue(com.android.internal.R.styleable.Animator_repeatMode)) {
             anim.setRepeatMode(
                     a.getInt(com.android.internal.R.styleable.Animator_repeatMode,
-                            Animator.RESTART));
+                            ValueAnimator.RESTART));
         }
         if (evaluator != null) {
             anim.setEvaluator(evaluator);
diff --git a/core/java/android/animation/AnimatableListenerAdapter.java b/core/java/android/animation/AnimatorListenerAdapter.java
similarity index 73%
rename from core/java/android/animation/AnimatableListenerAdapter.java
rename to core/java/android/animation/AnimatorListenerAdapter.java
index c169b28..6182389 100644
--- a/core/java/android/animation/AnimatableListenerAdapter.java
+++ b/core/java/android/animation/AnimatorListenerAdapter.java
@@ -16,41 +16,39 @@
 
 package android.animation;
 
-import android.animation.Animatable.AnimatableListener;
-
 /**
- * This adapter class provides empty implementations of the methods from {@link AnimatableListener}.
+ * This adapter class provides empty implementations of the methods from {@link android.animation.Animator.AnimatorListener}.
  * Any custom listener that cares only about a subset of the methods of this listener can
  * simply subclass this adapter class instead of implementing the interface directly.
  */
-public abstract class AnimatableListenerAdapter implements AnimatableListener {
+public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener {
 
     /**
      * {@inheritdoc}
      */
     @Override
-    public void onAnimationCancel(Animatable animation) {
+    public void onAnimationCancel(Animator animation) {
     }
 
     /**
      * {@inheritdoc}
      */
     @Override
-    public void onAnimationEnd(Animatable animation) {
+    public void onAnimationEnd(Animator animation) {
     }
 
     /**
      * {@inheritdoc}
      */
     @Override
-    public void onAnimationRepeat(Animatable animation) {
+    public void onAnimationRepeat(Animator animation) {
     }
 
     /**
      * {@inheritdoc}
      */
     @Override
-    public void onAnimationStart(Animatable animation) {
+    public void onAnimationStart(Animator animation) {
     }
 
 }
diff --git a/core/java/android/animation/Sequencer.java b/core/java/android/animation/AnimatorSet.java
similarity index 72%
rename from core/java/android/animation/Sequencer.java
rename to core/java/android/animation/AnimatorSet.java
index 04bede0..a8385e4 100644
--- a/core/java/android/animation/Sequencer.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -16,35 +16,31 @@
 
 package android.animation;
 
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 
 /**
- * This class plays a set of {@link Animatable} objects in the specified order. Animations
+ * This class plays a set of {@link Animator} objects in the specified order. Animations
  * can be set up to play together, in sequence, or after a specified delay.
  *
- * <p>There are two different approaches to adding animations to a <code>Sequencer</code>:
- * either the {@link Sequencer#playTogether(Animatable[]) playTogether()} or
- * {@link Sequencer#playSequentially(Animatable[]) playSequentially()} methods can be called to add
- * a set of animations all at once, or the {@link Sequencer#play(Animatable)} can be
- * used in conjunction with methods in the {@link android.animation.Sequencer.Builder Builder}
+ * <p>There are two different approaches to adding animations to a <code>AnimatorSet</code>:
+ * either the {@link AnimatorSet#playTogether(Animator[]) playTogether()} or
+ * {@link AnimatorSet#playSequentially(Animator[]) playSequentially()} methods can be called to add
+ * a set of animations all at once, or the {@link AnimatorSet#play(Animator)} can be
+ * used in conjunction with methods in the {@link AnimatorSet.Builder Builder}
  * class to add animations
  * one by one.</p>
  *
- * <p>It is possible to set up a <code>Sequencer</code> with circular dependencies between
+ * <p>It is possible to set up a <code>AnimatorSet</code> with circular dependencies between
  * its animations. For example, an animation a1 could be set up to start before animation a2, a2
  * before a3, and a3 before a1. The results of this configuration are undefined, but will typically
  * result in none of the affected animations being played. Because of this (and because
  * circular dependencies do not make logical sense anyway), circular dependencies
  * should be avoided, and the dependency flow of animations should only be in one direction.
  */
-public final class Sequencer extends Animatable {
+public final class AnimatorSet extends Animator {
 
     /**
      * Internal variables
@@ -55,21 +51,21 @@
 
     /**
      * Tracks animations currently being played, so that we know what to
-     * cancel or end when cancel() or end() is called on this Sequencer
+     * cancel or end when cancel() or end() is called on this AnimatorSet
      */
-    private ArrayList<Animatable> mPlayingSet = new ArrayList<Animatable>();
+    private ArrayList<Animator> mPlayingSet = new ArrayList<Animator>();
 
     /**
-     * Contains all nodes, mapped to their respective Animatables. When new
-     * dependency information is added for an Animatable, we want to add it
-     * to a single node representing that Animatable, not create a new Node
+     * Contains all nodes, mapped to their respective Animators. When new
+     * dependency information is added for an Animator, we want to add it
+     * to a single node representing that Animator, not create a new Node
      * if one already exists.
      */
-    private HashMap<Animatable, Node> mNodeMap = new HashMap<Animatable, Node>();
+    private HashMap<Animator, Node> mNodeMap = new HashMap<Animator, Node>();
 
     /**
-     * Set of all nodes created for this Sequencer. This list is used upon
-     * starting the sequencer, and the nodes are placed in sorted order into the
+     * Set of all nodes created for this AnimatorSet. This list is used upon
+     * starting the set, and the nodes are placed in sorted order into the
      * sortedNodes collection.
      */
     private ArrayList<Node> mNodes = new ArrayList<Node>();
@@ -88,12 +84,12 @@
      */
     private boolean mNeedsSort = true;
 
-    private SequencerAnimatableListener mSequenceListener = null;
+    private AnimatorSetListener mSetListener = null;
 
     /**
-     * Flag indicating that the Sequencer has been canceled (by calling cancel() or end()).
+     * Flag indicating that the AnimatorSet has been canceled (by calling cancel() or end()).
      * This flag is used to avoid starting other animations when currently-playing
-     * child animations of this Sequencer end.
+     * child animations of this AnimatorSet end.
      */
     boolean mCanceled = false;
 
@@ -102,55 +98,55 @@
 
 
     // How long the child animations should last in ms. The default value is negative, which
-    // simply means that there is no duration set on the Sequencer. When a real duration is
+    // simply means that there is no duration set on the AnimatorSet. When a real duration is
     // set, it is passed along to the child animations.
     private long mDuration = -1;
 
 
     /**
-     * Sets up this Sequencer to play all of the supplied animations at the same time.
+     * Sets up this AnimatorSet to play all of the supplied animations at the same time.
      *
-     * @param sequenceItems The animations that will be started simultaneously.
+     * @param items The animations that will be started simultaneously.
      */
-    public void playTogether(Animatable... sequenceItems) {
-        if (sequenceItems != null) {
+    public void playTogether(Animator... items) {
+        if (items != null) {
             mNeedsSort = true;
-            Builder builder = play(sequenceItems[0]);
-            for (int i = 1; i < sequenceItems.length; ++i) {
-                builder.with(sequenceItems[i]);
+            Builder builder = play(items[0]);
+            for (int i = 1; i < items.length; ++i) {
+                builder.with(items[i]);
             }
         }
     }
 
     /**
-     * Sets up this Sequencer to play each of the supplied animations when the
+     * Sets up this AnimatorSet to play each of the supplied animations when the
      * previous animation ends.
      *
-     * @param sequenceItems The aniamtions that will be started one after another.
+     * @param items The aniamtions that will be started one after another.
      */
-    public void playSequentially(Animatable... sequenceItems) {
-        if (sequenceItems != null) {
+    public void playSequentially(Animator... items) {
+        if (items != null) {
             mNeedsSort = true;
-            if (sequenceItems.length == 1) {
-                play(sequenceItems[0]);
+            if (items.length == 1) {
+                play(items[0]);
             } else {
-                for (int i = 0; i < sequenceItems.length - 1; ++i) {
-                    play(sequenceItems[i]).before(sequenceItems[i+1]);
+                for (int i = 0; i < items.length - 1; ++i) {
+                    play(items[i]).before(items[i+1]);
                 }
             }
         }
     }
 
     /**
-     * Returns the current list of child Animatable objects controlled by this
-     * Sequencer. This is a copy of the internal list; modifications to the returned list
-     * will not affect the Sequencer, although changes to the underlying Animatable objects
-     * will affect those objects being managed by the Sequencer.
+     * Returns the current list of child Animator objects controlled by this
+     * AnimatorSet. This is a copy of the internal list; modifications to the returned list
+     * will not affect the AnimatorSet, although changes to the underlying Animator objects
+     * will affect those objects being managed by the AnimatorSet.
      *
-     * @return ArrayList<Animatable> The list of child animations of this Sequencer.
+     * @return ArrayList<Animator> The list of child animations of this AnimatorSet.
      */
-    public ArrayList<Animatable> getChildAnimations() {
-        ArrayList<Animatable> childList = new ArrayList<Animatable>();
+    public ArrayList<Animator> getChildAnimations() {
+        ArrayList<Animator> childList = new ArrayList<Animator>();
         for (Node node : mNodes) {
             childList.add(node.animation);
         }
@@ -159,28 +155,28 @@
 
     /**
      * Sets the target object for all current {@link #getChildAnimations() child animations}
-     * of this Sequencer that take targets ({@link android.animation.PropertyAnimator} and
-     * Sequencer).
+     * of this AnimatorSet that take targets ({@link ObjectAnimator} and
+     * AnimatorSet).
      *
      * @param target The object being animated
      */
     @Override
     public void setTarget(Object target) {
         for (Node node : mNodes) {
-            Animatable animation = node.animation;
-            if (animation instanceof Sequencer) {
-                ((Sequencer)animation).setTarget(target);
-            } else if (animation instanceof PropertyAnimator) {
-                ((PropertyAnimator)animation).setTarget(target);
+            Animator animation = node.animation;
+            if (animation instanceof AnimatorSet) {
+                ((AnimatorSet)animation).setTarget(target);
+            } else if (animation instanceof ObjectAnimator) {
+                ((ObjectAnimator)animation).setTarget(target);
             }
         }
     }
 
     /**
      * Sets the Interpolator for all current {@link #getChildAnimations() child animations}
-     * of this Sequencer.
+     * of this AnimatorSet.
      *
-     * @param interpolator the interpolator to be used by each child animation of this Sequencer
+     * @param interpolator the interpolator to be used by each child animation of this AnimatorSet
      */
     @Override
     public void setInterpolator(Interpolator interpolator) {
@@ -194,11 +190,11 @@
      * set up playing constraints. This initial <code>play()</code> method
      * tells the <code>Builder</code> the animation that is the dependency for
      * the succeeding commands to the <code>Builder</code>. For example,
-     * calling <code>play(a1).with(a2)</code> sets up the Sequence to play
+     * calling <code>play(a1).with(a2)</code> sets up the AnimatorSet to play
      * <code>a1</code> and <code>a2</code> at the same time,
-     * <code>play(a1).before(a2)</code> sets up the Sequence to play
+     * <code>play(a1).before(a2)</code> sets up the AnimatorSet to play
      * <code>a1</code> first, followed by <code>a2</code>, and
-     * <code>play(a1).after(a2)</code> sets up the Sequence to play
+     * <code>play(a1).after(a2)</code> sets up the AnimatorSet to play
      * <code>a2</code> first, followed by <code>a1</code>.
      *
      * <p>Note that <code>play()</code> is the only way to tell the
@@ -213,11 +209,11 @@
      * @param anim The animation that is the dependency used in later calls to the
      * methods in the returned <code>Builder</code> object. A null parameter will result
      * in a null <code>Builder</code> return value.
-     * @return Builder The object that constructs the sequence based on the dependencies
+     * @return Builder The object that constructs the AnimatorSet based on the dependencies
      * outlined in the calls to <code>play</code> and the other methods in the
      * <code>Builder</code object.
      */
-    public Builder play(Animatable anim) {
+    public Builder play(Animator anim) {
         if (anim != null) {
             mNeedsSort = true;
             return new Builder(anim);
@@ -228,7 +224,7 @@
     /**
      * {@inheritDoc}
      *
-     * <p>Note that canceling a <code>Sequencer</code> also cancels all of the animations that it is
+     * <p>Note that canceling a <code>AnimatorSet</code> also cancels all of the animations that it is
      * responsible for.</p>
      */
     @SuppressWarnings("unchecked")
@@ -236,9 +232,9 @@
     public void cancel() {
         mCanceled = true;
         if (mListeners != null) {
-            ArrayList<AnimatableListener> tmpListeners =
-                    (ArrayList<AnimatableListener>) mListeners.clone();
-            for (AnimatableListener listener : tmpListeners) {
+            ArrayList<AnimatorListener> tmpListeners =
+                    (ArrayList<AnimatorListener>) mListeners.clone();
+            for (AnimatorListener listener : tmpListeners) {
                 listener.onAnimationCancel(this);
             }
         }
@@ -252,7 +248,7 @@
     /**
      * {@inheritDoc}
      *
-     * <p>Note that ending a <code>Sequencer</code> also ends all of the animations that it is
+     * <p>Note that ending a <code>AnimatorSet</code> also ends all of the animations that it is
      * responsible for.</p>
      */
     @Override
@@ -262,10 +258,10 @@
             // hasn't been started yet - sort the nodes now, then end them
             sortNodes();
             for (Node node : mSortedNodes) {
-                if (mSequenceListener == null) {
-                    mSequenceListener = new SequencerAnimatableListener(this);
+                if (mSetListener == null) {
+                    mSetListener = new AnimatorSetListener(this);
                 }
-                node.animation.addListener(mSequenceListener);
+                node.animation.addListener(mSetListener);
             }
         }
         if (mSortedNodes.size() > 0) {
@@ -276,9 +272,9 @@
     }
 
     /**
-     * Returns true if any of the child animations of this Sequencer have been started and have not
+     * Returns true if any of the child animations of this AnimatorSet have been started and have not
      * yet ended.
-     * @return Whether this Sequencer has been started and has not yet ended.
+     * @return Whether this AnimatorSet has been started and has not yet ended.
      */
     @Override
     public boolean isRunning() {
@@ -313,12 +309,12 @@
     }
 
     /**
-     * Gets the length of each of the child animations of this Sequencer. This value may
-     * be less than 0, which indicates that no duration has been set on this Sequencer
+     * Gets the length of each of the child animations of this AnimatorSet. This value may
+     * be less than 0, which indicates that no duration has been set on this AnimatorSet
      * and each of the child animations will use their own duration.
      *
      * @return The length of the animation, in milliseconds, of each of the child
-     * animations of this Sequencer.
+     * animations of this AnimatorSet.
      */
     @Override
     public long getDuration() {
@@ -326,12 +322,12 @@
     }
 
     /**
-     * Sets the length of each of the current child animations of this Sequencer. By default,
-     * each child animation will use its own duration. If the duration is set on the Sequencer,
+     * Sets the length of each of the current child animations of this AnimatorSet. By default,
+     * each child animation will use its own duration. If the duration is set on the AnimatorSet,
      * then each child animation inherits this duration.
      *
      * @param duration The length of the animation, in milliseconds, of each of the child
-     * animations of this Sequencer.
+     * animations of this AnimatorSet.
      */
     @Override
     public void setDuration(long duration) {
@@ -339,7 +335,7 @@
             throw new IllegalArgumentException("duration must be a value of zero or greater");
         }
         for (Node node : mNodes) {
-            // TODO: don't set the duration of the timing-only nodes created by Sequencer to
+            // TODO: don't set the duration of the timing-only nodes created by AnimatorSet to
             // insert "play-after" delays
             node.animation.setDuration(duration);
         }
@@ -349,7 +345,7 @@
     /**
      * {@inheritDoc}
      *
-     * <p>Starting this <code>Sequencer</code> will, in turn, start the animations for which
+     * <p>Starting this <code>AnimatorSet</code> will, in turn, start the animations for which
      * it is responsible. The details of when exactly those animations are started depends on
      * the dependency relationships that have been set up between the animations.
      */
@@ -368,8 +364,8 @@
         // when some other animation also wants to start when the first animation begins.
         final ArrayList<Node> nodesToStart = new ArrayList<Node>();
         for (Node node : mSortedNodes) {
-            if (mSequenceListener == null) {
-                mSequenceListener = new SequencerAnimatableListener(this);
+            if (mSetListener == null) {
+                mSetListener = new AnimatorSetListener(this);
             }
             if (node.dependencies == null || node.dependencies.size() == 0) {
                 nodesToStart.add(node);
@@ -380,7 +376,7 @@
                 }
                 node.tmpDependencies = (ArrayList<Dependency>) node.dependencies.clone();
             }
-            node.animation.addListener(mSequenceListener);
+            node.animation.addListener(mSetListener);
         }
         // Now that all dependencies are set up, start the animations that should be started.
         if (mStartDelay <= 0) {
@@ -390,9 +386,9 @@
             }
         } else {
             // TODO: Need to cancel out of the delay appropriately
-            Animator delayAnim = new Animator(mStartDelay, 0f, 1f);
-            delayAnim.addListener(new AnimatableListenerAdapter() {
-                public void onAnimationEnd(Animatable anim) {
+            ValueAnimator delayAnim = new ValueAnimator(mStartDelay, 0f, 1f);
+            delayAnim.addListener(new AnimatorListenerAdapter() {
+                public void onAnimationEnd(Animator anim) {
                     for (Node node : nodesToStart) {
                         node.animation.start();
                         mPlayingSet.add(node.animation);
@@ -401,20 +397,20 @@
             });
         }
         if (mListeners != null) {
-            ArrayList<AnimatableListener> tmpListeners =
-                    (ArrayList<AnimatableListener>) mListeners.clone();
-            for (AnimatableListener listener : tmpListeners) {
+            ArrayList<AnimatorListener> tmpListeners =
+                    (ArrayList<AnimatorListener>) mListeners.clone();
+            for (AnimatorListener listener : tmpListeners) {
                 listener.onAnimationStart(this);
             }
         }
     }
 
     @Override
-    public Sequencer clone() {
-        final Sequencer anim = (Sequencer) super.clone();
+    public AnimatorSet clone() {
+        final AnimatorSet anim = (AnimatorSet) super.clone();
         /*
          * The basic clone() operation copies all items. This doesn't work very well for
-         * Sequencer, because it will copy references that need to be recreated and state
+         * AnimatorSet, because it will copy references that need to be recreated and state
          * that may not apply. What we need to do now is put the clone in an uninitialized
          * state, with fresh, empty data structures. Then we will build up the nodes list
          * manually, as we clone each Node (and its animation). The clone will then be sorted,
@@ -422,13 +418,13 @@
          */
         anim.mNeedsSort = true;
         anim.mCanceled = false;
-        anim.mPlayingSet = new ArrayList<Animatable>();
-        anim.mNodeMap = new HashMap<Animatable, Node>();
+        anim.mPlayingSet = new ArrayList<Animator>();
+        anim.mNodeMap = new HashMap<Animator, Node>();
         anim.mNodes = new ArrayList<Node>();
         anim.mSortedNodes = new ArrayList<Node>();
 
         // Walk through the old nodes list, cloning each node and adding it to the new nodemap.
-        // One problem is that the old node dependencies point to nodes in the old sequencer.
+        // One problem is that the old node dependencies point to nodes in the old AnimatorSet.
         // We need to track the old/new nodes in order to reconstruct the dependencies in the clone.
         HashMap<Node, Node> nodeCloneMap = new HashMap<Node, Node>(); // <old, new>
         for (Node node : mNodes) {
@@ -441,21 +437,21 @@
             nodeClone.tmpDependencies = null;
             nodeClone.nodeDependents = null;
             nodeClone.nodeDependencies = null;
-            // clear out any listeners that were set up by the sequencer; these will
+            // clear out any listeners that were set up by the AnimatorSet; these will
             // be set up when the clone's nodes are sorted
-            ArrayList<AnimatableListener> cloneListeners = nodeClone.animation.getListeners();
+            ArrayList<AnimatorListener> cloneListeners = nodeClone.animation.getListeners();
             if (cloneListeners != null) {
-                ArrayList<AnimatableListener> listenersToRemove = null;
-                for (AnimatableListener listener : cloneListeners) {
-                    if (listener instanceof SequencerAnimatableListener) {
+                ArrayList<AnimatorListener> listenersToRemove = null;
+                for (AnimatorListener listener : cloneListeners) {
+                    if (listener instanceof AnimatorSetListener) {
                         if (listenersToRemove == null) {
-                            listenersToRemove = new ArrayList<AnimatableListener>();
+                            listenersToRemove = new ArrayList<AnimatorListener>();
                         }
                         listenersToRemove.add(listener);
                     }
                 }
                 if (listenersToRemove != null) {
-                    for (AnimatableListener listener : listenersToRemove) {
+                    for (AnimatorListener listener : listenersToRemove) {
                         cloneListeners.remove(listener);
                     }
                 }
@@ -483,9 +479,9 @@
      * animations. If an animation has multiple dependencies on other animations, then
      * all dependencies must be satisfied before the animation is started.
      */
-    private static class DependencyListener implements AnimatableListener {
+    private static class DependencyListener implements AnimatorListener {
 
-        private Sequencer mSequencer;
+        private AnimatorSet mAnimatorSet;
 
         // The node upon which the dependency is based.
         private Node mNode;
@@ -494,8 +490,8 @@
         // the node
         private int mRule;
 
-        public DependencyListener(Sequencer sequencer, Node node, int rule) {
-            this.mSequencer = sequencer;
+        public DependencyListener(AnimatorSet animatorSet, Node node, int rule) {
+            this.mAnimatorSet = animatorSet;
             this.mNode = node;
             this.mRule = rule;
         }
@@ -505,13 +501,13 @@
          * to prevent follow-on animations from running when some dependency
          * animation is canceled.
          */
-        public void onAnimationCancel(Animatable animation) {
+        public void onAnimationCancel(Animator animation) {
         }
 
         /**
          * An end event is received - see if this is an event we are listening for
          */
-        public void onAnimationEnd(Animatable animation) {
+        public void onAnimationEnd(Animator animation) {
             if (mRule == Dependency.AFTER) {
                 startIfReady(animation);
             }
@@ -520,13 +516,13 @@
         /**
          * Ignore repeat events for now
          */
-        public void onAnimationRepeat(Animatable animation) {
+        public void onAnimationRepeat(Animator animation) {
         }
 
         /**
          * A start event is received - see if this is an event we are listening for
          */
-        public void onAnimationStart(Animatable animation) {
+        public void onAnimationStart(Animator animation) {
             if (mRule == Dependency.WITH) {
                 startIfReady(animation);
             }
@@ -538,9 +534,9 @@
          * the animation.
          * @param dependencyAnimation the animation that sent the event.
          */
-        private void startIfReady(Animatable dependencyAnimation) {
-            if (mSequencer.mCanceled) {
-                // if the parent Sequencer was canceled, then don't start any dependent anims
+        private void startIfReady(Animator dependencyAnimation) {
+            if (mAnimatorSet.mCanceled) {
+                // if the parent AnimatorSet was canceled, then don't start any dependent anims
                 return;
             }
             Dependency dependencyToRemove = null;
@@ -558,37 +554,37 @@
             if (mNode.tmpDependencies.size() == 0) {
                 // all dependencies satisfied: start the animation
                 mNode.animation.start();
-                mSequencer.mPlayingSet.add(mNode.animation);
+                mAnimatorSet.mPlayingSet.add(mNode.animation);
             }
         }
 
     }
 
-    private class SequencerAnimatableListener implements AnimatableListener {
+    private class AnimatorSetListener implements AnimatorListener {
 
-        private Sequencer mSequencer;
+        private AnimatorSet mAnimatorSet;
 
-        SequencerAnimatableListener(Sequencer sequencer) {
-            mSequencer = sequencer;
+        AnimatorSetListener(AnimatorSet animatorSet) {
+            mAnimatorSet = animatorSet;
         }
 
-        public void onAnimationCancel(Animatable animation) {
+        public void onAnimationCancel(Animator animation) {
             if (mPlayingSet.size() == 0) {
                 if (mListeners != null) {
-                    for (AnimatableListener listener : mListeners) {
-                        listener.onAnimationCancel(mSequencer);
+                    for (AnimatorListener listener : mListeners) {
+                        listener.onAnimationCancel(mAnimatorSet);
                     }
                 }
             }
         }
 
         @SuppressWarnings("unchecked")
-        public void onAnimationEnd(Animatable animation) {
+        public void onAnimationEnd(Animator animation) {
             animation.removeListener(this);
             mPlayingSet.remove(animation);
-            Node animNode = mSequencer.mNodeMap.get(animation);
+            Node animNode = mAnimatorSet.mNodeMap.get(animation);
             animNode.done = true;
-            ArrayList<Node> sortedNodes = mSequencer.mSortedNodes;
+            ArrayList<Node> sortedNodes = mAnimatorSet.mSortedNodes;
             boolean allDone = true;
             for (Node node : sortedNodes) {
                 if (!node.done) {
@@ -598,23 +594,23 @@
             }
             if (allDone) {
                 // If this was the last child animation to end, then notify listeners that this
-                // sequencer has ended
+                // AnimatorSet has ended
                 if (mListeners != null) {
-                    ArrayList<AnimatableListener> tmpListeners =
-                            (ArrayList<AnimatableListener>) mListeners.clone();
-                    for (AnimatableListener listener : tmpListeners) {
-                        listener.onAnimationEnd(mSequencer);
+                    ArrayList<AnimatorListener> tmpListeners =
+                            (ArrayList<AnimatorListener>) mListeners.clone();
+                    for (AnimatorListener listener : tmpListeners) {
+                        listener.onAnimationEnd(mAnimatorSet);
                     }
                 }
             }
         }
 
         // Nothing to do
-        public void onAnimationRepeat(Animatable animation) {
+        public void onAnimationRepeat(Animator animation) {
         }
 
         // Nothing to do
-        public void onAnimationStart(Animatable animation) {
+        public void onAnimationStart(Animator animation) {
         }
 
     }
@@ -658,7 +654,7 @@
             mNeedsSort = false;
             if (mSortedNodes.size() != mNodes.size()) {
                 throw new IllegalStateException("Circular dependencies cannot exist"
-                        + " in Sequencer");
+                        + " in AnimatorSet");
             }
         } else {
             // Doesn't need sorting, but still need to add in the nodeDependencies list
@@ -702,13 +698,13 @@
     }
 
     /**
-     * A Node is an embodiment of both the Animatable that it wraps as well as
+     * A Node is an embodiment of both the Animator that it wraps as well as
      * any dependencies that are associated with that Animation. This includes
      * both dependencies upon other nodes (in the dependencies list) as
      * well as dependencies of other nodes upon this (in the nodeDependents list).
      */
     private static class Node implements Cloneable {
-        public Animatable animation;
+        public Animator animation;
 
         /**
          *  These are the dependencies that this node's animation has on other
@@ -723,8 +719,8 @@
          * But we also use the list to keep track of when multiple dependencies are satisfied,
          * but removing each dependency as it is satisfied. We do not want to remove
          * the dependency itself from the list, because we need to retain that information
-         * if the sequencer is launched in the future. So we create a copy of the dependency
-         * list when the sequencer starts and use this tmpDependencies list to track the
+         * if the AnimatorSet is launched in the future. So we create a copy of the dependency
+         * list when the AnimatorSet starts and use this tmpDependencies list to track the
          * list of satisfied dependencies.
          */
         public ArrayList<Dependency> tmpDependencies = null;
@@ -744,8 +740,8 @@
 
         /**
          * Flag indicating whether the animation in this node is finished. This flag
-         * is used by Sequencer to check, as each animation ends, whether all child animations
-         * are done and it's time to send out an end event for the entire Sequencer.
+         * is used by AnimatorSet to check, as each animation ends, whether all child animations
+         * are done and it's time to send out an end event for the entire AnimatorSet.
          */
         public boolean done = false;
 
@@ -756,7 +752,7 @@
          *
          * @param animation The animation that the Node encapsulates.
          */
-        public Node(Animatable animation) {
+        public Node(Animator animation) {
             this.animation = animation;
         }
 
@@ -785,7 +781,7 @@
         public Node clone() {
             try {
                 Node node = (Node) super.clone();
-                node.animation = (Animatable) animation.clone();
+                node.animation = (Animator) animation.clone();
                 return node;
             } catch (CloneNotSupportedException e) {
                throw new AssertionError();
@@ -795,45 +791,45 @@
 
     /**
      * The <code>Builder</code> object is a utility class to facilitate adding animations to a
-     * <code>Sequencer</code> along with the relationships between the various animations. The
+     * <code>AnimatorSet</code> along with the relationships between the various animations. The
      * intention of the <code>Builder</code> methods, along with the {@link
-     * Sequencer#play(Animatable) play()} method of <code>Sequencer</code> is to make it possible to
+     * AnimatorSet#play(Animator) play()} method of <code>AnimatorSet</code> is to make it possible to
      * express the dependency relationships of animations in a natural way. Developers can also use
-     * the {@link Sequencer#playTogether(Animatable[]) playTogether()} and {@link
-     * Sequencer#playSequentially(Animatable[]) playSequentially()} methods if these suit the need,
-     * but it might be easier in some situations to express the sequence of animations in pairs.
+     * the {@link AnimatorSet#playTogether(Animator[]) playTogether()} and {@link
+     * AnimatorSet#playSequentially(Animator[]) playSequentially()} methods if these suit the need,
+     * but it might be easier in some situations to express the AnimatorSet of animations in pairs.
      * <p/>
      * <p>The <code>Builder</code> object cannot be constructed directly, but is rather constructed
-     * internally via a call to {@link Sequencer#play(Animatable)}.</p>
+     * internally via a call to {@link AnimatorSet#play(Animator)}.</p>
      * <p/>
-     * <p>For example, this sets up a Sequencer to play anim1 and anim2 at the same time, anim3 to
+     * <p>For example, this sets up a AnimatorSet to play anim1 and anim2 at the same time, anim3 to
      * play when anim2 finishes, and anim4 to play when anim3 finishes:</p>
      * <pre>
-     *     Sequencer s = new Sequencer();
+     *     AnimatorSet s = new AnimatorSet();
      *     s.play(anim1).with(anim2);
      *     s.play(anim2).before(anim3);
      *     s.play(anim4).after(anim3);
      * </pre>
      * <p/>
-     * <p>Note in the example that both {@link Builder#before(Animatable)} and {@link
-     * Builder#after(Animatable)} are used. These are just different ways of expressing the same
+     * <p>Note in the example that both {@link Builder#before(Animator)} and {@link
+     * Builder#after(Animator)} are used. These are just different ways of expressing the same
      * relationship and are provided to make it easier to say things in a way that is more natural,
      * depending on the situation.</p>
      * <p/>
      * <p>It is possible to make several calls into the same <code>Builder</code> object to express
      * multiple relationships. However, note that it is only the animation passed into the initial
-     * {@link Sequencer#play(Animatable)} method that is the dependency in any of the successive
+     * {@link AnimatorSet#play(Animator)} method that is the dependency in any of the successive
      * calls to the <code>Builder</code> object. For example, the following code starts both anim2
      * and anim3 when anim1 ends; there is no direct dependency relationship between anim2 and
      * anim3:
      * <pre>
-     *   Sequencer s = new Sequencer();
+     *   AnimatorSet s = new AnimatorSet();
      *   s.play(anim1).before(anim2).before(anim3);
      * </pre>
      * If the desired result is to play anim1 then anim2 then anim3, this code expresses the
      * relationship correctly:</p>
      * <pre>
-     *   Sequencer s = new Sequencer();
+     *   AnimatorSet s = new AnimatorSet();
      *   s.play(anim1).before(anim2);
      *   s.play(anim2).before(anim3);
      * </pre>
@@ -841,26 +837,26 @@
      * <p>Note that it is possible to express relationships that cannot be resolved and will not
      * result in sensible results. For example, <code>play(anim1).after(anim1)</code> makes no
      * sense. In general, circular dependencies like this one (or more indirect ones where a depends
-     * on b, which depends on c, which depends on a) should be avoided. Only create sequences that
-     * can boil down to a simple, one-way relationship of animations starting with, before, and
+     * on b, which depends on c, which depends on a) should be avoided. Only create AnimatorSets
+     * that can boil down to a simple, one-way relationship of animations starting with, before, and
      * after other, different, animations.</p>
      */
     public class Builder {
 
         /**
          * This tracks the current node being processed. It is supplied to the play() method
-         * of Sequencer and passed into the constructor of Builder.
+         * of AnimatorSet and passed into the constructor of Builder.
          */
         private Node mCurrentNode;
 
         /**
-         * package-private constructor. Builders are only constructed by Sequencer, when the
+         * package-private constructor. Builders are only constructed by AnimatorSet, when the
          * play() method is called.
          *
          * @param anim The animation that is the dependency for the other animations passed into
          * the other methods of this Builder object.
          */
-        Builder(Animatable anim) {
+        Builder(Animator anim) {
             mCurrentNode = mNodeMap.get(anim);
             if (mCurrentNode == null) {
                 mCurrentNode = new Node(anim);
@@ -871,12 +867,12 @@
 
         /**
          * Sets up the given animation to play at the same time as the animation supplied in the
-         * {@link Sequencer#play(Animatable)} call that created this <code>Builder</code> object.
+         * {@link AnimatorSet#play(Animator)} call that created this <code>Builder</code> object.
          *
          * @param anim The animation that will play when the animation supplied to the
-         * {@link Sequencer#play(Animatable)} method starts.
+         * {@link AnimatorSet#play(Animator)} method starts.
          */
-        public void with(Animatable anim) {
+        public void with(Animator anim) {
             Node node = mNodeMap.get(anim);
             if (node == null) {
                 node = new Node(anim);
@@ -889,13 +885,13 @@
 
         /**
          * Sets up the given animation to play when the animation supplied in the
-         * {@link Sequencer#play(Animatable)} call that created this <code>Builder</code> object
+         * {@link AnimatorSet#play(Animator)} call that created this <code>Builder</code> object
          * ends.
          *
          * @param anim The animation that will play when the animation supplied to the
-         * {@link Sequencer#play(Animatable)} method ends.
+         * {@link AnimatorSet#play(Animator)} method ends.
          */
-        public void before(Animatable anim) {
+        public void before(Animator anim) {
             Node node = mNodeMap.get(anim);
             if (node == null) {
                 node = new Node(anim);
@@ -908,13 +904,13 @@
 
         /**
          * Sets up the given animation to play when the animation supplied in the
-         * {@link Sequencer#play(Animatable)} call that created this <code>Builder</code> object
+         * {@link AnimatorSet#play(Animator)} call that created this <code>Builder</code> object
          * to start when the animation supplied in this method call ends.
          *
          * @param anim The animation whose end will cause the animation supplied to the
-         * {@link Sequencer#play(Animatable)} method to play.
+         * {@link AnimatorSet#play(Animator)} method to play.
          */
-        public void after(Animatable anim) {
+        public void after(Animator anim) {
             Node node = mNodeMap.get(anim);
             if (node == null) {
                 node = new Node(anim);
@@ -927,15 +923,15 @@
 
         /**
          * Sets up the animation supplied in the
-         * {@link Sequencer#play(Animatable)} call that created this <code>Builder</code> object
+         * {@link AnimatorSet#play(Animator)} call that created this <code>Builder</code> object
          * to play when the given amount of time elapses.
          *
          * @param delay The number of milliseconds that should elapse before the
          * animation starts.
          */
         public void after(long delay) {
-            // setup dummy Animator just to run the clock
-            after(new Animator(delay, 0f, 1f));
+            // setup dummy ValueAnimator just to run the clock
+            after(new ValueAnimator(delay, 0f, 1f));
         }
 
     }
diff --git a/core/java/android/animation/Keyframe.java b/core/java/android/animation/Keyframe.java
index 7d4d104..192ba5c 100644
--- a/core/java/android/animation/Keyframe.java
+++ b/core/java/android/animation/Keyframe.java
@@ -20,7 +20,7 @@
 
 /**
  * This class holds a time/value pair for an animation. The Keyframe class is used
- * by {@link Animator} to define the values that the animation target will have over the course
+ * by {@link ValueAnimator} to define the values that the animation target will have over the course
  * of the animation. As the time proceeds from one keyframe to the other, the value of the
  * target object will animate between the value at the previous keyframe and the value at the
  * next keyframe. Each keyframe also holds an option {@link android.view.animation.Interpolator}
@@ -59,7 +59,7 @@
      * the time in this keyframe, and the the value animated from as the time passes the time in
      * this keyframe.
      * @param valueType The type of the <code>value</code> object. This is used by the
-     * {@link #getValue()} functionm, which is queried by {@link Animator} to determine
+     * {@link #getValue()} functionm, which is queried by {@link ValueAnimator} to determine
      * the type of {@link TypeEvaluator} to use to interpolate between values.
      */
     private Keyframe(float fraction, Object value, Class valueType) {
@@ -239,7 +239,7 @@
     }
 
     /**
-     * Gets the type of keyframe. This information is used by Animator to determine the type of
+     * Gets the type of keyframe. This information is used by ValueAnimator to determine the type of
      * {@link TypeEvaluator} to use when calculating values between keyframes. The type is based
      * on the type of Keyframe created.
      *
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
index d144b9c..af47a15 100644
--- a/core/java/android/animation/KeyframeSet.java
+++ b/core/java/android/animation/KeyframeSet.java
@@ -21,7 +21,7 @@
 import android.view.animation.Interpolator;
 
 /**
- * This class holds a collection of Keyframe objects and is called by Animator to calculate
+ * This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate
  * values between those keyframes for a given animation. The class internal to the animation
  * package because it is an implementation detail of how Keyframes are stored and used.
  */
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 5dfdfbd..d1bc9bd 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -32,8 +32,8 @@
  * transitions for a layout container, create a LayoutTransition object and set it on any
  * ViewGroup by calling {@link ViewGroup#setLayoutTransition(LayoutTransition)}. This will cause
  * default animations to run whenever items are added to or removed from that container. To specify
- * custom animations, use the {@link LayoutTransition#setAnimatable(int, Animatable)
- * setAnimatable()} method.
+ * custom animations, use the {@link LayoutTransition#setAnimator(int, Animator)
+ * setAnimator()} method.
  *
  * <p>One of the core concepts of these transition animations is that there are two core
  * changes that cause the transition and four different animations that run because of
@@ -61,7 +61,7 @@
  * CHANGE_APPEARING animation animates <code>left</code>, <code>top</code>, <code>right</code>,
  * and <code>bottom</code>. Values for these properties are updated with the pre- and post-layout
  * values when the transition begins. Custom animations will be similarly populated with
- * the target and values being animated, assuming they use PropertyAnimator objects with
+ * the target and values being animated, assuming they use ObjectAnimator objects with
  * property names that are known on the target object.</p>
  */
 public class LayoutTransition {
@@ -93,21 +93,21 @@
     /**
      * These variables hold the animations that are currently used to run the transition effects.
      * These animations are set to defaults, but can be changed to custom animations by
-     * calls to setAnimatable().
+     * calls to setAnimator().
      */
-    private Animatable mDisappearingAnim = null;
-    private Animatable mAppearingAnim = null;
-    private Animatable mChangingAppearingAnim = null;
-    private Animatable mChangingDisappearingAnim = null;
+    private Animator mDisappearingAnim = null;
+    private Animator mAppearingAnim = null;
+    private Animator mChangingAppearingAnim = null;
+    private Animator mChangingDisappearingAnim = null;
 
     /**
      * These are the default animations, defined in the constructor, that will be used
      * unless the user specifies custom animations.
      */
-    private static PropertyAnimator defaultChangeIn;
-    private static PropertyAnimator defaultChangeOut;
-    private static PropertyAnimator defaultFadeIn;
-    private static PropertyAnimator defaultFadeOut;
+    private static ObjectAnimator defaultChangeIn;
+    private static ObjectAnimator defaultChangeOut;
+    private static ObjectAnimator defaultFadeIn;
+    private static ObjectAnimator defaultFadeOut;
 
     /**
      * The default duration used by all animations.
@@ -154,7 +154,7 @@
      * we cache all of the current animations in this map for possible cancellation on
      * another layout event.
      */
-    private HashMap<View, Animatable> currentAnimations = new HashMap<View, Animatable>();
+    private HashMap<View, Animator> currentAnimations = new HashMap<View, Animator>();
 
     /**
      * This hashmap is used to track the listeners that have been added to the children of
@@ -194,7 +194,7 @@
             PropertyValuesHolder<Integer> pvhTop = new PropertyValuesHolder<Integer>("top", 0, 1);
             PropertyValuesHolder<Integer> pvhRight = new PropertyValuesHolder<Integer>("right", 0, 1);
             PropertyValuesHolder<Integer> pvhBottom = new PropertyValuesHolder<Integer>("bottom", 0, 1);
-            defaultChangeIn = new PropertyAnimator<PropertyValuesHolder>(DEFAULT_DURATION, this,
+            defaultChangeIn = new ObjectAnimator<PropertyValuesHolder>(DEFAULT_DURATION, this,
                     pvhLeft, pvhTop, pvhRight, pvhBottom);
             defaultChangeIn.setStartDelay(mChangingAppearingDelay);
             defaultChangeIn.setInterpolator(mChangingAppearingInterpolator);
@@ -202,11 +202,11 @@
             defaultChangeOut.setStartDelay(mChangingDisappearingDelay);
             defaultChangeOut.setInterpolator(mChangingDisappearingInterpolator);
             defaultFadeIn =
-                    new PropertyAnimator<Float>(DEFAULT_DURATION, this, "alpha", 0f, 1f);
+                    new ObjectAnimator<Float>(DEFAULT_DURATION, this, "alpha", 0f, 1f);
             defaultFadeIn.setStartDelay(mAppearingDelay);
             defaultFadeIn.setInterpolator(mAppearingInterpolator);
             defaultFadeOut =
-                    new PropertyAnimator<Float>(DEFAULT_DURATION, this, "alpha", 1f, 0f);
+                    new ObjectAnimator<Float>(DEFAULT_DURATION, this, "alpha", 1f, 0f);
             defaultFadeOut.setStartDelay(mDisappearingDelay);
             defaultFadeOut.setInterpolator(mDisappearingInterpolator);
         }
@@ -240,7 +240,7 @@
      * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose start
      * delay is being set.
      * @param delay The length of time, in milliseconds, to delay before starting the animation.
-     * @see android.animation.Animatable#setStartDelay(long)
+     * @see Animator#setStartDelay(long)
      */
     public void setStartDelay(int transitionType, long delay) {
         switch (transitionType) {
@@ -268,7 +268,7 @@
      * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose start
      * delay is returned.
      * @return long The start delay of the specified animation.
-     * @see android.animation.Animatable#getStartDelay()
+     * @see Animator#getStartDelay()
      */
     public long getStartDelay(int transitionType) {
         switch (transitionType) {
@@ -294,7 +294,7 @@
      * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
      * duration is being set.
      * @param duration The length of time, in milliseconds, that the specified animation should run.
-     * @see android.animation.Animatable#setDuration(long)
+     * @see Animator#setDuration(long)
      */
     public void setDuration(int transitionType, long duration) {
         switch (transitionType) {
@@ -322,7 +322,7 @@
      * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
      * duration is returned.
      * @return long The duration of the specified animation.
-     * @see android.animation.Animatable#getDuration()
+     * @see Animator#getDuration()
      */
     public long getDuration(int transitionType) {
         switch (transitionType) {
@@ -387,7 +387,7 @@
      * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
      * duration is being set.
      * @param interpolator The interpolator that the specified animation should use.
-     * @see android.animation.Animatable#setInterpolator(android.view.animation.Interpolator)
+     * @see Animator#setInterpolator(android.view.animation.Interpolator)
      */
     public void setInterpolator(int transitionType, Interpolator interpolator) {
         switch (transitionType) {
@@ -415,7 +415,7 @@
      * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
      * duration is being set.
      * @return Interpolator The interpolator that the specified animation uses.
-     * @see android.animation.Animatable#setInterpolator(android.view.animation.Interpolator)
+     * @see Animator#setInterpolator(android.view.animation.Interpolator)
      */
     public Interpolator getInterpolator(int transitionType) {
         switch (transitionType) {
@@ -434,11 +434,11 @@
 
     /**
      * Sets the animation used during one of the transition types that may run. Any
-     * Animatable object can be used, but to be most useful in the context of layout
-     * transitions, the animation should either be a PropertyAnimator or a Sequencer
-     * of animations including PropertyAnimators. Also, these PropertyAnimator objects
+     * Animator object can be used, but to be most useful in the context of layout
+     * transitions, the animation should either be a ObjectAnimator or a AnimatorSet
+     * of animations including PropertyAnimators. Also, these ObjectAnimator objects
      * should be able to get and set values on their target objects automatically. For
-     * example, a PropertyAnimator that animates the property "left" is able to set and get the
+     * example, a ObjectAnimator that animates the property "left" is able to set and get the
      * <code>left</code> property from the View objects being animated by the layout
      * transition. The transition works by setting target objects and properties
      * dynamically, according to the pre- and post-layoout values of those objects, so
@@ -454,26 +454,26 @@
      * object (presumably 1) as its starting and ending value when the animation begins.
      * Animations which need to use values at the beginning and end that may not match the
      * values queried when the transition begins may need to use a different mechanism
-     * than a standard PropertyAnimator object.</p>
+     * than a standard ObjectAnimator object.</p>
      *
      * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
      * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
      * duration is being set.
-     * @param animatable The animation being assigned.
+     * @param animator The animation being assigned.
      */
-    public void setAnimatable(int transitionType, Animatable animatable) {
+    public void setAnimator(int transitionType, Animator animator) {
         switch (transitionType) {
             case CHANGE_APPEARING:
-                mChangingAppearingAnim = (animatable != null) ? animatable : defaultChangeIn;
+                mChangingAppearingAnim = (animator != null) ? animator : defaultChangeIn;
                 break;
             case CHANGE_DISAPPEARING:
-                mChangingDisappearingAnim = (animatable != null) ? animatable : defaultChangeOut;
+                mChangingDisappearingAnim = (animator != null) ? animator : defaultChangeOut;
                 break;
             case APPEARING:
-                mAppearingAnim = (animatable != null) ? animatable : defaultFadeIn;
+                mAppearingAnim = (animator != null) ? animator : defaultFadeIn;
                 break;
             case DISAPPEARING:
-                mDisappearingAnim = (animatable != null) ? animatable : defaultFadeOut;
+                mDisappearingAnim = (animator != null) ? animator : defaultFadeOut;
                 break;
         }
     }
@@ -484,10 +484,10 @@
      * @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
      * {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
      * duration is being set.
-     * @return Animatable The animation being used for the given transition type.
-     * @see #setAnimatable(int, Animatable)
+     * @return Animator The animation being used for the given transition type.
+     * @see #setAnimator(int, Animator)
      */
-    public Animatable getAnimatable(int transitionType) {
+    public Animator getAnimator(int transitionType) {
         switch (transitionType) {
             case CHANGE_APPEARING:
                 return mChangingAppearingAnim;
@@ -529,21 +529,21 @@
             if (child != newView) {
 
                 // If there's an animation running on this view already, cancel it
-                Animatable currentAnimation = currentAnimations.get(child);
+                Animator currentAnimation = currentAnimations.get(child);
                 if (currentAnimation != null) {
                     currentAnimation.cancel();
                     currentAnimations.remove(child);
                 }
 
                 // Make a copy of the appropriate animation
-                final Animatable anim = (changeReason == APPEARING) ?
+                final Animator anim = (changeReason == APPEARING) ?
                         mChangingAppearingAnim.clone() :
                         mChangingDisappearingAnim.clone();
 
                 // Set the target object for the animation
                 anim.setTarget(child);
 
-                // A PropertyAnimator (or Sequencer of them) can extract start values from
+                // A ObjectAnimator (or AnimatorSet of them) can extract start values from
                 // its target object
                 anim.setupStartValues();
 
@@ -574,20 +574,20 @@
                         anim.setDuration(duration);
 
                         // Remove the animation from the cache when it ends
-                        anim.addListener(new AnimatableListenerAdapter() {
+                        anim.addListener(new AnimatorListenerAdapter() {
                             private boolean canceled = false;
-                            public void onAnimationCancel(Animatable animatable) {
+                            public void onAnimationCancel(Animator animator) {
                                 // we remove canceled animations immediately, not here
                                 canceled = true;
                             }
-                            public void onAnimationEnd(Animatable animatable) {
+                            public void onAnimationEnd(Animator animator) {
                                 if (!canceled) {
                                     currentAnimations.remove(child);
                                 }
                             }
                         });
-                        if (anim instanceof PropertyAnimator) {
-                            ((PropertyAnimator) anim).setCurrentPlayTime(0);
+                        if (anim instanceof ObjectAnimator) {
+                            ((ObjectAnimator) anim).setCurrentPlayTime(0);
                         }
                         anim.start();
 
@@ -626,15 +626,15 @@
      * @param child The View being added to the ViewGroup.
      */
     private void runAppearingTransition(final ViewGroup parent, final View child) {
-        Animatable anim = mAppearingAnim.clone();
+        Animator anim = mAppearingAnim.clone();
         anim.setTarget(child);
         anim.setStartDelay(mAppearingDelay);
         anim.setDuration(mAppearingDuration);
-        if (anim instanceof PropertyAnimator) {
-            ((PropertyAnimator) anim).setCurrentPlayTime(0);
+        if (anim instanceof ObjectAnimator) {
+            ((ObjectAnimator) anim).setCurrentPlayTime(0);
         }
         if (mListeners != null) {
-            anim.addListener(new AnimatableListenerAdapter() {
+            anim.addListener(new AnimatorListenerAdapter() {
                 public void onAnimationEnd() {
                     for (TransitionListener listener : mListeners) {
                         listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
@@ -652,12 +652,12 @@
      * @param child The View being removed from the ViewGroup.
      */
     private void runDisappearingTransition(final ViewGroup parent, final View child) {
-        Animatable anim = mDisappearingAnim.clone();
+        Animator anim = mDisappearingAnim.clone();
         anim.setStartDelay(mDisappearingDelay);
         anim.setDuration(mDisappearingDuration);
         anim.setTarget(child);
         if (mListeners != null) {
-            anim.addListener(new AnimatableListenerAdapter() {
+            anim.addListener(new AnimatorListenerAdapter() {
                 public void onAnimationEnd() {
                     for (TransitionListener listener : mListeners) {
                         listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
@@ -665,8 +665,8 @@
                 }
             });
         }
-        if (anim instanceof PropertyAnimator) {
-            ((PropertyAnimator) anim).setCurrentPlayTime(0);
+        if (anim instanceof ObjectAnimator) {
+            ((ObjectAnimator) anim).setCurrentPlayTime(0);
         }
         anim.start();
     }
diff --git a/core/java/android/animation/PropertyAnimator.java b/core/java/android/animation/ObjectAnimator.java
similarity index 92%
rename from core/java/android/animation/PropertyAnimator.java
rename to core/java/android/animation/ObjectAnimator.java
index e555cc6..6cb90be 100644
--- a/core/java/android/animation/PropertyAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -21,13 +21,13 @@
 import java.lang.reflect.Method;
 
 /**
- * This subclass of {@link Animator} provides support for animating properties on target objects.
+ * This subclass of {@link ValueAnimator} provides support for animating properties on target objects.
  * The constructors of this class take parameters to define the target object that will be animated
  * as well as the name of the property that will be animated. Appropriate set/get functions
  * are then determined internally and the animation will call these functions as necessary to
  * animate the property.
  */
-public final class PropertyAnimator<T> extends Animator<T> {
+public final class ObjectAnimator<T> extends ValueAnimator<T> {
 
     // The target object on which the property exists, set in the constructor
     private Object mTarget;
@@ -47,7 +47,7 @@
      * <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to
      * the setter function will fail.</p>
      *
-     * <p>If this PropertyAnimator has been set up to animate several properties together,
+     * <p>If this ObjectAnimator has been set up to animate several properties together,
      * using more than one PropertyValuesHolder objects, then setting the propertyName simply
      * sets the propertyName in the first of those PropertyValuesHolder objects.</p>
      *
@@ -101,18 +101,18 @@
         try {
             returnVal = mTarget.getClass().getMethod(setterName, args);
         } catch (NoSuchMethodException e) {
-            Log.e("PropertyAnimator",
+            Log.e("ObjectAnimator",
                     "Couldn't find setter/getter for property " + mPropertyName + ": " + e);
         }
         return returnVal;
     }
 
     /**
-     * Creates a new PropertyAnimator object. This default constructor is primarily for
+     * Creates a new ObjectAnimator object. This default constructor is primarily for
      * use internally; the other constructors which take parameters are more generally
      * useful.
      */
-    public PropertyAnimator() {
+    public ObjectAnimator() {
     }
 
     /**
@@ -128,7 +128,7 @@
      * is assumed to be the final value being animated to, and the initial value will be
      * derived on the fly.
      */
-    public PropertyAnimator(long duration, Object target, String propertyName, T...values) {
+    public ObjectAnimator(long duration, Object target, String propertyName, T...values) {
         super(duration, (T[]) values);
         mTarget = target;
         setPropertyName(propertyName);
@@ -136,7 +136,7 @@
 
     /**
      * A constructor that takes <code>PropertyValueHolder</code> values. This constructor should
-     * be used when animating several properties at once with the same PropertyAnimator, since
+     * be used when animating several properties at once with the same ObjectAnimator, since
      * PropertyValuesHolder allows you to associate a set of animation values with a property
      * name.
      *
@@ -148,7 +148,7 @@
      * @param values The PropertyValuesHolder objects which hold each the property name and values
      * to animate that property between.
      */
-    public PropertyAnimator(long duration, Object target, PropertyValuesHolder...values) {
+    public ObjectAnimator(long duration, Object target, PropertyValuesHolder...values) {
         super(duration);
         setValues(values);
         mTarget = target;
@@ -239,8 +239,8 @@
     }
 
     @Override
-    public PropertyAnimator clone() {
-        final PropertyAnimator anim = (PropertyAnimator) super.clone();
+    public ObjectAnimator clone() {
+        final ObjectAnimator anim = (ObjectAnimator) super.clone();
         return anim;
     }
 }
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index b6ff54e..1d46123 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -27,31 +27,31 @@
 /**
  * This class holds information about a property and the values that that property
  * should take on during an animation. PropertyValuesHolder objects can be used to create
- * animations with Animator or PropertyAnimator that operate on several different properties
+ * animations with ValueAnimator or ObjectAnimator that operate on several different properties
  * in parallel.
  */
 public class PropertyValuesHolder<T> implements Cloneable {
 
     /**
      * The name of the property associated with the values. This need not be a real property,
-     * unless this object is being used with PropertyAnimator. But this is the name by which
-     * aniamted values are looked up with getAnimatedValue(String) in Animator.
+     * unless this object is being used with ObjectAnimator. But this is the name by which
+     * aniamted values are looked up with getAnimatedValue(String) in ValueAnimator.
      */
     private String mPropertyName;
 
     /**
-     * The setter function, if needed. PropertyAnimator hands off this functionality to
+     * The setter function, if needed. ObjectAnimator hands off this functionality to
      * PropertyValuesHolder, since it holds all of the per-property information. This
      * property can be manually set via setSetter(). Otherwise, it is automatically
-     * derived when the animation starts in setupSetterAndGetter() if using PropertyAnimator.
+     * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator.
      */
     private Method mSetter = null;
 
     /**
-     * The getter function, if needed. PropertyAnimator hands off this functionality to
+     * The getter function, if needed. ObjectAnimator hands off this functionality to
      * PropertyValuesHolder, since it holds all of the per-property information. This
      * property can be manually set via setSetter(). Otherwise, it is automatically
-     * derived when the animation starts in setupSetterAndGetter() if using PropertyAnimator.
+     * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator.
      * The getter is only derived and used if one of the values is null.
      */
     private Method mGetter = null;
@@ -112,16 +112,16 @@
 
     /**
      * The value most recently calculated by calculateValue(). This is set during
-     * that function and might be retrieved later either by Animator.animatedValue() or
-     * by the property-setting logic in PropertyAnimator.animatedValue().
+     * that function and might be retrieved later either by ValueAnimator.animatedValue() or
+     * by the property-setting logic in ObjectAnimator.animatedValue().
      */
     private Object mAnimatedValue;
 
     /**
      * Constructs a PropertyValuesHolder object with just a set of values. This constructor
-     * is typically not used when animating objects with PropertyAnimator, because that
+     * is typically not used when animating objects with ObjectAnimator, because that
      * object needs distinct and meaningful property names. Simpler animations of one
-     * set of values using Animator may use this constructor, however, because no
+     * set of values using ValueAnimator may use this constructor, however, because no
      * distinguishing name is needed.
      * @param values The set of values to animate between. If there is only one value, it
      * is assumed to be the final value being animated to, and the initial value will be
@@ -141,14 +141,14 @@
      * on the object. Also, if any value is null, the value will be filled in when the animation
      * starts in the same way. This mechanism of automatically getting null values only works
      * if the PropertyValuesHolder object is used in conjunction
-     * {@link android.animation.PropertyAnimator}, and with a getter function either
+     * {@link ObjectAnimator}, and with a getter function either
      * derived automatically from <code>propertyName</code> or set explicitly via
      * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
      * no way of determining what the value should be.
      * @param propertyName The name of the property associated with this set of values. This
-     * can be the actual property name to be used when using a PropertyAnimator object, or
+     * can be the actual property name to be used when using a ObjectAnimator object, or
      * just a name used to get animated values, such as if this object is used with an
-     * Animator object.
+     * ValueAnimator object.
      * @param values The set of values to animate between.
      */
     public PropertyValuesHolder(String propertyName, T... values) {
@@ -163,7 +163,7 @@
      * on the object. Also, if any value is null, the value will be filled in when the animation
      * starts in the same way. This mechanism of automatically getting null values only works
      * if the PropertyValuesHolder object is used in conjunction
-     * {@link android.animation.PropertyAnimator}, and with a getter function either
+     * {@link ObjectAnimator}, and with a getter function either
      * derived automatically from <code>propertyName</code> or set explicitly via
      * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
      * no way of determining what the value should be.
@@ -331,7 +331,7 @@
     }
 
     /**
-     * Internal function (called from PropertyAnimator) to set up the setter and getter
+     * Internal function (called from ObjectAnimator) to set up the setter and getter
      * prior to running the animation. If the setter has not been manually set for this
      * object, it will be derived automatically given the property name, target object, and
      * types of values supplied. If no getter has been set, it will be supplied iff any of the
@@ -383,7 +383,7 @@
     }
 
     /**
-     * This function is called by PropertyAnimator when setting the start values for an animation.
+     * This function is called by ObjectAnimator when setting the start values for an animation.
      * The start values are set according to the current values in the target object. The
      * property whose value is extracted is whatever is specified by the propertyName of this
      * PropertyValuesHolder object.
@@ -395,7 +395,7 @@
     }
 
     /**
-     * This function is called by PropertyAnimator when setting the end values for an animation.
+     * This function is called by ObjectAnimator when setting the end values for an animation.
      * The end values are set according to the current values in the target object. The
      * property whose value is extracted is whatever is specified by the propertyName of this
      * PropertyValuesHolder object.
@@ -420,8 +420,8 @@
     }
     /**
      * Internal function to set the value on the target object, using the setter set up
-     * earlier on this PropertyValuesHolder object. This function is called by PropertyAnimator
-     * to handle turning the value calculated by Animator into a value set on the object
+     * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+     * to handle turning the value calculated by ValueAnimator into a value set on the object
      * according to the name of the property.
      * @param target The target object on which the value is set
      */
@@ -439,7 +439,7 @@
     }
 
     /**
-     * Internal function, called by Animator, to set up the TypeEvaluator that will be used
+     * Internal function, called by ValueAnimator, to set up the TypeEvaluator that will be used
      * to calculate animated values.
      */
     void init() {
@@ -466,7 +466,7 @@
 
     /**
      * Function used to calculate the value according to the evaluator set up for
-     * this PropertyValuesHolder object. This function is called by Animator.animateValue().
+     * this PropertyValuesHolder object. This function is called by ValueAnimator.animateValue().
      *
      * @param fraction The elapsed, interpolated fraction of the animation.
      * @return The calculated value at this point in the animation.
@@ -483,7 +483,7 @@
      * approach is more direct, and is especially useful when a function must be called that does
      * not correspond to the convention of <code>setName()</code>. For example, if a function
      * called <code>offset()</code> is to be called with the animated values, there is no way
-     * to tell <code>PropertyAnimator</code> how to call that function simply through a property
+     * to tell <code>ObjectAnimator</code> how to call that function simply through a property
      * name, so a setter method should be supplied instead.
      *
      * <p>Note that the setter function must take the same parameter type as the
@@ -511,7 +511,7 @@
      * approach is more direct, and is especially useful when a function must be called that does
      * not correspond to the convention of <code>setName()</code>. For example, if a function
      * called <code>offset()</code> is to be called to get an initial value, there is no way
-     * to tell <code>PropertyAnimator</code> how to call that function simply through a property
+     * to tell <code>ObjectAnimator</code> how to call that function simply through a property
      * name, so a getter method should be supplied instead.
      *
      * <p>Note that the getter method is only called whether supplied here or derived
@@ -569,7 +569,7 @@
     }
 
     /**
-     * Internal function, called by Animator and PropertyAnimator, to retrieve the value
+     * Internal function, called by ValueAnimator and ObjectAnimator, to retrieve the value
      * most recently calculated in calculateValue().
      * @return
      */
diff --git a/core/java/android/animation/TypeEvaluator.java b/core/java/android/animation/TypeEvaluator.java
index 6150e00..fa49175 100644
--- a/core/java/android/animation/TypeEvaluator.java
+++ b/core/java/android/animation/TypeEvaluator.java
@@ -17,12 +17,12 @@
 package android.animation;
 
 /**
- * Interface for use with the {@link Animator#setEvaluator(TypeEvaluator)} function. Evaluators
+ * Interface for use with the {@link ValueAnimator#setEvaluator(TypeEvaluator)} function. Evaluators
  * allow developers to create animations on arbitrary property types, by allowing them to supply
  * custom evaulators for types that are not automatically understood and used by the animation
  * system.
  *
- * @see Animator#setEvaluator(TypeEvaluator)
+ * @see ValueAnimator#setEvaluator(TypeEvaluator)
  */
 public interface TypeEvaluator {
 
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
new file mode 100755
index 0000000..54a8e4b
--- /dev/null
+++ b/core/java/android/animation/ValueAnimator.java
@@ -0,0 +1,972 @@
+/*
+ * 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.animation;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * This class provides a simple timing engine for running animations
+ * which calculate animated values and set them on target objects.
+ *
+ * <p>There is a single timing pulse that all animations use. It runs in a
+ * custom handler to ensure that property changes happen on the UI thread.</p>
+ *
+ * <p>By default, ValueAnimator uses non-linear time interpolation, via the
+ * {@link AccelerateDecelerateInterpolator} class, which accelerates into and decelerates
+ * out of an animation. This behavior can be changed by calling
+ * {@link ValueAnimator#setInterpolator(Interpolator)}.</p>
+ */
+public class ValueAnimator<T> extends Animator {
+
+    /**
+     * Internal constants
+     */
+
+    /*
+     * The default amount of time in ms between animation frames
+     */
+    private static final long DEFAULT_FRAME_DELAY = 30;
+
+    /**
+     * Messages sent to timing handler: START is sent when an animation first begins, FRAME is sent
+     * by the handler to itself to process the next animation frame
+     */
+    private static final int ANIMATION_START = 0;
+    private static final int ANIMATION_FRAME = 1;
+
+    /**
+     * Values used with internal variable mPlayingState to indicate the current state of an
+     * animation.
+     */
+    private static final int STOPPED    = 0; // Not yet playing
+    private static final int RUNNING    = 1; // Playing normally
+    private static final int CANCELED   = 2; // cancel() called - need to end it
+    private static final int ENDED      = 3; // end() called - need to end it
+    private static final int SEEKED     = 4; // Seeked to some time value
+
+    /**
+     * Internal variables
+     * NOTE: This object implements the clone() method, making a deep copy of any referenced
+     * objects. As other non-trivial fields are added to this class, make sure to add logic
+     * to clone() to make deep copies of them.
+     */
+
+    // The first time that the animation's animateFrame() method is called. This time is used to
+    // determine elapsed time (and therefore the elapsed fraction) in subsequent calls
+    // to animateFrame()
+    private long mStartTime;
+
+    /**
+     * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked
+     * to a value.
+     */
+    private long mSeekTime = -1;
+
+    // The static sAnimationHandler processes the internal timing loop on which all animations
+    // are based
+    private static AnimationHandler sAnimationHandler;
+
+    // The static list of all active animations
+    private static final ArrayList<ValueAnimator> sAnimations = new ArrayList<ValueAnimator>();
+
+    // The set of animations to be started on the next animation frame
+    private static final ArrayList<ValueAnimator> sPendingAnimations = new ArrayList<ValueAnimator>();
+
+    // The time interpolator to be used if none is set on the animation
+    private static final Interpolator sDefaultInterpolator = new AccelerateDecelerateInterpolator();
+
+    // type evaluators for the three primitive types handled by this implementation
+    private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
+    private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator();
+    private static final TypeEvaluator sDoubleEvaluator = new DoubleEvaluator();
+
+    /**
+     * Used to indicate whether the animation is currently playing in reverse. This causes the
+     * elapsed fraction to be inverted to calculate the appropriate values.
+     */
+    private boolean mPlayingBackwards = false;
+
+    /**
+     * This variable tracks the current iteration that is playing. When mCurrentIteration exceeds the
+     * repeatCount (if repeatCount!=INFINITE), the animation ends
+     */
+    private int mCurrentIteration = 0;
+
+    /**
+     * Tracks whether a startDelay'd animation has begun playing through the startDelay.
+     */
+    private boolean mStartedDelay = false;
+
+    /**
+     * Tracks the time at which the animation began playing through its startDelay. This is
+     * different from the mStartTime variable, which is used to track when the animation became
+     * active (which is when the startDelay expired and the animation was added to the active
+     * animations list).
+     */
+    private long mDelayStartTime;
+
+    /**
+     * Flag that represents the current state of the animation. Used to figure out when to start
+     * an animation (if state == STOPPED). Also used to end an animation that
+     * has been cancel()'d or end()'d since the last animation frame. Possible values are
+     * STOPPED, RUNNING, ENDED, CANCELED.
+     */
+    private int mPlayingState = STOPPED;
+
+    /**
+     * Internal collections used to avoid set collisions as animations start and end while being
+     * processed.
+     */
+    private static final ArrayList<ValueAnimator> sEndingAnims = new ArrayList<ValueAnimator>();
+    private static final ArrayList<ValueAnimator> sDelayedAnims = new ArrayList<ValueAnimator>();
+    private static final ArrayList<ValueAnimator> sReadyAnims = new ArrayList<ValueAnimator>();
+
+    /**
+     * Flag that denotes whether the animation is set up and ready to go. Used to
+     * set up animation that has not yet been started.
+     */
+    boolean mInitialized = false;
+
+    //
+    // Backing variables
+    //
+
+    // How long the animation should last in ms
+    private long mDuration;
+
+    // The amount of time in ms to delay starting the animation after start() is called
+    private long mStartDelay = 0;
+
+    // The number of milliseconds between animation frames
+    private static long sFrameDelay = DEFAULT_FRAME_DELAY;
+
+    // The number of times the animation will repeat. The default is 0, which means the animation
+    // will play only once
+    private int mRepeatCount = 0;
+
+    /**
+     * The type of repetition that will occur when repeatMode is nonzero. RESTART means the
+     * animation will start from the beginning on every new cycle. REVERSE means the animation
+     * will reverse directions on each iteration.
+     */
+    private int mRepeatMode = RESTART;
+
+    /**
+     * The time interpolator to be used. The elapsed fraction of the animation will be passed
+     * through this interpolator to calculate the interpolated fraction, which is then used to
+     * calculate the animated values.
+     */
+    private Interpolator mInterpolator = sDefaultInterpolator;
+
+    /**
+     * The set of listeners to be sent events through the life of an animation.
+     */
+    private ArrayList<AnimatorUpdateListener> mUpdateListeners = null;
+
+    /**
+     * The property/value sets being animated.
+     */
+    PropertyValuesHolder[] mValues;
+
+    /**
+     * A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values
+     * by property name during calls to getAnimatedValue(String).
+     */
+    HashMap<String, PropertyValuesHolder> mValuesMap;
+
+    /**
+     * Public constants
+     */
+
+    /**
+     * When the animation reaches the end and <code>repeatCount</code> is INFINITE
+     * or a positive value, the animation restarts from the beginning.
+     */
+    public static final int RESTART = 1;
+    /**
+     * When the animation reaches the end and <code>repeatCount</code> is INFINITE
+     * or a positive value, the animation reverses direction on every iteration.
+     */
+    public static final int REVERSE = 2;
+    /**
+     * This value used used with the {@link #setRepeatCount(int)} property to repeat
+     * the animation indefinitely.
+     */
+    public static final int INFINITE = -1;
+
+    /**
+     * Creates a new ValueAnimator object. This default constructor is primarily for
+     * use internally; the other constructors which take parameters are more generally
+     * useful.
+     */
+    public ValueAnimator() {
+    }
+
+    /**
+     * Constructs an ValueAnimator object with the specified duration and set of
+     * values. If the values are a set of PropertyValuesHolder objects, then these objects
+     * define the potentially multiple properties being animated and the values the properties are
+     * animated between. Otherwise, the values define a single set of values animated between.
+     *
+     * @param duration The length of the animation, in milliseconds.
+     * @param values The set of values to animate between. If these values are not
+     * PropertyValuesHolder objects, then there should be more than one value, since the values
+     * determine the interval to animate between.
+     */
+    public ValueAnimator(long duration, T...values) {
+        mDuration = duration;
+        if (values.length > 0) {
+            setValues(values);
+        }
+    }
+
+    /**
+     * Sets the values, per property, being animated between. This function is called internally
+     * by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can
+     * be constructed without values and this method can be called to set the values manually
+     * instead.
+     *
+     * @param values The set of values, per property, being animated between.
+     */
+    public void setValues(PropertyValuesHolder... values) {
+        int numValues = values.length;
+        mValues = values;
+        mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
+        for (int i = 0; i < numValues; ++i) {
+            PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
+            mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
+        }
+    }
+
+    /**
+     * Returns the values that this ValueAnimator animates between. These values are stored in
+     * PropertyValuesHolder objects, even if the ValueAnimator was created with a simple list
+     * of value objects instead.
+     *
+     * @return PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the
+     * values, per property, that define the animation.
+     */
+    public PropertyValuesHolder[] getValues() {
+        return mValues;
+    }
+
+    /**
+     * Sets the values to animate between for this animation. If <code>values</code> is
+     * a set of PropertyValuesHolder objects, these objects will become the set of properties
+     * animated and the values that those properties are animated between. Otherwise, this method
+     * will set only one set of values for the ValueAnimator. Also, if the values are not
+     * PropertyValuesHolder objects and if there are already multiple sets of
+     * values defined for this ValueAnimator via
+     * more than one PropertyValuesHolder objects, this method will set the values for
+     * the first of those objects.
+     *
+     * @param values The set of values to animate between.
+     */
+    public void setValues(T... values) {
+        if (mValues == null || mValues.length == 0) {
+            setValues(new PropertyValuesHolder[]{
+                    new PropertyValuesHolder("", (Object[])values)});
+        } else {
+            PropertyValuesHolder valuesHolder = mValues[0];
+            valuesHolder.setValues(values);
+        }
+    }
+
+    /**
+     * This function is called immediately before processing the first animation
+     * frame of an animation. If there is a nonzero <code>startDelay</code>, the
+     * function is called after that delay ends.
+     * It takes care of the final initialization steps for the
+     * animation.
+     *
+     *  <p>Overrides of this method should call the superclass method to ensure
+     *  that internal mechanisms for the animation are set up correctly.</p>
+     */
+    void initAnimation() {
+        if (!mInitialized) {
+            int numValues = mValues.length;
+            for (int i = 0; i < numValues; ++i) {
+                mValues[i].init();
+            }
+            mCurrentIteration = 0;
+            mInitialized = true;
+        }
+    }
+
+
+    /**
+     * Sets the length of the animation.
+     *
+     * @param duration The length of the animation, in milliseconds.
+     */
+    public void setDuration(long duration) {
+        mDuration = duration;
+    }
+
+    /**
+     * Gets the length of the animation.
+     *
+     * @return The length of the animation, in milliseconds.
+     */
+    public long getDuration() {
+        return mDuration;
+    }
+
+    /**
+     * Sets the position of the animation to the specified point in time. This time should
+     * be between 0 and the total duration of the animation, including any repetition. If
+     * the animation has not yet been started, then it will not advance forward after it is
+     * set to this time; it will simply set the time to this value and perform any appropriate
+     * actions based on that time. If the animation is already running, then setCurrentPlayTime()
+     * will set the current playing time to this value and continue playing from that point.
+     *
+     * @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
+     */
+    public void setCurrentPlayTime(long playTime) {
+        initAnimation();
+        long currentTime = AnimationUtils.currentAnimationTimeMillis();
+        if (mPlayingState != RUNNING) {
+            mSeekTime = playTime;
+            mPlayingState = SEEKED;
+        }
+        mStartTime = currentTime - playTime;
+        animationFrame(currentTime);
+    }
+
+    /**
+     * Gets the current position of the animation in time, which is equal to the current
+     * time minus the time that the animation started. An animation that is not yet started will
+     * return a value of zero.
+     *
+     * @return The current position in time of the animation.
+     */
+    public long getCurrentPlayTime() {
+        if (!mInitialized || mPlayingState == STOPPED) {
+            return 0;
+        }
+        return AnimationUtils.currentAnimationTimeMillis() - mStartTime;
+    }
+
+    /**
+     * This custom, static handler handles the timing pulse that is shared by
+     * all active animations. This approach ensures that the setting of animation
+     * values will happen on the UI thread and that all animations will share
+     * the same times for calculating their values, which makes synchronizing
+     * animations possible.
+     *
+     */
+    private static class AnimationHandler extends Handler {
+        /**
+         * There are only two messages that we care about: ANIMATION_START and
+         * ANIMATION_FRAME. The START message is sent when an animation's start()
+         * method is called. It cannot start synchronously when start() is called
+         * because the call may be on the wrong thread, and it would also not be
+         * synchronized with other animations because it would not start on a common
+         * timing pulse. So each animation sends a START message to the handler, which
+         * causes the handler to place the animation on the active animations queue and
+         * start processing frames for that animation.
+         * The FRAME message is the one that is sent over and over while there are any
+         * active animations to process.
+         */
+        @Override
+        public void handleMessage(Message msg) {
+            boolean callAgain = true;
+            switch (msg.what) {
+                // TODO: should we avoid sending frame message when starting if we
+                // were already running?
+                case ANIMATION_START:
+                    if (sAnimations.size() > 0 || sDelayedAnims.size() > 0) {
+                        callAgain = false;
+                    }
+                    // pendingAnims holds any animations that have requested to be started
+                    // We're going to clear sPendingAnimations, but starting animation may
+                    // cause more to be added to the pending list (for example, if one animation
+                    // starting triggers another starting). So we loop until sPendingAnimations
+                    // is empty.
+                    while (sPendingAnimations.size() > 0) {
+                        ArrayList<ValueAnimator> pendingCopy =
+                                (ArrayList<ValueAnimator>) sPendingAnimations.clone();
+                        sPendingAnimations.clear();
+                        int count = pendingCopy.size();
+                        for (int i = 0; i < count; ++i) {
+                            ValueAnimator anim = pendingCopy.get(i);
+                            // If the animation has a startDelay, place it on the delayed list
+                            if (anim.mStartDelay == 0 || anim.mPlayingState == ENDED ||
+                                    anim.mPlayingState == CANCELED) {
+                                anim.startAnimation();
+                            } else {
+                                sDelayedAnims.add(anim);
+                            }
+                        }
+                    }
+                    // fall through to process first frame of new animations
+                case ANIMATION_FRAME:
+                    // currentTime holds the common time for all animations processed
+                    // during this frame
+                    long currentTime = AnimationUtils.currentAnimationTimeMillis();
+
+                    // First, process animations currently sitting on the delayed queue, adding
+                    // them to the active animations if they are ready
+                    int numDelayedAnims = sDelayedAnims.size();
+                    for (int i = 0; i < numDelayedAnims; ++i) {
+                        ValueAnimator anim = sDelayedAnims.get(i);
+                        if (anim.delayedAnimationFrame(currentTime)) {
+                            sReadyAnims.add(anim);
+                        }
+                    }
+                    int numReadyAnims = sReadyAnims.size();
+                    if (numReadyAnims > 0) {
+                        for (int i = 0; i < numReadyAnims; ++i) {
+                            ValueAnimator anim = sReadyAnims.get(i);
+                            anim.startAnimation();
+                            sDelayedAnims.remove(anim);
+                        }
+                        sReadyAnims.clear();
+                    }
+
+                    // Now process all active animations. The return value from animationFrame()
+                    // tells the handler whether it should now be ended
+                    int numAnims = sAnimations.size();
+                    for (int i = 0; i < numAnims; ++i) {
+                        ValueAnimator anim = sAnimations.get(i);
+                        if (anim.animationFrame(currentTime)) {
+                            sEndingAnims.add(anim);
+                        }
+                    }
+                    if (sEndingAnims.size() > 0) {
+                        for (int i = 0; i < sEndingAnims.size(); ++i) {
+                            sEndingAnims.get(i).endAnimation();
+                        }
+                        sEndingAnims.clear();
+                    }
+
+                    // If there are still active or delayed animations, call the handler again
+                    // after the frameDelay
+                    if (callAgain && (!sAnimations.isEmpty() || !sDelayedAnims.isEmpty())) {
+                        sendEmptyMessageDelayed(ANIMATION_FRAME, sFrameDelay);
+                    }
+                    break;
+            }
+        }
+    }
+
+    /**
+     * The amount of time, in milliseconds, to delay starting the animation after
+     * {@link #start()} is called.
+     *
+     * @return the number of milliseconds to delay running the animation
+     */
+    public long getStartDelay() {
+        return mStartDelay;
+    }
+
+    /**
+     * The amount of time, in milliseconds, to delay starting the animation after
+     * {@link #start()} is called.
+
+     * @param startDelay The amount of the delay, in milliseconds
+     */
+    public void setStartDelay(long startDelay) {
+        this.mStartDelay = startDelay;
+    }
+
+    /**
+     * The amount of time, in milliseconds, between each frame of the animation. This is a
+     * requested time that the animation will attempt to honor, but the actual delay between
+     * frames may be different, depending on system load and capabilities. This is a static
+     * function because the same delay will be applied to all animations, since they are all
+     * run off of a single timing loop.
+     *
+     * @return the requested time between frames, in milliseconds
+     */
+    public static long getFrameDelay() {
+        return sFrameDelay;
+    }
+
+    /**
+     * The amount of time, in milliseconds, between each frame of the animation. This is a
+     * requested time that the animation will attempt to honor, but the actual delay between
+     * frames may be different, depending on system load and capabilities. This is a static
+     * function because the same delay will be applied to all animations, since they are all
+     * run off of a single timing loop.
+     *
+     * @param frameDelay the requested time between frames, in milliseconds
+     */
+    public static void setFrameDelay(long frameDelay) {
+        sFrameDelay = frameDelay;
+    }
+
+    /**
+     * The most recent value calculated by this <code>ValueAnimator</code> when there is just one
+     * property being animated. This value is only sensible while the animation is running. The main
+     * purpose for this read-only property is to retrieve the value from the <code>ValueAnimator</code>
+     * during a call to {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which
+     * is called during each animation frame, immediately after the value is calculated.
+     *
+     * @return animatedValue The value most recently calculated by this <code>ValueAnimator</code> for
+     * the single property being animated. If there are several properties being animated
+     * (specified by several PropertyValuesHolder objects in the constructor), this function
+     * returns the animated value for the first of those objects.
+     */
+    public Object getAnimatedValue() {
+        if (mValues != null && mValues.length > 0) {
+            return mValues[0].getAnimatedValue();
+        }
+        // Shouldn't get here; should always have values unless ValueAnimator was set up wrong
+        return null;
+    }
+
+    /**
+     * The most recent value calculated by this <code>ValueAnimator</code> for <code>propertyName</code>.
+     * The main purpose for this read-only property is to retrieve the value from the
+     * <code>ValueAnimator</code> during a call to
+     * {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which
+     * is called during each animation frame, immediately after the value is calculated.
+     *
+     * @return animatedValue The value most recently calculated for the named property
+     * by this <code>ValueAnimator</code>.
+     */
+    public Object getAnimatedValue(String propertyName) {
+        PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
+        if (valuesHolder != null) {
+            return valuesHolder.getAnimatedValue();
+        } else {
+            // At least avoid crashing if called with bogus propertyName
+            return null;
+        }
+    }
+
+    /**
+     * Sets how many times the animation should be repeated. If the repeat
+     * count is 0, the animation is never repeated. If the repeat count is
+     * greater than 0 or {@link #INFINITE}, the repeat mode will be taken
+     * into account. The repeat count is 0 by default.
+     *
+     * @param value the number of times the animation should be repeated
+     */
+    public void setRepeatCount(int value) {
+        mRepeatCount = value;
+    }
+    /**
+     * Defines how many times the animation should repeat. The default value
+     * is 0.
+     *
+     * @return the number of times the animation should repeat, or {@link #INFINITE}
+     */
+    public int getRepeatCount() {
+        return mRepeatCount;
+    }
+
+    /**
+     * Defines what this animation should do when it reaches the end. This
+     * setting is applied only when the repeat count is either greater than
+     * 0 or {@link #INFINITE}. Defaults to {@link #RESTART}.
+     *
+     * @param value {@link #RESTART} or {@link #REVERSE}
+     */
+    public void setRepeatMode(int value) {
+        mRepeatMode = value;
+    }
+
+    /**
+     * Defines what this animation should do when it reaches the end.
+     *
+     * @return either one of {@link #REVERSE} or {@link #RESTART}
+     */
+    public int getRepeatMode() {
+        return mRepeatMode;
+    }
+
+    /**
+     * Adds a listener to the set of listeners that are sent update events through the life of
+     * an animation. This method is called on all listeners for every frame of the animation,
+     * after the values for the animation have been calculated.
+     *
+     * @param listener the listener to be added to the current set of listeners for this animation.
+     */
+    public void addUpdateListener(AnimatorUpdateListener listener) {
+        if (mUpdateListeners == null) {
+            mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
+        }
+        mUpdateListeners.add(listener);
+    }
+
+    /**
+     * Removes a listener from the set listening to frame updates for this animation.
+     *
+     * @param listener the listener to be removed from the current set of update listeners
+     * for this animation.
+     */
+    public void removeUpdateListener(AnimatorUpdateListener listener) {
+        if (mUpdateListeners == null) {
+            return;
+        }
+        mUpdateListeners.remove(listener);
+        if (mUpdateListeners.size() == 0) {
+            mUpdateListeners = null;
+        }
+    }
+
+
+    /**
+     * The time interpolator used in calculating the elapsed fraction of this animation. The
+     * interpolator determines whether the animation runs with linear or non-linear motion,
+     * such as acceleration and deceleration. The default value is
+     * {@link android.view.animation.AccelerateDecelerateInterpolator}
+     *
+     * @param value the interpolator to be used by this animation
+     */
+    @Override
+    public void setInterpolator(Interpolator value) {
+        if (value != null) {
+            mInterpolator = value;
+        }
+    }
+
+    /**
+     * Returns the timing interpolator that this ValueAnimator uses.
+     *
+     * @return The timing interpolator for this ValueAnimator.
+     */
+    public Interpolator getInterpolator() {
+        return mInterpolator;
+    }
+
+    /**
+     * The type evaluator to be used when calculating the animated values of this animation.
+     * The system will automatically assign a float, int, or double evaluator based on the type
+     * of <code>startValue</code> and <code>endValue</code> in the constructor. But if these values
+     * are not one of these primitive types, or if different evaluation is desired (such as is
+     * necessary with int values that represent colors), a custom evaluator needs to be assigned.
+     * For example, when running an animation on color values, the {@link RGBEvaluator}
+     * should be used to get correct RGB color interpolation.
+     *
+     * <p>If this ValueAnimator has only one set of values being animated between, this evaluator
+     * will be used for that set. If there are several sets of values being animated, which is
+     * the case if PropertyValuesHOlder objects were set on the ValueAnimator, then the evaluator
+     * is assigned just to the first PropertyValuesHolder object.</p>
+     *
+     * @param value the evaluator to be used this animation
+     */
+    public void setEvaluator(TypeEvaluator value) {
+        if (value != null && mValues != null && mValues.length > 0) {
+            mValues[0].setEvaluator(value);
+        }
+    }
+
+    /**
+     * Start the animation playing. This version of start() takes a boolean flag that indicates
+     * whether the animation should play in reverse. The flag is usually false, but may be set
+     * to true if called from the reverse() method/
+     *
+     * @param playBackwards Whether the ValueAnimator should start playing in reverse.
+     */
+    private void start(boolean playBackwards) {
+        mPlayingBackwards = playBackwards;
+        if ((mStartDelay == 0) && (Thread.currentThread() == Looper.getMainLooper().getThread())) {
+            // This sets the initial value of the animation, prior to actually starting it running
+            setCurrentPlayTime(getCurrentPlayTime());
+        }
+        mPlayingState = STOPPED;
+        mStartedDelay = false;
+        sPendingAnimations.add(this);
+        if (sAnimationHandler == null) {
+            sAnimationHandler = new AnimationHandler();
+        }
+        // TODO: does this put too many messages on the queue if the handler
+        // is already running?
+        sAnimationHandler.sendEmptyMessage(ANIMATION_START);
+    }
+
+    @Override
+    public void start() {
+        start(false);
+    }
+
+    @Override
+    public void cancel() {
+        if (mListeners != null) {
+            ArrayList<AnimatorListener> tmpListeners =
+                    (ArrayList<AnimatorListener>) mListeners.clone();
+            for (AnimatorListener listener : tmpListeners) {
+                listener.onAnimationCancel(this);
+            }
+        }
+        // Just set the CANCELED flag - this causes the animation to end the next time a frame
+        // is processed.
+        mPlayingState = CANCELED;
+    }
+
+    @Override
+    public void end() {
+        if (!sAnimations.contains(this) && !sPendingAnimations.contains(this)) {
+            // Special case if the animation has not yet started; get it ready for ending
+            mStartedDelay = false;
+            sPendingAnimations.add(this);
+            if (sAnimationHandler == null) {
+                sAnimationHandler = new AnimationHandler();
+            }
+            sAnimationHandler.sendEmptyMessage(ANIMATION_START);
+        }
+        // Just set the ENDED flag - this causes the animation to end the next time a frame
+        // is processed.
+        mPlayingState = ENDED;
+    }
+
+    @Override
+    public boolean isRunning() {
+        // ENDED or CANCELED indicate that it has been ended or canceled, but not processed yet
+        return (mPlayingState == RUNNING || mPlayingState == ENDED || mPlayingState == CANCELED);
+    }
+
+    /**
+     * Plays the ValueAnimator in reverse. If the animation is already running,
+     * it will stop itself and play backwards from the point reached when reverse was called.
+     * If the animation is not currently running, then it will start from the end and
+     * play backwards. This behavior is only set for the current animation; future playing
+     * of the animation will use the default behavior of playing forward.
+     */
+    public void reverse() {
+        mPlayingBackwards = !mPlayingBackwards;
+        if (mPlayingState == RUNNING) {
+            long currentTime = AnimationUtils.currentAnimationTimeMillis();
+            long currentPlayTime = currentTime - mStartTime;
+            long timeLeft = mDuration - currentPlayTime;
+            mStartTime = currentTime - timeLeft;
+        } else {
+            start(true);
+        }
+    }
+
+    /**
+     * Called internally to end an animation by removing it from the animations list. Must be
+     * called on the UI thread.
+     */
+    private void endAnimation() {
+        sAnimations.remove(this);
+        mPlayingState = STOPPED;
+        if (mListeners != null) {
+            ArrayList<AnimatorListener> tmpListeners =
+                    (ArrayList<AnimatorListener>) mListeners.clone();
+            for (AnimatorListener listener : tmpListeners) {
+                listener.onAnimationEnd(this);
+            }
+        }
+    }
+
+    /**
+     * Called internally to start an animation by adding it to the active animations list. Must be
+     * called on the UI thread.
+     */
+    private void startAnimation() {
+        initAnimation();
+        sAnimations.add(this);
+        if (mListeners != null) {
+            ArrayList<AnimatorListener> tmpListeners =
+                    (ArrayList<AnimatorListener>) mListeners.clone();
+            for (AnimatorListener listener : tmpListeners) {
+                listener.onAnimationStart(this);
+            }
+        }
+    }
+
+    /**
+     * Internal function called to process an animation frame on an animation that is currently
+     * sleeping through its <code>startDelay</code> phase. The return value indicates whether it
+     * should be woken up and put on the active animations queue.
+     *
+     * @param currentTime The current animation time, used to calculate whether the animation
+     * has exceeded its <code>startDelay</code> and should be started.
+     * @return True if the animation's <code>startDelay</code> has been exceeded and the animation
+     * should be added to the set of active animations.
+     */
+    private boolean delayedAnimationFrame(long currentTime) {
+        if (mPlayingState == CANCELED || mPlayingState == ENDED) {
+            // end the delay, process an animation frame to actually cancel it
+            return true;
+        }
+        if (!mStartedDelay) {
+            mStartedDelay = true;
+            mDelayStartTime = currentTime;
+        } else {
+            long deltaTime = currentTime - mDelayStartTime;
+            if (deltaTime > mStartDelay) {
+                // startDelay ended - start the anim and record the
+                // mStartTime appropriately
+                mStartTime = currentTime - (deltaTime - mStartDelay);
+                mPlayingState = RUNNING;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * This internal function processes a single animation frame for a given animation. The
+     * currentTime parameter is the timing pulse sent by the handler, used to calculate the
+     * elapsed duration, and therefore
+     * the elapsed fraction, of the animation. The return value indicates whether the animation
+     * should be ended (which happens when the elapsed time of the animation exceeds the
+     * animation's duration, including the repeatCount).
+     *
+     * @param currentTime The current time, as tracked by the static timing handler
+     * @return true if the animation's duration, including any repetitions due to
+     * <code>repeatCount</code> has been exceeded and the animation should be ended.
+     */
+    private boolean animationFrame(long currentTime) {
+        boolean done = false;
+
+        if (mPlayingState == STOPPED) {
+            mPlayingState = RUNNING;
+            if (mSeekTime < 0) {
+                mStartTime = currentTime;
+            } else {
+                mStartTime = currentTime - mSeekTime;
+                // Now that we're playing, reset the seek time
+                mSeekTime = -1;
+            }
+        }
+        switch (mPlayingState) {
+        case RUNNING:
+        case SEEKED:
+            float fraction = (float)(currentTime - mStartTime) / mDuration;
+            if (fraction >= 1f) {
+                if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
+                    // Time to repeat
+                    if (mListeners != null) {
+                        for (AnimatorListener listener : mListeners) {
+                            listener.onAnimationRepeat(this);
+                        }
+                    }
+                    ++mCurrentIteration;
+                    if (mRepeatMode == REVERSE) {
+                        mPlayingBackwards = mPlayingBackwards ? false : true;
+                    }
+                    // TODO: doesn't account for fraction going Wayyyyy over 1, like 2+
+                    fraction = fraction - 1f;
+                    mStartTime += mDuration;
+                } else {
+                    done = true;
+                    fraction = Math.min(fraction, 1.0f);
+                }
+            }
+            if (mPlayingBackwards) {
+                fraction = 1f - fraction;
+            }
+            animateValue(fraction);
+            break;
+        case ENDED:
+            // The final value set on the target varies, depending on whether the animation
+            // was supposed to repeat an odd number of times
+            if (mRepeatCount > 0 && (mRepeatCount & 0x01) == 1) {
+                animateValue(0f);
+            } else {
+                animateValue(1f);
+            }
+            // Fall through to set done flag
+        case CANCELED:
+            done = true;
+            mPlayingState = STOPPED;
+            break;
+        }
+
+        return done;
+    }
+
+    /**
+     * This method is called with the elapsed fraction of the animation during every
+     * animation frame. This function turns the elapsed fraction into an interpolated fraction
+     * and then into an animated value (from the evaluator. The function is called mostly during
+     * animation updates, but it is also called when the <code>end()</code>
+     * function is called, to set the final value on the property.
+     *
+     * <p>Overrides of this method must call the superclass to perform the calculation
+     * of the animated value.</p>
+     *
+     * @param fraction The elapsed fraction of the animation.
+     */
+    void animateValue(float fraction) {
+        fraction = mInterpolator.getInterpolation(fraction);
+        int numValues = mValues.length;
+        for (int i = 0; i < numValues; ++i) {
+            mValues[i].calculateValue(fraction);
+        }
+        if (mUpdateListeners != null) {
+            int numListeners = mUpdateListeners.size();
+            for (int i = 0; i < numListeners; ++i) {
+                mUpdateListeners.get(i).onAnimationUpdate(this);
+            }
+        }
+    }
+
+    @Override
+    public ValueAnimator clone() {
+        final ValueAnimator anim = (ValueAnimator) super.clone();
+        if (mUpdateListeners != null) {
+            ArrayList<AnimatorUpdateListener> oldListeners = mUpdateListeners;
+            anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
+            int numListeners = oldListeners.size();
+            for (int i = 0; i < numListeners; ++i) {
+                anim.mUpdateListeners.add(oldListeners.get(i));
+            }
+        }
+        anim.mSeekTime = -1;
+        anim.mPlayingBackwards = false;
+        anim.mCurrentIteration = 0;
+        anim.mInitialized = false;
+        anim.mPlayingState = STOPPED;
+        anim.mStartedDelay = false;
+        PropertyValuesHolder[] oldValues = mValues;
+        if (oldValues != null) {
+            int numValues = oldValues.length;
+            anim.mValues = new PropertyValuesHolder[numValues];
+            for (int i = 0; i < numValues; ++i) {
+                anim.mValues[i] = oldValues[i].clone();
+            }
+            anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
+            for (int i = 0; i < numValues; ++i) {
+                PropertyValuesHolder valuesHolder = mValues[i];
+                anim.mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
+            }
+        }
+        return anim;
+    }
+
+    /**
+     * Implementors of this interface can add themselves as update listeners
+     * to an <code>ValueAnimator</code> instance to receive callbacks on every animation
+     * frame, after the current frame's values have been calculated for that
+     * <code>ValueAnimator</code>.
+     */
+    public static interface AnimatorUpdateListener {
+        /**
+         * <p>Notifies the occurrence of another frame of the animation.</p>
+         *
+         * @param animation The animation which was repeated.
+         */
+        void onAnimationUpdate(ValueAnimator animation);
+
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 56cf399..16d105a 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -16,7 +16,7 @@
 
 package android.app;
 
-import android.animation.Animatable;
+import android.animation.Animator;
 import android.content.ComponentCallbacks;
 import android.content.Context;
 import android.content.Intent;
@@ -26,7 +26,6 @@
 import android.os.Parcelable;
 import android.util.AndroidRuntimeException;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.SparseArray;
 import android.view.ContextMenu;
 import android.view.LayoutInflater;
@@ -755,7 +754,7 @@
     /**
      * Called when a fragment loads an animation.
      */
-    public Animatable onCreateAnimatable(int transit, boolean enter, int nextAnim) {
+    public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
         return null;
     }
     
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 7641f61..4d4f892 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -16,10 +16,10 @@
 
 package android.app;
 
-import android.animation.Animatable;
-import android.animation.AnimatableInflater;
-import android.animation.PropertyAnimator;
-import android.animation.Sequencer;
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.content.res.TypedArray;
 import android.os.Bundle;
 import android.os.Handler;
@@ -248,16 +248,16 @@
         return f;
     }
 
-    Animatable loadAnimatable(Fragment fragment, int transit, boolean enter,
+    Animator loadAnimator(Fragment fragment, int transit, boolean enter,
             int transitionStyle) {
-        Animatable animObj = fragment.onCreateAnimatable(transit, enter,
+        Animator animObj = fragment.onCreateAnimator(transit, enter,
                 fragment.mNextAnim);
         if (animObj != null) {
             return animObj;
         }
         
         if (fragment.mNextAnim != 0) {
-            Animatable anim = AnimatableInflater.loadAnimatable(mActivity, fragment.mNextAnim);
+            Animator anim = AnimatorInflater.loadAnimator(mActivity, fragment.mNextAnim);
             if (anim != null) {
                 return anim;
             }
@@ -288,7 +288,7 @@
             return null;
         }
         
-        return AnimatableInflater.loadAnimatable(mActivity, anim);
+        return AnimatorInflater.loadAnimator(mActivity, anim);
     }
     
     void moveToState(Fragment f, int newState, int transit, int transitionStyle) {
@@ -360,13 +360,13 @@
                             if (f.mView != null) {
                                 f.mView.setSaveFromParentEnabled(false);
                                 if (container != null) {
-                                    Animatable anim = loadAnimatable(f, transit, true,
+                                    Animator anim = loadAnimator(f, transit, true,
                                             transitionStyle);
                                     if (anim != null) {
-                                        if (anim instanceof Sequencer) {
-                                            ((Sequencer)anim).setTarget(f.mView);
-                                        } else if (anim instanceof PropertyAnimator) {
-                                            ((PropertyAnimator)anim).setTarget(f.mView);
+                                        if (anim instanceof AnimatorSet) {
+                                            ((AnimatorSet)anim).setTarget(f.mView);
+                                        } else if (anim instanceof ObjectAnimator) {
+                                            ((ObjectAnimator)anim).setTarget(f.mView);
                                         }
                                         anim.start();
                                     }
@@ -448,13 +448,13 @@
                         }
                         if (f.mView != null && f.mContainer != null) {
                             if (mCurState > Fragment.INITIALIZING) {
-                                Animatable anim = loadAnimatable(f, transit, true,
+                                Animator anim = loadAnimator(f, transit, true,
                                         transitionStyle);
                                 if (anim != null) {
-                                    if (anim instanceof Sequencer) {
-                                        ((Sequencer)anim).setTarget(f.mView);
-                                    } else if (anim instanceof PropertyAnimator) {
-                                        ((PropertyAnimator)anim).setTarget(f.mView);
+                                    if (anim instanceof AnimatorSet) {
+                                        ((AnimatorSet)anim).setTarget(f.mView);
+                                    } else if (anim instanceof ObjectAnimator) {
+                                        ((ObjectAnimator)anim).setTarget(f.mView);
                                     }
                                     anim.start();
                                 }
@@ -588,13 +588,13 @@
         if (!fragment.mHidden) {
             fragment.mHidden = true;
             if (fragment.mView != null) {
-                Animatable anim = loadAnimatable(fragment, transition, true,
+                Animator anim = loadAnimator(fragment, transition, true,
                         transitionStyle);
                 if (anim != null) {
-                    if (anim instanceof Sequencer) {
-                        ((Sequencer)anim).setTarget(fragment.mView);
-                    } else if (anim instanceof PropertyAnimator) {
-                        ((PropertyAnimator)anim).setTarget(fragment.mView);
+                    if (anim instanceof AnimatorSet) {
+                        ((AnimatorSet)anim).setTarget(fragment.mView);
+                    } else if (anim instanceof ObjectAnimator) {
+                        ((ObjectAnimator)anim).setTarget(fragment.mView);
                     }
                     anim.start();
                 }
@@ -612,13 +612,13 @@
         if (fragment.mHidden) {
             fragment.mHidden = false;
             if (fragment.mView != null) {
-                Animatable anim = loadAnimatable(fragment, transition, true,
+                Animator anim = loadAnimator(fragment, transition, true,
                         transitionStyle);
                 if (anim != null) {
-                    if (anim instanceof Sequencer) {
-                        ((Sequencer)anim).setTarget(fragment.mView);
-                    } else if (anim instanceof PropertyAnimator) {
-                        ((PropertyAnimator)anim).setTarget(fragment.mView);
+                    if (anim instanceof AnimatorSet) {
+                        ((AnimatorSet)anim).setTarget(fragment.mView);
+                    } else if (anim instanceof ObjectAnimator) {
+                        ((ObjectAnimator)anim).setTarget(fragment.mView);
                     }
                     anim.start();
                 }
diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java
index c090f8e..32ff647 100644
--- a/core/java/android/view/animation/AnimationUtils.java
+++ b/core/java/android/view/animation/AnimationUtils.java
@@ -35,7 +35,7 @@
 public class AnimationUtils {
 
     /**
-     * These flags are used when parsing Sequencer objects
+     * These flags are used when parsing AnimatorSet objects
      */
     private static final int TOGETHER = 0;
     private static final int SEQUENTIALLY = 1;
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 830e899..e8d96c5 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -18,12 +18,10 @@
 
 import java.util.ArrayList;
 
-import android.animation.PropertyAnimator;
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.graphics.RectF;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Parcel;
@@ -220,13 +218,13 @@
      * @param view The view that is being animated
      */
     void animateViewForTransition(int fromIndex, int toIndex, View view) {
-        PropertyAnimator pa;
+        ObjectAnimator pa;
         if (fromIndex == -1) {
             view.setAlpha(0.0f);
-            pa = new PropertyAnimator(400, view, "alpha", 0.0f, 1.0f);
+            pa = new ObjectAnimator(400, view, "alpha", 0.0f, 1.0f);
             pa.start();
         } else if (toIndex == -1) {
-            pa = new PropertyAnimator(400, view, "alpha", 1.0f, 0.0f);
+            pa = new ObjectAnimator(400, view, "alpha", 1.0f, 0.0f);
             pa.start();
         }
     }
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 9025b83..0a97904 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -16,8 +16,8 @@
 
 package android.widget;
 
-import android.animation.PropertyAnimator;
 import android.animation.PropertyValuesHolder;
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BlurMaskFilter;
@@ -166,7 +166,7 @@
             }
             view.setVisibility(VISIBLE);
 
-            PropertyAnimator<Float> fadeIn = new PropertyAnimator<Float>(DEFAULT_ANIMATION_DURATION,
+            ObjectAnimator<Float> fadeIn = new ObjectAnimator<Float>(DEFAULT_ANIMATION_DURATION,
                     view, "alpha", view.getAlpha(), 1.0f);
             fadeIn.start();
         } else if (fromIndex == mNumActiveViews - 1 && toIndex == mNumActiveViews - 2) {
@@ -181,7 +181,7 @@
                     new PropertyValuesHolder<Float>("YProgress", 0.0f);
             PropertyValuesHolder<Float> slideInX =
                     new PropertyValuesHolder<Float>("XProgress", 0.0f);
-            PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
+            ObjectAnimator pa = new ObjectAnimator(duration, animationSlider,
                     slideInX, slideInY);
             pa.setInterpolator(new LinearInterpolator());
             pa.start();
@@ -196,7 +196,7 @@
                     new PropertyValuesHolder<Float>("YProgress", 1.0f);
             PropertyValuesHolder<Float> slideOutX =
                     new PropertyValuesHolder<Float>("XProgress", 0.0f);
-            PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
+            ObjectAnimator pa = new ObjectAnimator(duration, animationSlider,
                    slideOutX, slideOutY);
             pa.setInterpolator(new LinearInterpolator());
             pa.start();
@@ -208,7 +208,7 @@
             lp.setVerticalOffset(-mViewHeight);
         } else if (toIndex == -1) {
             // Fade item out
-            PropertyAnimator<Float> fadeOut = new PropertyAnimator<Float>
+            ObjectAnimator<Float> fadeOut = new ObjectAnimator<Float>
                     (DEFAULT_ANIMATION_DURATION, view, "alpha", view.getAlpha(), 0.0f);
             fadeOut.start();
         }
@@ -234,7 +234,7 @@
 
             PropertyValuesHolder<Float> translationY =
                     new PropertyValuesHolder<Float>("translationY", transY);
-            PropertyAnimator pa = new PropertyAnimator(100, view, scaleX, scaleY, translationY);
+            ObjectAnimator pa = new ObjectAnimator(100, view, scaleX, scaleY, translationY);
             pa.start();
         }
     }
@@ -510,7 +510,7 @@
                     new PropertyValuesHolder<Float>("YProgress", finalYProgress);
             PropertyValuesHolder<Float> snapBackX =
                     new PropertyValuesHolder<Float>("XProgress", 0.0f);
-            PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
+            ObjectAnimator pa = new ObjectAnimator(duration, animationSlider,
                     snapBackX, snapBackY);
             pa.setInterpolator(new LinearInterpolator());
             pa.start();
@@ -529,7 +529,7 @@
                     new PropertyValuesHolder<Float>("YProgress", finalYProgress);
             PropertyValuesHolder<Float> snapBackX =
                     new PropertyValuesHolder<Float>("XProgress", 0.0f);
-            PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
+            ObjectAnimator pa = new ObjectAnimator(duration, animationSlider,
                     snapBackX, snapBackY);
             pa.start();
         }
@@ -870,7 +870,7 @@
 
         private Rect invalidateRect = new Rect();
         private RectF invalidateRectf = new RectF();
-        // This is public so that PropertyAnimator can access it
+        // This is public so that ObjectAnimator can access it
         public void setVerticalOffset(int newVerticalOffset) {
             int offsetDelta = newVerticalOffset - verticalOffset;
             verticalOffset = newVerticalOffset;
diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java
index 4b56cb4..3865510 100644
--- a/core/java/com/android/internal/widget/SlidingTab.java
+++ b/core/java/com/android/internal/widget/SlidingTab.java
@@ -416,7 +416,7 @@
         }
 
         /**
-         * Start animating the slider. Note we need two animations since an Animator
+         * Start animating the slider. Note we need two animations since an ValueAnimator
          * keeps internal state of the invalidation region which is just the view being animated.
          *
          * @param anim1
diff --git a/core/res/res/anim/animator_fade_in.xml b/core/res/res/anim/animator_fade_in.xml
index cd5042f..2a28b4d 100644
--- a/core/res/res/anim/animator_fade_in.xml
+++ b/core/res/res/anim/animator_fade_in.xml
@@ -17,7 +17,7 @@
 */
 -->
 
-<property xmlns:android="http://schemas.android.com/apk/res/android"
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
     android:interpolator="@anim/accelerate_interpolator"
     android:valueFrom="0"
     android:valueTo="1"
diff --git a/core/res/res/anim/animator_fade_out.xml b/core/res/res/anim/animator_fade_out.xml
index dfb5d9c..4db6591 100644
--- a/core/res/res/anim/animator_fade_out.xml
+++ b/core/res/res/anim/animator_fade_out.xml
@@ -17,7 +17,7 @@
 */
 -->
 
-<property xmlns:android="http://schemas.android.com/apk/res/android"
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
     android:interpolator="@anim/accelerate_interpolator"
     android:valueFrom="1.0"
     android:valueTo="0.0"
diff --git a/core/res/res/anim/fragment_close_enter.xml b/core/res/res/anim/fragment_close_enter.xml
index d4091e8..53afa2a 100644
--- a/core/res/res/anim/fragment_close_enter.xml
+++ b/core/res/res/anim/fragment_close_enter.xml
@@ -16,33 +16,33 @@
 ** limitations under the License.
 */
 -->
-<sequencer xmlns:android="http://schemas.android.com/apk/res/android">
-    <property
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
         android:interpolator="@anim/decelerate_interpolator"
         android:valueFrom="2"
         android:valueTo="1"
         android:valueType="floatType"
         android:propertyName="scaleX"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:interpolator="@anim/decelerate_interpolator"
         android:valueFrom="2"
         android:valueTo="1"
         android:valueType="floatType"
         android:propertyName="scaleY"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:interpolator="@anim/decelerate_interpolator"
         android:valueFrom="0"
         android:valueTo="1"
         android:valueType="floatType"
         android:propertyName="alpha"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:interpolator="@anim/decelerate_interpolator"
         android:valueFrom="-400"
         android:valueTo="0"
         android:valueType="floatType"
         android:propertyName="translationX"
         android:duration="@android:integer/config_mediumAnimTime"/>
-</sequencer>
\ No newline at end of file
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_close_exit.xml b/core/res/res/anim/fragment_close_exit.xml
index 3e2cd22..1554a4e 100644
--- a/core/res/res/anim/fragment_close_exit.xml
+++ b/core/res/res/anim/fragment_close_exit.xml
@@ -16,33 +16,33 @@
 ** limitations under the License.
 */
 -->
-<sequencer xmlns:android="http://schemas.android.com/apk/res/android">
-    <property
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
         android:interpolator="@anim/accelerate_interpolator"
         android:valueFrom="1"
         android:valueTo=".5"
         android:valueType="floatType"
         android:propertyName="scaleX"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:interpolator="@anim/accelerate_interpolator"
         android:valueFrom="1"
         android:valueTo=".5"
         android:valueType="floatType"
         android:propertyName="scaleY"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:interpolator="@anim/accelerate_interpolator"
         android:valueFrom="1"
         android:valueTo="0"
         android:valueType="floatType"
         android:propertyName="alpha"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:interpolator="@anim/accelerate_interpolator"
         android:valueFrom="0"
         android:valueTo="400"
         android:valueType="floatType"
         android:propertyName="translationX"
         android:duration="@android:integer/config_mediumAnimTime"/>
-</sequencer>
\ No newline at end of file
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_open_enter.xml b/core/res/res/anim/fragment_open_enter.xml
index c89001c..142f60c 100644
--- a/core/res/res/anim/fragment_open_enter.xml
+++ b/core/res/res/anim/fragment_open_enter.xml
@@ -16,31 +16,31 @@
 ** limitations under the License.
 */
 -->
-<sequencer xmlns:android="http://schemas.android.com/apk/res/android">
-    <property
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
         android:interpolator="@anim/decelerate_interpolator"
         android:valueFrom="2"
         android:valueTo="1"
         android:valueType="floatType"
         android:propertyName="scaleX"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:interpolator="@anim/decelerate_interpolator"
         android:valueFrom="2"
         android:valueTo="1"
         android:valueType="floatType"
         android:propertyName="scaleY"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:valueFrom="0"
         android:valueTo="1"
         android:valueType="floatType"
         android:propertyName="alpha"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:valueFrom="400"
         android:valueTo="0"
         android:valueType="floatType"
         android:propertyName="translationX"
         android:duration="@android:integer/config_mediumAnimTime"/>
-</sequencer>
\ No newline at end of file
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_open_exit.xml b/core/res/res/anim/fragment_open_exit.xml
index 427fe4f..21260b9 100644
--- a/core/res/res/anim/fragment_open_exit.xml
+++ b/core/res/res/anim/fragment_open_exit.xml
@@ -16,31 +16,31 @@
 ** limitations under the License.
 */
 -->
-<sequencer xmlns:android="http://schemas.android.com/apk/res/android">
-    <property
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
         android:interpolator="@anim/accelerate_interpolator"
         android:valueFrom="1"
         android:valueTo="2"
         android:valueType="floatType"
         android:propertyName="scaleX"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:interpolator="@anim/accelerate_interpolator"
         android:valueFrom="1"
         android:valueTo="2"
         android:valueType="floatType"
         android:propertyName="scaleY"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:valueFrom="1"
         android:valueTo="0"
         android:valueType="floatType"
         android:propertyName="alpha"
         android:duration="@android:integer/config_mediumAnimTime"/>
-    <property
+    <objectAnimator
         android:valueFrom="0"
         android:valueTo="-400"
         android:valueType="floatType"
         android:propertyName="translationX"
         android:duration="@android:integer/config_mediumAnimTime"/>
-</sequencer>
\ No newline at end of file
+</set>
\ No newline at end of file
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 786e6b2..7b8d427 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3010,7 +3010,7 @@
     </declare-styleable>
 
     <!-- ========================== -->
-    <!-- Animator class attributes -->
+    <!-- ValueAnimator class attributes -->
     <!-- ========================== -->
     <eat-comment />
 
@@ -3047,7 +3047,7 @@
     </declare-styleable>
 
     <!-- ========================== -->
-    <!-- PropertyAnimator class attributes -->
+    <!-- ObjectAnimator class attributes -->
     <!-- ========================== -->
     <eat-comment />
 
@@ -3058,11 +3058,11 @@
 
 
     <!-- ========================== -->
-    <!-- Sequencer class attributes -->
+    <!-- AnimatorSet class attributes -->
     <!-- ========================== -->
     <eat-comment />
 
-    <declare-styleable name="Sequencer">
+    <declare-styleable name="AnimatorSet">
         <!-- Name of the property being animated. -->
         <attr name="ordering">
             <!-- child animations should be played together. -->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 5dc46d0..814d375 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -16,13 +16,9 @@
 
 package com.android.systemui.statusbar.tablet;
 
-import android.animation.Animator;
 import android.app.ActivityManagerNative;
-import android.app.Notification;
 import android.app.PendingIntent;
-import android.app.Service;
 import android.app.StatusBarManager;
-import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -33,7 +29,6 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.util.Slog;
-import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.Gravity;
 import android.view.LayoutInflater;
@@ -41,7 +36,6 @@
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
-import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.RemoteViews;
@@ -50,7 +44,6 @@
 import android.widget.TextView;
 
 import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.statusbar.StatusBarIconList;
 import com.android.internal.statusbar.StatusBarNotification;
 
 import com.android.systemui.statusbar.*;