Bug 1255162 - Replace NineOldAndroids with system API. r=liuche
authorSebastian Kaspari <s.kaspari@gmail.com>
Thu, 10 Mar 2016 13:38:28 +0100
changeset 289204 14c37c9ab9a46726da61e954bca1ecde5c4bfffc
parent 289203 21b7869572c92dab8d9fa07d333c43f2855a1b3b
child 289205 c2c52f4c59b2e3e0b7c6216e2e5cdb7fb37f702e
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersliuche
bugs1255162
milestone48.0a1
Bug 1255162 - Replace NineOldAndroids with system API. r=liuche NineOldAndroids is a backport of the animation API that was introduced with Honeycomb. Since we stopped supporting Gingerbread we do not need this library anymore and can just use the system API. MozReview-Commit-ID: Fv6ALlIktt5
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/animation/TransitionsTracker.java
mobile/android/base/java/org/mozilla/gecko/firstrun/FirstrunAnimationContainer.java
mobile/android/base/java/org/mozilla/gecko/firstrun/FirstrunPager.java
mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueuePrompt.java
mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java
mobile/android/base/java/org/mozilla/gecko/tabs/TabsGridLayout.java
mobile/android/base/java/org/mozilla/gecko/trackingprotection/TrackingProtectionPrompt.java
mobile/android/base/java/org/mozilla/gecko/widget/CropImageView.java
mobile/android/base/java/org/mozilla/gecko/widget/SwipeDismissListViewTouchListener.java
mobile/android/base/moz.build
mobile/android/search/java/org/mozilla/search/SearchActivity.java
mobile/android/thirdparty/com/nineoldandroids/animation/Animator.java
mobile/android/thirdparty/com/nineoldandroids/animation/AnimatorInflater.java
mobile/android/thirdparty/com/nineoldandroids/animation/AnimatorListenerAdapter.java
mobile/android/thirdparty/com/nineoldandroids/animation/AnimatorSet.java
mobile/android/thirdparty/com/nineoldandroids/animation/ArgbEvaluator.java
mobile/android/thirdparty/com/nineoldandroids/animation/FloatEvaluator.java
mobile/android/thirdparty/com/nineoldandroids/animation/FloatKeyframeSet.java
mobile/android/thirdparty/com/nineoldandroids/animation/IntEvaluator.java
mobile/android/thirdparty/com/nineoldandroids/animation/IntKeyframeSet.java
mobile/android/thirdparty/com/nineoldandroids/animation/Keyframe.java
mobile/android/thirdparty/com/nineoldandroids/animation/KeyframeSet.java
mobile/android/thirdparty/com/nineoldandroids/animation/ObjectAnimator.java
mobile/android/thirdparty/com/nineoldandroids/animation/PreHoneycombCompat.java
mobile/android/thirdparty/com/nineoldandroids/animation/PropertyValuesHolder.java
mobile/android/thirdparty/com/nineoldandroids/animation/TimeAnimator.java
mobile/android/thirdparty/com/nineoldandroids/animation/TypeEvaluator.java
mobile/android/thirdparty/com/nineoldandroids/animation/ValueAnimator.java
mobile/android/thirdparty/com/nineoldandroids/util/FloatProperty.java
mobile/android/thirdparty/com/nineoldandroids/util/IntProperty.java
mobile/android/thirdparty/com/nineoldandroids/util/NoSuchPropertyException.java
mobile/android/thirdparty/com/nineoldandroids/util/Property.java
mobile/android/thirdparty/com/nineoldandroids/util/ReflectiveProperty.java
mobile/android/thirdparty/com/nineoldandroids/view/ViewHelper.java
mobile/android/thirdparty/com/nineoldandroids/view/ViewPropertyAnimator.java
mobile/android/thirdparty/com/nineoldandroids/view/ViewPropertyAnimatorHC.java
mobile/android/thirdparty/com/nineoldandroids/view/ViewPropertyAnimatorICS.java
mobile/android/thirdparty/com/nineoldandroids/view/ViewPropertyAnimatorPreHC.java
mobile/android/thirdparty/com/nineoldandroids/view/animation/AnimatorProxy.java
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -138,18 +138,18 @@ import android.view.ViewTreeObserver;
 import android.view.Window;
 import android.view.animation.Interpolator;
 import android.widget.Button;
 import android.widget.ListView;
 import android.widget.RelativeLayout;
 import android.widget.ViewFlipper;
 import com.keepsafe.switchboard.AsyncConfigLoader;
 import com.keepsafe.switchboard.SwitchBoard;
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.ObjectAnimator;
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.lang.reflect.Method;
--- a/mobile/android/base/java/org/mozilla/gecko/animation/TransitionsTracker.java
+++ b/mobile/android/base/java/org/mozilla/gecko/animation/TransitionsTracker.java
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.animation;
 
-import com.nineoldandroids.animation.Animator;
+import android.animation.Animator;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
 import org.mozilla.gecko.animation.PropertyAnimator;
 import org.mozilla.gecko.animation.PropertyAnimator.PropertyAnimationListener;
 import org.mozilla.gecko.util.ThreadUtils;
--- a/mobile/android/base/java/org/mozilla/gecko/firstrun/FirstrunAnimationContainer.java
+++ b/mobile/android/base/java/org/mozilla/gecko/firstrun/FirstrunAnimationContainer.java
@@ -6,19 +6,19 @@
 package org.mozilla.gecko.firstrun;
 
 import android.content.Context;
 import android.support.v4.app.FragmentManager;
 import android.util.AttributeSet;
 
 import android.view.View;
 import android.widget.LinearLayout;
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.AnimatorListenerAdapter;
-import com.nineoldandroids.animation.ObjectAnimator;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.animation.TransitionsTracker;
 import org.mozilla.gecko.util.Experiments;
 
 /**
  * A container for the pager and the entire first run experience.
--- a/mobile/android/base/java/org/mozilla/gecko/firstrun/FirstrunPager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/firstrun/FirstrunPager.java
@@ -8,20 +8,19 @@ package org.mozilla.gecko.firstrun;
 import android.content.Context;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentPagerAdapter;
 import android.support.v4.view.ViewPager;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.AnimatorSet;
-import com.nineoldandroids.animation.ObjectAnimator;
-import com.nineoldandroids.view.ViewHelper;
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 
 import org.mozilla.gecko.Restrictions;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.animation.TransitionsTracker;
 import org.mozilla.gecko.home.HomePager.Decor;
 import org.mozilla.gecko.home.TabMenuStrip;
 
@@ -117,18 +116,18 @@ public class FirstrunPager extends ViewP
         Telemetry.sendUIEvent(TelemetryContract.Event.SHOW, TelemetryContract.Method.PANEL, "onboarding.0");
     }
 
     public void cleanup() {
         setAdapter(null);
     }
 
     private void animateLoad() {
-        ViewHelper.setTranslationY(this, 500);
-        ViewHelper.setAlpha(this, 0);
+        setTranslationY(500);
+        setAlpha(0);
 
         final Animator translateAnimator = ObjectAnimator.ofFloat(this, "translationY", 0);
         translateAnimator.setDuration(400);
 
         final Animator alphaAnimator = ObjectAnimator.ofFloat(this, "alpha", 1);
         alphaAnimator.setStartDelay(200);
         alphaAnimator.setDuration(600);
 
--- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueuePrompt.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueuePrompt.java
@@ -18,21 +18,20 @@ import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.Toast;
 
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.AnimatorListenerAdapter;
-import com.nineoldandroids.animation.AnimatorSet;
-import com.nineoldandroids.animation.ObjectAnimator;
-import com.nineoldandroids.view.ViewHelper;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 
 public class TabQueuePrompt extends Locales.LocaleAwareActivity {
     public static final String LOGTAG = "Gecko" + TabQueuePrompt.class.getSimpleName();
 
     private static final int SETTINGS_REQUEST_CODE = 1;
 
     // Flag set during animation to prevent animation multiple-start.
     private boolean isAnimating;
@@ -91,18 +90,18 @@ public class TabQueuePrompt extends Loca
             tipView.setVisibility(View.GONE);
             settingsPermitView.setVisibility(View.VISIBLE);
         }
 
         containerView = findViewById(R.id.tab_queue_container);
         buttonContainer = findViewById(R.id.button_container);
         enabledConfirmation = findViewById(R.id.enabled_confirmation);
 
-        ViewHelper.setTranslationY(containerView, 500);
-        ViewHelper.setAlpha(containerView, 0);
+        containerView.setTranslationY(500);
+        containerView.setAlpha(0);
 
         final Animator translateAnimator = ObjectAnimator.ofFloat(containerView, "translationY", 0);
         translateAnimator.setDuration(400);
 
         final Animator alphaAnimator = ObjectAnimator.ofFloat(containerView, "alpha", 1);
         alphaAnimator.setStartDelay(200);
         alphaAnimator.setDuration(600);
 
@@ -119,17 +118,17 @@ public class TabQueuePrompt extends Loca
         super.finish();
 
         // Don't perform an activity-dismiss animation.
         overridePendingTransition(0, 0);
     }
 
     private void onConfirmButtonPressed() {
         enabledConfirmation.setVisibility(View.VISIBLE);
-        ViewHelper.setAlpha(enabledConfirmation, 0);
+        enabledConfirmation.setAlpha(0);
 
         final Animator buttonsAlphaAnimator = ObjectAnimator.ofFloat(buttonContainer, "alpha", 0);
         buttonsAlphaAnimator.setDuration(300);
 
         final Animator messagesAlphaAnimator = ObjectAnimator.ofFloat(enabledConfirmation, "alpha", 1);
         messagesAlphaAnimator.setDuration(300);
         messagesAlphaAnimator.setStartDelay(200);
 
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java
@@ -13,20 +13,20 @@ import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.animation.DecelerateInterpolator;
 import android.view.View;
 import android.view.ViewTreeObserver.OnPreDrawListener;
 
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.Animator.AnimatorListener;
-import com.nineoldandroids.animation.AnimatorSet;
-import com.nineoldandroids.animation.ObjectAnimator;
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 
 import java.util.ArrayList;
 import java.util.List;
 
 import org.mozilla.gecko.animation.TransitionsTracker;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsGridLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsGridLayout.java
@@ -29,22 +29,21 @@ import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.AbsListView;
 import android.widget.AdapterView;
 import android.widget.Button;
 import android.widget.GridView;
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.AnimatorSet;
-import com.nineoldandroids.animation.ObjectAnimator;
-import com.nineoldandroids.animation.PropertyValuesHolder;
-import com.nineoldandroids.animation.ValueAnimator;
-import com.nineoldandroids.view.ViewHelper;
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /**
  * A tabs layout implementation for the tablet redesign (bug 1014156) and later ported to mobile (bug 1193745).
  */
 
@@ -311,19 +310,19 @@ class TabsGridLayout extends GridView
                 tabData.add(tab);
         }
 
         tabsAdapter.setTabs(tabData);
         updateSelectedPosition();
     }
 
     private void resetTransforms(View view) {
-        ViewHelper.setAlpha(view, 1);
-        ViewHelper.setTranslationX(view, 0);
-        ViewHelper.setTranslationY(view, 0);
+        view.setAlpha(1);
+        view.setTranslationX(0);
+        view.setTranslationY(0);
 
         ((TabsLayoutItemView) view).setCloseVisible(true);
     }
 
     @Override
     public void closeAll() {
 
         autoHidePanel();
@@ -586,17 +585,17 @@ class TabsGridLayout extends GridView
 
                     mVelocityTracker.addMovement(e);
                     mVelocityTracker.computeCurrentVelocity(1000, mMaxFlingVelocity);
 
                     float velocityX = Math.abs(mVelocityTracker.getXVelocity());
 
                     boolean dismiss = false;
 
-                    float deltaX = ViewHelper.getTranslationX(mSwipeView);
+                    float deltaX = mSwipeView.getTranslationX();
 
                     if (Math.abs(deltaX) > mTabWidth / 2) {
                         dismiss = true;
                     } else if (mMinFlingVelocity <= velocityX && velocityX <= mMaxFlingVelocity) {
                         dismiss = mSwiping && (deltaX * mVelocityTracker.getYVelocity() > 0);
                     }
                     if (dismiss) {
                         closeTab(mSwipeView.findViewById(R.id.close));
@@ -640,20 +639,19 @@ class TabsGridLayout extends GridView
                         MotionEvent cancelEvent = MotionEvent.obtain(e);
                         cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
                                 (e.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
                         TabsGridLayout.this.onTouchEvent(cancelEvent);
                         cancelEvent.recycle();
                     }
 
                     if (mSwiping) {
-                        ViewHelper.setTranslationX(mSwipeView, delta);
+                        mSwipeView.setTranslationX(delta);
 
-                        ViewHelper.setAlpha(mSwipeView, Math.min(1f,
-                                1f - 2f * Math.abs(delta) / mTabWidth));
+                        mSwipeView.setAlpha(Math.min(1f, 1f - 2f * Math.abs(delta) / mTabWidth));
 
                         return true;
                     }
 
                     break;
                 }
             }
             return false;
--- a/mobile/android/base/java/org/mozilla/gecko/trackingprotection/TrackingProtectionPrompt.java
+++ b/mobile/android/base/java/org/mozilla/gecko/trackingprotection/TrackingProtectionPrompt.java
@@ -10,21 +10,20 @@ import org.mozilla.gecko.R;
 import org.mozilla.gecko.animation.TransitionsTracker;
 import org.mozilla.gecko.preferences.GeckoPreferences;
 import org.mozilla.gecko.util.HardwareUtils;
 
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.MotionEvent;
 import android.view.View;
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.AnimatorListenerAdapter;
-import com.nineoldandroids.animation.AnimatorSet;
-import com.nineoldandroids.animation.ObjectAnimator;
-import com.nineoldandroids.view.ViewHelper;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 
 public class TrackingProtectionPrompt extends Locales.LocaleAwareActivity {
         public static final String LOGTAG = "Gecko" + TrackingProtectionPrompt.class.getSimpleName();
 
         // Flag set during animation to prevent animation multiple-start.
         private boolean isAnimating;
 
         private View containerView;
@@ -58,18 +57,18 @@ public class TrackingProtectionPrompt ex
                     if (HardwareUtils.IS_KINDLE_DEVICE) {
                         overridePendingTransition(0, 0);
                     }
                 }
             });
 
             containerView = findViewById(R.id.tracking_protection_inner_container);
 
-            ViewHelper.setTranslationY(containerView, 500);
-            ViewHelper.setAlpha(containerView, 0);
+            containerView.setTranslationY(500);
+            containerView.setAlpha(0);
 
             final Animator translateAnimator = ObjectAnimator.ofFloat(containerView, "translationY", 0);
             translateAnimator.setDuration(400);
 
             final Animator alphaAnimator = ObjectAnimator.ofFloat(containerView, "alpha", 1);
             alphaAnimator.setStartDelay(200);
             alphaAnimator.setDuration(600);
 
--- a/mobile/android/base/java/org/mozilla/gecko/widget/CropImageView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/CropImageView.java
@@ -7,17 +7,16 @@ package org.mozilla.gecko.widget;
 
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
-import com.nineoldandroids.view.ViewHelper;
 import org.mozilla.gecko.widget.themed.ThemedImageView;
 
 /**
  * An ImageView which will always display at the given width and calculated height (based on the width and
  * the supplied aspect ratio), drawn starting from the top left hand corner.  A supplied drawable will be resized to fit
  * the width of the view; if the resized drawable is too tall for the view then the drawable will be cropped at the
  * bottom, however if the resized drawable is too short for the view to display whilst honouring it's given width and
  * height then the drawable will be displayed at full height with the right hand side cropped.
@@ -49,18 +48,18 @@ public abstract class CropImageView exte
     }
 
     protected abstract float getAspectRatio();
 
     protected void init() {
         // Setting the pivots means that the image will be drawn from the top left hand corner.  There are
         // issues in Android 4.1 (16) which mean setting these values to 0 may not work.
         // http://stackoverflow.com/questions/26658124/setpivotx-doesnt-work-on-android-4-1-1-nineoldandroids
-        ViewHelper.setPivotX(this, 1);
-        ViewHelper.setPivotY(this, 1);
+        setPivotX(1);
+        setPivotY(1);
     }
 
     /**
      * Measure the view to determine the measured width and height.
      * The height is constrained by the measured width.
      *
      * @param widthMeasureSpec  horizontal space requirements as imposed by the parent.
      * @param heightMeasureSpec vertical space requirements as imposed by the parent, but ignored.
--- a/mobile/android/base/java/org/mozilla/gecko/widget/SwipeDismissListViewTouchListener.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/SwipeDismissListViewTouchListener.java
@@ -21,21 +21,20 @@ import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.widget.AbsListView;
 import android.widget.AbsListView.RecyclerListener;
 import android.widget.ListView;
 
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.AnimatorListenerAdapter;
-import com.nineoldandroids.animation.ValueAnimator;
-import com.nineoldandroids.view.ViewHelper;
-import com.nineoldandroids.view.ViewPropertyAnimator;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.view.ViewPropertyAnimator;
 
 import org.mozilla.gecko.R;
 
 /**
  * This code is based off of Jake Wharton's NOA port (https://github.com/JakeWharton/SwipeToDismissNOA)
  * of Roman Nurik's SwipeToDismiss library. It has been modified for better support with async
  * adapters.
  *
@@ -168,18 +167,18 @@ public class SwipeDismissListViewTouchLi
         return new AbsListView.RecyclerListener() {
             @Override
             public void onMovedToScrapHeap(View view) {
                 final Object tag = view.getTag(R.id.original_height);
 
                 // To reset the view to the correct height after its animation, the view's height
                 // is stored in its tag. Reset the view here.
                 if (tag instanceof Integer) {
-                    ViewHelper.setAlpha(view, 1f);
-                    ViewHelper.setTranslationX(view, 0);
+                    view.setAlpha(1f);
+                    view.setTranslationX(0);
                     final ViewGroup.LayoutParams lp = view.getLayoutParams();
                     lp.height = (int) tag;
                     view.setLayoutParams(lp);
                     view.setTag(R.id.original_height, null);
                 }
             }
         };
     }
@@ -250,29 +249,29 @@ public class SwipeDismissListViewTouchLi
                     dismiss = true;
                     dismissRight = mVelocityTracker.getXVelocity() > 0;
                 }
                 if (dismiss) {
                     // dismiss
                     mDismissing = true;
                     final View downView = mDownView; // mDownView gets null'd before animation ends
                     final int downPosition = mDownPosition;
-                    ViewPropertyAnimator.animate(mDownView)
+                    mDownView.animate()
                             .translationX(dismissRight ? mViewWidth : -mViewWidth)
                             .alpha(0)
                             .setDuration(mAnimationTime)
                             .setListener(new AnimatorListenerAdapter() {
                                 @Override
                                 public void onAnimationEnd(Animator animation) {
                                     performDismiss(downView, downPosition);
                                 }
                             });
                 } else {
                     // cancel
-                    ViewPropertyAnimator.animate(mDownView)
+                    mDownView.animate()
                             .translationX(0)
                             .alpha(1)
                             .setDuration(mAnimationTime)
                             .setListener(null);
                 }
 
                 if (mVelocityTracker != null) {
                     mVelocityTracker.recycle();
@@ -302,19 +301,18 @@ public class SwipeDismissListViewTouchLi
                     cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
                             (motionEvent.getActionIndex()
                                     << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
                     mListView.onTouchEvent(cancelEvent);
                     cancelEvent.recycle();
                 }
 
                 if (mSwiping) {
-                    ViewHelper.setTranslationX(mDownView, deltaX);
-                    ViewHelper.setAlpha(mDownView, Math.max(0f, Math.min(1f,
-                            1f - 2f * Math.abs(deltaX) / mViewWidth)));
+                    mDownView.setTranslationX(deltaX);
+                    mDownView.setAlpha(Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / mViewWidth)));
                     return true;
                 }
                 break;
             }
         }
         return false;
     }
 
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -794,44 +794,16 @@ gbjar.javac_flags += ['-Xlint:all,-depre
 # gecko-thirdparty is a good place to put small independent libraries
 gtjar = add_java_jar('gecko-thirdparty')
 gtjar.sources += [ thirdparty_source_dir + f for f in [
     'com/keepsafe/switchboard/AsyncConfigLoader.java',
     'com/keepsafe/switchboard/DeviceUuidFactory.java',
     'com/keepsafe/switchboard/Preferences.java',
     'com/keepsafe/switchboard/Switch.java',
     'com/keepsafe/switchboard/SwitchBoard.java',
-    'com/nineoldandroids/animation/Animator.java',
-    'com/nineoldandroids/animation/AnimatorInflater.java',
-    'com/nineoldandroids/animation/AnimatorListenerAdapter.java',
-    'com/nineoldandroids/animation/AnimatorSet.java',
-    'com/nineoldandroids/animation/ArgbEvaluator.java',
-    'com/nineoldandroids/animation/FloatEvaluator.java',
-    'com/nineoldandroids/animation/FloatKeyframeSet.java',
-    'com/nineoldandroids/animation/IntEvaluator.java',
-    'com/nineoldandroids/animation/IntKeyframeSet.java',
-    'com/nineoldandroids/animation/Keyframe.java',
-    'com/nineoldandroids/animation/KeyframeSet.java',
-    'com/nineoldandroids/animation/ObjectAnimator.java',
-    'com/nineoldandroids/animation/PreHoneycombCompat.java',
-    'com/nineoldandroids/animation/PropertyValuesHolder.java',
-    'com/nineoldandroids/animation/TimeAnimator.java',
-    'com/nineoldandroids/animation/TypeEvaluator.java',
-    'com/nineoldandroids/animation/ValueAnimator.java',
-    'com/nineoldandroids/util/FloatProperty.java',
-    'com/nineoldandroids/util/IntProperty.java',
-    'com/nineoldandroids/util/NoSuchPropertyException.java',
-    'com/nineoldandroids/util/Property.java',
-    'com/nineoldandroids/util/ReflectiveProperty.java',
-    'com/nineoldandroids/view/animation/AnimatorProxy.java',
-    'com/nineoldandroids/view/ViewHelper.java',
-    'com/nineoldandroids/view/ViewPropertyAnimator.java',
-    'com/nineoldandroids/view/ViewPropertyAnimatorHC.java',
-    'com/nineoldandroids/view/ViewPropertyAnimatorICS.java',
-    'com/nineoldandroids/view/ViewPropertyAnimatorPreHC.java',
     'com/squareup/leakcanary/LeakCanary.java',
     'com/squareup/leakcanary/RefWatcher.java',
     'com/squareup/picasso/Action.java',
     'com/squareup/picasso/AssetBitmapHunter.java',
     'com/squareup/picasso/BitmapHunter.java',
     'com/squareup/picasso/Cache.java',
     'com/squareup/picasso/Callback.java',
     'com/squareup/picasso/ContactsPhotoBitmapHunter.java',
--- a/mobile/android/search/java/org/mozilla/search/SearchActivity.java
+++ b/mobile/android/search/java/org/mozilla/search/SearchActivity.java
@@ -24,19 +24,19 @@ import android.content.Intent;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 import android.view.animation.AccelerateDecelerateInterpolator;
 import android.view.animation.Interpolator;
 
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.AnimatorSet;
-import com.nineoldandroids.animation.ObjectAnimator;
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 
 /**
  * The main entrance for the Android search intent.
  * <p/>
  * State management is delegated to child fragments. Fragments communicate
  * with each other by passing messages through this activity.
  */
 public class SearchActivity extends Locales.LocaleAwareFragmentActivity
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/Animator.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-import java.util.ArrayList;
-
-import android.view.animation.Interpolator;
-
-/**
- * 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 abstract class Animator implements Cloneable {
-
-
-    /**
-     * The set of listeners to be sent events through the life of an animation.
-     */
-    ArrayList<AnimatorListener> mListeners = null;
-
-    /**
-     * Starts this animation. If the animation has a nonzero startDelay, the animation will start
-     * running after that delay elapses. A non-delayed animation will have its initial
-     * value(s) set immediately, followed by calls to
-     * {@link AnimatorListener#onAnimationStart(Animator)} for any listeners of this animator.
-     *
-     * <p>The animation started by calling this method will be run on the thread that called
-     * this method. This thread should have a Looper on it (a runtime exception will be thrown if
-     * this is not the case). Also, if the animation will animate
-     * properties of objects in the view hierarchy, then the calling thread should be the UI
-     * thread for that view hierarchy.</p>
-     *
-     */
-    public void start() {
-    }
-
-    /**
-     * 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.
-     *
-     * <p>This method must be called on the thread that is running the animation.</p>
-     */
-    public void cancel() {
-    }
-
-    /**
-     * 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.
-     *
-     * <p>This method must be called on the thread that is running the animation.</p>
-     */
-    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 Animator 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(/*Time*/Interpolator value);
-
-    /**
-     * Returns whether this Animator is currently running (having been started and gone past any
-     * initial startDelay period and not yet ended).
-     *
-     * @return Whether the Animator is running.
-     */
-    public abstract boolean isRunning();
-
-    /**
-     * Returns whether this Animator has been started and not yet ended. This state is a superset
-     * of the state of {@link #isRunning()}, because an Animator with a nonzero
-     * {@link #getStartDelay() startDelay} will return true for {@link #isStarted()} during the
-     * delay phase, whereas {@link #isRunning()} will return true only after the delay phase
-     * is complete.
-     *
-     * @return Whether the Animator has been started and not yet ended.
-     */
-    public boolean isStarted() {
-        // Default method returns value for isRunning(). Subclasses should override to return a
-        // real value.
-        return 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;
-        }
-    }
-
-    /**
-     * Gets the set of {@link android.animation.Animator.AnimatorListener} objects that are currently
-     * listening for events on this <code>Animator</code> object.
-     *
-     * @return ArrayList<AnimatorListener> The set of listeners.
-     */
-    public ArrayList<AnimatorListener> 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 Animator clone() {
-        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();
-        }
-    }
-
-    /**
-     * 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 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 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 onAnimationRepeat(Animator animation);
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/AnimatorInflater.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.nineoldandroids.animation;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.content.res.Resources.NotFoundException;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.util.Xml;
-import android.view.animation.AnimationUtils;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * This class is used to instantiate animator XML files into Animator objects.
- * <p>
- * For performance reasons, inflation relies heavily on pre-processing of
- * XML files that is done at build time. Therefore, it is not currently possible
- * to use this inflater with an XmlPullParser over a plain XML file at runtime;
- * it only works with an XmlPullParser returned from a compiled resource (R.
- * <em>something</em> file.)
- */
-public class AnimatorInflater {
-    private static final int[] AnimatorSet = new int[] {
-        /* 0 */ android.R.attr.ordering,
-    };
-    private static final int AnimatorSet_ordering = 0;
-
-    private static final int[] PropertyAnimator = new int[] {
-        /* 0 */ android.R.attr.propertyName,
-    };
-    private static final int PropertyAnimator_propertyName = 0;
-
-    private static final int[] Animator = new int[] {
-        /* 0 */ android.R.attr.interpolator,
-        /* 1 */ android.R.attr.duration,
-        /* 2 */ android.R.attr.startOffset,
-        /* 3 */ android.R.attr.repeatCount,
-        /* 4 */ android.R.attr.repeatMode,
-        /* 5 */ android.R.attr.valueFrom,
-        /* 6 */ android.R.attr.valueTo,
-        /* 7 */ android.R.attr.valueType,
-    };
-    private static final int Animator_interpolator = 0;
-    private static final int Animator_duration = 1;
-    private static final int Animator_startOffset = 2;
-    private static final int Animator_repeatCount = 3;
-    private static final int Animator_repeatMode = 4;
-    private static final int Animator_valueFrom = 5;
-    private static final int Animator_valueTo = 6;
-    private static final int Animator_valueType = 7;
-
-    /**
-     * These flags are used when parsing AnimatorSet objects
-     */
-    private static final int TOGETHER = 0;
-    //private static final int SEQUENTIALLY = 1;
-
-    /**
-     * Enum values used in XML attributes to indicate the value for mValueType
-     */
-    private static final int VALUE_TYPE_FLOAT       = 0;
-    //private static final int VALUE_TYPE_INT         = 1;
-    //private static final int VALUE_TYPE_COLOR       = 4;
-    //private static final int VALUE_TYPE_CUSTOM      = 5;
-
-    /**
-     * 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 animator object reference by the specified id
-     * @throws android.content.res.Resources.NotFoundException when the animation cannot be loaded
-     */
-    public static Animator loadAnimator(Context context, int id)
-            throws NotFoundException {
-
-        XmlResourceParser parser = null;
-        try {
-            parser = context.getResources().getAnimation(id);
-            return createAnimatorFromXml(context, parser);
-        } catch (XmlPullParserException ex) {
-            Resources.NotFoundException rnf =
-                    new Resources.NotFoundException("Can't load animation resource ID #0x" +
-                    Integer.toHexString(id));
-            rnf.initCause(ex);
-            throw rnf;
-        } catch (IOException ex) {
-            Resources.NotFoundException rnf =
-                    new Resources.NotFoundException("Can't load animation resource ID #0x" +
-                    Integer.toHexString(id));
-            rnf.initCause(ex);
-            throw rnf;
-        } finally {
-            if (parser != null) parser.close();
-        }
-    }
-
-    private static Animator createAnimatorFromXml(Context c, XmlPullParser parser)
-            throws XmlPullParserException, IOException {
-
-        return createAnimatorFromXml(c, parser, Xml.asAttributeSet(parser), null, 0);
-    }
-
-    private static Animator createAnimatorFromXml(Context c, XmlPullParser parser,
-            AttributeSet attrs, AnimatorSet parent, int sequenceOrdering)
-            throws XmlPullParserException, IOException {
-
-        Animator anim = null;
-        ArrayList<Animator> childAnims = null;
-
-        // Make sure we are on a start tag.
-        int type;
-        int depth = parser.getDepth();
-
-        while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
-               && type != XmlPullParser.END_DOCUMENT) {
-
-            if (type != XmlPullParser.START_TAG) {
-                continue;
-            }
-
-            String  name = parser.getName();
-
-            if (name.equals("objectAnimator")) {
-                anim = loadObjectAnimator(c, attrs);
-            } else if (name.equals("animator")) {
-                anim = loadAnimator(c, attrs, null);
-            } else if (name.equals("set")) {
-                anim = new AnimatorSet();
-                TypedArray a = c.obtainStyledAttributes(attrs,
-                        /*com.android.internal.R.styleable.*/AnimatorSet);
-
-                TypedValue orderingValue = new TypedValue();
-                a.getValue(/*com.android.internal.R.styleable.*/AnimatorSet_ordering, orderingValue);
-                int ordering = orderingValue.type == TypedValue.TYPE_INT_DEC ? orderingValue.data : TOGETHER;
-
-                createAnimatorFromXml(c, parser, attrs, (AnimatorSet) anim,  ordering);
-                a.recycle();
-            } else {
-                throw new RuntimeException("Unknown animator name: " + parser.getName());
-            }
-
-            if (parent != null) {
-                if (childAnims == null) {
-                    childAnims = new ArrayList<Animator>();
-                }
-                childAnims.add(anim);
-            }
-        }
-        if (parent != null && childAnims != null) {
-            Animator[] animsArray = new Animator[childAnims.size()];
-            int index = 0;
-            for (Animator a : childAnims) {
-                animsArray[index++] = a;
-            }
-            if (sequenceOrdering == TOGETHER) {
-                parent.playTogether(animsArray);
-            } else {
-                parent.playSequentially(animsArray);
-            }
-        }
-
-        return anim;
-
-    }
-
-    private static ObjectAnimator loadObjectAnimator(Context context, AttributeSet attrs)
-            throws NotFoundException {
-
-        ObjectAnimator anim = new ObjectAnimator();
-
-        loadAnimator(context, attrs, anim);
-
-        TypedArray a =
-                context.obtainStyledAttributes(attrs, /*com.android.internal.R.styleable.*/PropertyAnimator);
-
-        String propertyName = a.getString(/*com.android.internal.R.styleable.*/PropertyAnimator_propertyName);
-
-        anim.setPropertyName(propertyName);
-
-        a.recycle();
-
-        return anim;
-    }
-
-    /**
-     * Creates a new animation whose parameters come from the specified context and
-     * attributes set.
-     *
-     * @param context the application environment
-     * @param attrs the set of attributes holding the animation parameters
-     */
-    private static ValueAnimator loadAnimator(Context context, AttributeSet attrs, ValueAnimator anim)
-            throws NotFoundException {
-
-        TypedArray a =
-                context.obtainStyledAttributes(attrs, /*com.android.internal.R.styleable.*/Animator);
-
-        long duration = a.getInt(/*com.android.internal.R.styleable.*/Animator_duration, 0);
-
-        long startDelay = a.getInt(/*com.android.internal.R.styleable.*/Animator_startOffset, 0);
-
-        int valueType = a.getInt(/*com.android.internal.R.styleable.*/Animator_valueType,
-                VALUE_TYPE_FLOAT);
-
-        if (anim == null) {
-            anim = new ValueAnimator();
-        }
-        //TypeEvaluator evaluator = null;
-
-        int valueFromIndex = /*com.android.internal.R.styleable.*/Animator_valueFrom;
-        int valueToIndex = /*com.android.internal.R.styleable.*/Animator_valueTo;
-
-        boolean getFloats = (valueType == VALUE_TYPE_FLOAT);
-
-        TypedValue tvFrom = a.peekValue(valueFromIndex);
-        boolean hasFrom = (tvFrom != null);
-        int fromType = hasFrom ? tvFrom.type : 0;
-        TypedValue tvTo = a.peekValue(valueToIndex);
-        boolean hasTo = (tvTo != null);
-        int toType = hasTo ? tvTo.type : 0;
-
-        if ((hasFrom && (fromType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                (fromType <= TypedValue.TYPE_LAST_COLOR_INT)) ||
-            (hasTo && (toType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                (toType <= TypedValue.TYPE_LAST_COLOR_INT))) {
-            // special case for colors: ignore valueType and get ints
-            getFloats = false;
-            anim.setEvaluator(new ArgbEvaluator());
-        }
-
-        if (getFloats) {
-            float valueFrom;
-            float valueTo;
-            if (hasFrom) {
-                if (fromType == TypedValue.TYPE_DIMENSION) {
-                    valueFrom = a.getDimension(valueFromIndex, 0f);
-                } else {
-                    valueFrom = a.getFloat(valueFromIndex, 0f);
-                }
-                if (hasTo) {
-                    if (toType == TypedValue.TYPE_DIMENSION) {
-                        valueTo = a.getDimension(valueToIndex, 0f);
-                    } else {
-                        valueTo = a.getFloat(valueToIndex, 0f);
-                    }
-                    anim.setFloatValues(valueFrom, valueTo);
-                } else {
-                    anim.setFloatValues(valueFrom);
-                }
-            } else {
-                if (toType == TypedValue.TYPE_DIMENSION) {
-                    valueTo = a.getDimension(valueToIndex, 0f);
-                } else {
-                    valueTo = a.getFloat(valueToIndex, 0f);
-                }
-                anim.setFloatValues(valueTo);
-            }
-        } else {
-            int valueFrom;
-            int valueTo;
-            if (hasFrom) {
-                if (fromType == TypedValue.TYPE_DIMENSION) {
-                    valueFrom = (int) a.getDimension(valueFromIndex, 0f);
-                } else if ((fromType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                        (fromType <= TypedValue.TYPE_LAST_COLOR_INT)) {
-                    valueFrom = a.getColor(valueFromIndex, 0);
-                } else {
-                    valueFrom = a.getInt(valueFromIndex, 0);
-                }
-                if (hasTo) {
-                    if (toType == TypedValue.TYPE_DIMENSION) {
-                        valueTo = (int) a.getDimension(valueToIndex, 0f);
-                    } else if ((toType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                            (toType <= TypedValue.TYPE_LAST_COLOR_INT)) {
-                        valueTo = a.getColor(valueToIndex, 0);
-                    } else {
-                        valueTo = a.getInt(valueToIndex, 0);
-                    }
-                    anim.setIntValues(valueFrom, valueTo);
-                } else {
-                    anim.setIntValues(valueFrom);
-                }
-            } else {
-                if (hasTo) {
-                    if (toType == TypedValue.TYPE_DIMENSION) {
-                        valueTo = (int) a.getDimension(valueToIndex, 0f);
-                    } else if ((toType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                        (toType <= TypedValue.TYPE_LAST_COLOR_INT)) {
-                        valueTo = a.getColor(valueToIndex, 0);
-                    } else {
-                        valueTo = a.getInt(valueToIndex, 0);
-                    }
-                    anim.setIntValues(valueTo);
-                }
-            }
-        }
-
-        anim.setDuration(duration);
-        anim.setStartDelay(startDelay);
-
-        if (a.hasValue(/*com.android.internal.R.styleable.*/Animator_repeatCount)) {
-            anim.setRepeatCount(
-                    a.getInt(/*com.android.internal.R.styleable.*/Animator_repeatCount, 0));
-        }
-        if (a.hasValue(/*com.android.internal.R.styleable.*/Animator_repeatMode)) {
-            anim.setRepeatMode(
-                    a.getInt(/*com.android.internal.R.styleable.*/Animator_repeatMode,
-                            ValueAnimator.RESTART));
-        }
-        //if (evaluator != null) {
-        //    anim.setEvaluator(evaluator);
-        //}
-
-        final int resID =
-                a.getResourceId(/*com.android.internal.R.styleable.*/Animator_interpolator, 0);
-        if (resID > 0) {
-            anim.setInterpolator(AnimationUtils.loadInterpolator(context, resID));
-        }
-        a.recycle();
-
-        return anim;
-    }
-}
\ No newline at end of file
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/AnimatorListenerAdapter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-/**
- * 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 AnimatorListenerAdapter implements Animator.AnimatorListener {
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onAnimationCancel(Animator animation) {
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onAnimationEnd(Animator animation) {
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onAnimationRepeat(Animator animation) {
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onAnimationStart(Animator animation) {
-    }
-
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/AnimatorSet.java
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-
-import android.view.animation.Interpolator;
-
-/**
- * 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>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>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 AnimatorSet extends Animator {
-
-    /**
-     * 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.
-     */
-
-    /**
-     * Tracks animations currently being played, so that we know what to
-     * cancel or end when cancel() or end() is called on this AnimatorSet
-     */
-    private ArrayList<Animator> mPlayingSet = new ArrayList<Animator>();
-
-    /**
-     * 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<Animator, Node> mNodeMap = new HashMap<Animator, Node>();
-
-    /**
-     * 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>();
-
-    /**
-     * The sorted list of nodes. This is the order in which the animations will
-     * be played. The details about when exactly they will be played depend
-     * on the dependency relationships of the nodes.
-     */
-    private ArrayList<Node> mSortedNodes = new ArrayList<Node>();
-
-    /**
-     * Flag indicating whether the nodes should be sorted prior to playing. This
-     * flag allows us to cache the previous sorted nodes so that if the sequence
-     * is replayed with no changes, it does not have to re-sort the nodes again.
-     */
-    private boolean mNeedsSort = true;
-
-    private AnimatorSetListener mSetListener = null;
-
-    /**
-     * Flag indicating that the AnimatorSet has been manually
-     * terminated (by calling cancel() or end()).
-     * This flag is used to avoid starting other animations when currently-playing
-     * child animations of this AnimatorSet end. It also determines whether cancel/end
-     * notifications are sent out via the normal AnimatorSetListener mechanism.
-     */
-    boolean mTerminated = false;
-
-    /**
-     * Indicates whether an AnimatorSet has been start()'d, whether or
-     * not there is a nonzero startDelay.
-     */
-    private boolean mStarted = false;
-
-    // The amount of time in ms to delay starting the animation after start() is called
-    private long mStartDelay = 0;
-
-    // Animator used for a nonzero startDelay
-    private ValueAnimator mDelayAnim = null;
-
-
-    // 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 AnimatorSet. When a real duration is
-    // set, it is passed along to the child animations.
-    private long mDuration = -1;
-
-
-    /**
-     * Sets up this AnimatorSet to play all of the supplied animations at the same time.
-     *
-     * @param items The animations that will be started simultaneously.
-     */
-    public void playTogether(Animator... items) {
-        if (items != null) {
-            mNeedsSort = true;
-            Builder builder = play(items[0]);
-            for (int i = 1; i < items.length; ++i) {
-                builder.with(items[i]);
-            }
-        }
-    }
-
-    /**
-     * Sets up this AnimatorSet to play all of the supplied animations at the same time.
-     *
-     * @param items The animations that will be started simultaneously.
-     */
-    public void playTogether(Collection<Animator> items) {
-        if (items != null && items.size() > 0) {
-            mNeedsSort = true;
-            Builder builder = null;
-            for (Animator anim : items) {
-                if (builder == null) {
-                    builder = play(anim);
-                } else {
-                    builder.with(anim);
-                }
-            }
-        }
-    }
-
-    /**
-     * Sets up this AnimatorSet to play each of the supplied animations when the
-     * previous animation ends.
-     *
-     * @param items The animations that will be started one after another.
-     */
-    public void playSequentially(Animator... items) {
-        if (items != null) {
-            mNeedsSort = true;
-            if (items.length == 1) {
-                play(items[0]);
-            } else {
-                for (int i = 0; i < items.length - 1; ++i) {
-                    play(items[i]).before(items[i+1]);
-                }
-            }
-        }
-    }
-
-    /**
-     * Sets up this AnimatorSet to play each of the supplied animations when the
-     * previous animation ends.
-     *
-     * @param items The animations that will be started one after another.
-     */
-    public void playSequentially(List<Animator> items) {
-        if (items != null && items.size() > 0) {
-            mNeedsSort = true;
-            if (items.size() == 1) {
-                play(items.get(0));
-            } else {
-                for (int i = 0; i < items.size() - 1; ++i) {
-                    play(items.get(i)).before(items.get(i+1));
-                }
-            }
-        }
-    }
-
-    /**
-     * 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<Animator> The list of child animations of this AnimatorSet.
-     */
-    public ArrayList<Animator> getChildAnimations() {
-        ArrayList<Animator> childList = new ArrayList<Animator>();
-        for (Node node : mNodes) {
-            childList.add(node.animation);
-        }
-        return childList;
-    }
-
-    /**
-     * Sets the target object for all current {@link #getChildAnimations() child animations}
-     * 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) {
-            Animator animation = node.animation;
-            if (animation instanceof AnimatorSet) {
-                ((AnimatorSet)animation).setTarget(target);
-            } else if (animation instanceof ObjectAnimator) {
-                ((ObjectAnimator)animation).setTarget(target);
-            }
-        }
-    }
-
-    /**
-     * Sets the TimeInterpolator for all current {@link #getChildAnimations() child animations}
-     * of this AnimatorSet.
-     *
-     * @param interpolator the interpolator to be used by each child animation of this AnimatorSet
-     */
-    @Override
-    public void setInterpolator(/*Time*/Interpolator interpolator) {
-        for (Node node : mNodes) {
-            node.animation.setInterpolator(interpolator);
-        }
-    }
-
-    /**
-     * This method creates a <code>Builder</code> object, which is used to
-     * 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 AnimatorSet to play
-     * <code>a1</code> and <code>a2</code> at the same time,
-     * <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 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
-     * <code>Builder</code> the animation upon which the dependency is created,
-     * so successive calls to the various functions in <code>Builder</code>
-     * will all refer to the initial parameter supplied in <code>play()</code>
-     * as the dependency of the other animations. For example, calling
-     * <code>play(a1).before(a2).before(a3)</code> will play both <code>a2</code>
-     * and <code>a3</code> when a1 ends; it does not set up a dependency between
-     * <code>a2</code> and <code>a3</code>.</p>
-     *
-     * @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 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(Animator anim) {
-        if (anim != null) {
-            mNeedsSort = true;
-            return new Builder(anim);
-        }
-        return null;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p>Note that canceling a <code>AnimatorSet</code> also cancels all of the animations that it
-     * is responsible for.</p>
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public void cancel() {
-        mTerminated = true;
-        if (isStarted()) {
-            ArrayList<AnimatorListener> tmpListeners = null;
-            if (mListeners != null) {
-                tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone();
-                for (AnimatorListener listener : tmpListeners) {
-                    listener.onAnimationCancel(this);
-                }
-            }
-            if (mDelayAnim != null && mDelayAnim.isRunning()) {
-                // If we're currently in the startDelay period, just cancel that animator and
-                // send out the end event to all listeners
-                mDelayAnim.cancel();
-            } else  if (mSortedNodes.size() > 0) {
-                for (Node node : mSortedNodes) {
-                    node.animation.cancel();
-                }
-            }
-            if (tmpListeners != null) {
-                for (AnimatorListener listener : tmpListeners) {
-                    listener.onAnimationEnd(this);
-                }
-            }
-            mStarted = false;
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p>Note that ending a <code>AnimatorSet</code> also ends all of the animations that it is
-     * responsible for.</p>
-     */
-    @Override
-    public void end() {
-        mTerminated = true;
-        if (isStarted()) {
-            if (mSortedNodes.size() != mNodes.size()) {
-                // hasn't been started yet - sort the nodes now, then end them
-                sortNodes();
-                for (Node node : mSortedNodes) {
-                    if (mSetListener == null) {
-                        mSetListener = new AnimatorSetListener(this);
-                    }
-                    node.animation.addListener(mSetListener);
-                }
-            }
-            if (mDelayAnim != null) {
-                mDelayAnim.cancel();
-            }
-            if (mSortedNodes.size() > 0) {
-                for (Node node : mSortedNodes) {
-                    node.animation.end();
-                }
-            }
-            if (mListeners != null) {
-                ArrayList<AnimatorListener> tmpListeners =
-                        (ArrayList<AnimatorListener>) mListeners.clone();
-                for (AnimatorListener listener : tmpListeners) {
-                    listener.onAnimationEnd(this);
-                }
-            }
-            mStarted = false;
-        }
-    }
-
-    /**
-     * Returns true if any of the child animations of this AnimatorSet have been started and have
-     * not yet ended.
-     * @return Whether this AnimatorSet has been started and has not yet ended.
-     */
-    @Override
-    public boolean isRunning() {
-        for (Node node : mNodes) {
-            if (node.animation.isRunning()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isStarted() {
-        return mStarted;
-    }
-
-    /**
-     * 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
-     */
-    @Override
-    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
-     */
-    @Override
-    public void setStartDelay(long startDelay) {
-        mStartDelay = startDelay;
-    }
-
-    /**
-     * 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 AnimatorSet.
-     */
-    @Override
-    public long getDuration() {
-        return mDuration;
-    }
-
-    /**
-     * 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 AnimatorSet.
-     */
-    @Override
-    public AnimatorSet setDuration(long duration) {
-        if (duration < 0) {
-            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 AnimatorSet to
-            // insert "play-after" delays
-            node.animation.setDuration(duration);
-        }
-        mDuration = duration;
-        return this;
-    }
-
-    @Override
-    public void setupStartValues() {
-        for (Node node : mNodes) {
-            node.animation.setupStartValues();
-        }
-    }
-
-    @Override
-    public void setupEndValues() {
-        for (Node node : mNodes) {
-            node.animation.setupEndValues();
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <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.
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public void start() {
-        mTerminated = false;
-        mStarted = true;
-
-        // First, sort the nodes (if necessary). This will ensure that sortedNodes
-        // contains the animation nodes in the correct order.
-        sortNodes();
-
-        int numSortedNodes = mSortedNodes.size();
-        for (int i = 0; i < numSortedNodes; ++i) {
-            Node node = mSortedNodes.get(i);
-            // First, clear out the old listeners
-            ArrayList<AnimatorListener> oldListeners = node.animation.getListeners();
-            if (oldListeners != null && oldListeners.size() > 0) {
-                final ArrayList<AnimatorListener> clonedListeners = new
-                        ArrayList<AnimatorListener>(oldListeners);
-
-                for (AnimatorListener listener : clonedListeners) {
-                    if (listener instanceof DependencyListener ||
-                            listener instanceof AnimatorSetListener) {
-                        node.animation.removeListener(listener);
-                    }
-                }
-            }
-        }
-
-        // nodesToStart holds the list of nodes to be started immediately. We don't want to
-        // start the animations in the loop directly because we first need to set up
-        // dependencies on all of the nodes. For example, we don't want to start an animation
-        // when some other animation also wants to start when the first animation begins.
-        final ArrayList<Node> nodesToStart = new ArrayList<Node>();
-        for (int i = 0; i < numSortedNodes; ++i) {
-            Node node = mSortedNodes.get(i);
-            if (mSetListener == null) {
-                mSetListener = new AnimatorSetListener(this);
-            }
-            if (node.dependencies == null || node.dependencies.size() == 0) {
-                nodesToStart.add(node);
-            } else {
-                int numDependencies = node.dependencies.size();
-                for (int j = 0; j < numDependencies; ++j) {
-                    Dependency dependency = node.dependencies.get(j);
-                    dependency.node.animation.addListener(
-                            new DependencyListener(this, node, dependency.rule));
-                }
-                node.tmpDependencies = (ArrayList<Dependency>) node.dependencies.clone();
-            }
-            node.animation.addListener(mSetListener);
-        }
-        // Now that all dependencies are set up, start the animations that should be started.
-        if (mStartDelay <= 0) {
-            for (Node node : nodesToStart) {
-                node.animation.start();
-                mPlayingSet.add(node.animation);
-            }
-        } else {
-            mDelayAnim = ValueAnimator.ofFloat(0f, 1f);
-            mDelayAnim.setDuration(mStartDelay);
-            mDelayAnim.addListener(new AnimatorListenerAdapter() {
-                boolean canceled = false;
-                public void onAnimationCancel(Animator anim) {
-                    canceled = true;
-                }
-                public void onAnimationEnd(Animator anim) {
-                    if (!canceled) {
-                        int numNodes = nodesToStart.size();
-                        for (int i = 0; i < numNodes; ++i) {
-                            Node node = nodesToStart.get(i);
-                            node.animation.start();
-                            mPlayingSet.add(node.animation);
-                        }
-                    }
-                }
-            });
-            mDelayAnim.start();
-        }
-        if (mListeners != null) {
-            ArrayList<AnimatorListener> tmpListeners =
-                    (ArrayList<AnimatorListener>) mListeners.clone();
-            int numListeners = tmpListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                tmpListeners.get(i).onAnimationStart(this);
-            }
-        }
-        if (mNodes.size() == 0 && mStartDelay == 0) {
-            // Handle unusual case where empty AnimatorSet is started - should send out
-            // end event immediately since the event will not be sent out at all otherwise
-            mStarted = false;
-            if (mListeners != null) {
-                ArrayList<AnimatorListener> tmpListeners =
-                        (ArrayList<AnimatorListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onAnimationEnd(this);
-                }
-            }
-        }
-    }
-
-    @Override
-    public AnimatorSet clone() {
-        final AnimatorSet anim = (AnimatorSet) super.clone();
-        /*
-         * The basic clone() operation copies all items. This doesn't work very well for
-         * 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,
-         * and will populate any appropriate lists, when it is started.
-         */
-        anim.mNeedsSort = true;
-        anim.mTerminated = false;
-        anim.mStarted = false;
-        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 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) {
-            Node nodeClone = node.clone();
-            nodeCloneMap.put(node, nodeClone);
-            anim.mNodes.add(nodeClone);
-            anim.mNodeMap.put(nodeClone.animation, nodeClone);
-            // Clear out the dependencies in the clone; we'll set these up manually later
-            nodeClone.dependencies = null;
-            nodeClone.tmpDependencies = null;
-            nodeClone.nodeDependents = null;
-            nodeClone.nodeDependencies = null;
-            // clear out any listeners that were set up by the AnimatorSet; these will
-            // be set up when the clone's nodes are sorted
-            ArrayList<AnimatorListener> cloneListeners = nodeClone.animation.getListeners();
-            if (cloneListeners != null) {
-                ArrayList<AnimatorListener> listenersToRemove = null;
-                for (AnimatorListener listener : cloneListeners) {
-                    if (listener instanceof AnimatorSetListener) {
-                        if (listenersToRemove == null) {
-                            listenersToRemove = new ArrayList<AnimatorListener>();
-                        }
-                        listenersToRemove.add(listener);
-                    }
-                }
-                if (listenersToRemove != null) {
-                    for (AnimatorListener listener : listenersToRemove) {
-                        cloneListeners.remove(listener);
-                    }
-                }
-            }
-        }
-        // Now that we've cloned all of the nodes, we're ready to walk through their
-        // dependencies, mapping the old dependencies to the new nodes
-        for (Node node : mNodes) {
-            Node nodeClone = nodeCloneMap.get(node);
-            if (node.dependencies != null) {
-                for (Dependency dependency : node.dependencies) {
-                    Node clonedDependencyNode = nodeCloneMap.get(dependency.node);
-                    Dependency cloneDependency = new Dependency(clonedDependencyNode,
-                            dependency.rule);
-                    nodeClone.addDependency(cloneDependency);
-                }
-            }
-        }
-
-        return anim;
-    }
-
-    /**
-     * This class is the mechanism by which animations are started based on events in other
-     * 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 AnimatorListener {
-
-        private AnimatorSet mAnimatorSet;
-
-        // The node upon which the dependency is based.
-        private Node mNode;
-
-        // The Dependency rule (WITH or AFTER) that the listener should wait for on
-        // the node
-        private int mRule;
-
-        public DependencyListener(AnimatorSet animatorSet, Node node, int rule) {
-            this.mAnimatorSet = animatorSet;
-            this.mNode = node;
-            this.mRule = rule;
-        }
-
-        /**
-         * Ignore cancel events for now. We may want to handle this eventually,
-         * to prevent follow-on animations from running when some dependency
-         * animation is canceled.
-         */
-        public void onAnimationCancel(Animator animation) {
-        }
-
-        /**
-         * An end event is received - see if this is an event we are listening for
-         */
-        public void onAnimationEnd(Animator animation) {
-            if (mRule == Dependency.AFTER) {
-                startIfReady(animation);
-            }
-        }
-
-        /**
-         * Ignore repeat events for now
-         */
-        public void onAnimationRepeat(Animator animation) {
-        }
-
-        /**
-         * A start event is received - see if this is an event we are listening for
-         */
-        public void onAnimationStart(Animator animation) {
-            if (mRule == Dependency.WITH) {
-                startIfReady(animation);
-            }
-        }
-
-        /**
-         * Check whether the event received is one that the node was waiting for.
-         * If so, mark it as complete and see whether it's time to start
-         * the animation.
-         * @param dependencyAnimation the animation that sent the event.
-         */
-        private void startIfReady(Animator dependencyAnimation) {
-            if (mAnimatorSet.mTerminated) {
-                // if the parent AnimatorSet was canceled, then don't start any dependent anims
-                return;
-            }
-            Dependency dependencyToRemove = null;
-            int numDependencies = mNode.tmpDependencies.size();
-            for (int i = 0; i < numDependencies; ++i) {
-                Dependency dependency = mNode.tmpDependencies.get(i);
-                if (dependency.rule == mRule &&
-                        dependency.node.animation == dependencyAnimation) {
-                    // rule fired - remove the dependency and listener and check to
-                    // see whether it's time to start the animation
-                    dependencyToRemove = dependency;
-                    dependencyAnimation.removeListener(this);
-                    break;
-                }
-            }
-            mNode.tmpDependencies.remove(dependencyToRemove);
-            if (mNode.tmpDependencies.size() == 0) {
-                // all dependencies satisfied: start the animation
-                mNode.animation.start();
-                mAnimatorSet.mPlayingSet.add(mNode.animation);
-            }
-        }
-
-    }
-
-    private class AnimatorSetListener implements AnimatorListener {
-
-        private AnimatorSet mAnimatorSet;
-
-        AnimatorSetListener(AnimatorSet animatorSet) {
-            mAnimatorSet = animatorSet;
-        }
-
-        public void onAnimationCancel(Animator animation) {
-            if (!mTerminated) {
-                // Listeners are already notified of the AnimatorSet canceling in cancel().
-                // The logic below only kicks in when animations end normally
-                if (mPlayingSet.size() == 0) {
-                    if (mListeners != null) {
-                        int numListeners = mListeners.size();
-                        for (int i = 0; i < numListeners; ++i) {
-                            mListeners.get(i).onAnimationCancel(mAnimatorSet);
-                        }
-                    }
-                }
-            }
-        }
-
-        @SuppressWarnings("unchecked")
-        public void onAnimationEnd(Animator animation) {
-            animation.removeListener(this);
-            mPlayingSet.remove(animation);
-            Node animNode = mAnimatorSet.mNodeMap.get(animation);
-            animNode.done = true;
-            if (!mTerminated) {
-                // Listeners are already notified of the AnimatorSet ending in cancel() or
-                // end(); the logic below only kicks in when animations end normally
-                ArrayList<Node> sortedNodes = mAnimatorSet.mSortedNodes;
-                boolean allDone = true;
-                int numSortedNodes = sortedNodes.size();
-                for (int i = 0; i < numSortedNodes; ++i) {
-                    if (!sortedNodes.get(i).done) {
-                        allDone = false;
-                        break;
-                    }
-                }
-                if (allDone) {
-                    // If this was the last child animation to end, then notify listeners that this
-                    // AnimatorSet has ended
-                    if (mListeners != null) {
-                        ArrayList<AnimatorListener> tmpListeners =
-                                (ArrayList<AnimatorListener>) mListeners.clone();
-                        int numListeners = tmpListeners.size();
-                        for (int i = 0; i < numListeners; ++i) {
-                            tmpListeners.get(i).onAnimationEnd(mAnimatorSet);
-                        }
-                    }
-                    mAnimatorSet.mStarted = false;
-                }
-            }
-        }
-
-        // Nothing to do
-        public void onAnimationRepeat(Animator animation) {
-        }
-
-        // Nothing to do
-        public void onAnimationStart(Animator animation) {
-        }
-
-    }
-
-    /**
-     * This method sorts the current set of nodes, if needed. The sort is a simple
-     * DependencyGraph sort, which goes like this:
-     * - All nodes without dependencies become 'roots'
-     * - while roots list is not null
-     * -   for each root r
-     * -     add r to sorted list
-     * -     remove r as a dependency from any other node
-     * -   any nodes with no dependencies are added to the roots list
-     */
-    private void sortNodes() {
-        if (mNeedsSort) {
-            mSortedNodes.clear();
-            ArrayList<Node> roots = new ArrayList<Node>();
-            int numNodes = mNodes.size();
-            for (int i = 0; i < numNodes; ++i) {
-                Node node = mNodes.get(i);
-                if (node.dependencies == null || node.dependencies.size() == 0) {
-                    roots.add(node);
-                }
-            }
-            ArrayList<Node> tmpRoots = new ArrayList<Node>();
-            while (roots.size() > 0) {
-                int numRoots = roots.size();
-                for (int i = 0; i < numRoots; ++i) {
-                    Node root = roots.get(i);
-                    mSortedNodes.add(root);
-                    if (root.nodeDependents != null) {
-                        int numDependents = root.nodeDependents.size();
-                        for (int j = 0; j < numDependents; ++j) {
-                            Node node = root.nodeDependents.get(j);
-                            node.nodeDependencies.remove(root);
-                            if (node.nodeDependencies.size() == 0) {
-                                tmpRoots.add(node);
-                            }
-                        }
-                    }
-                }
-                roots.clear();
-                roots.addAll(tmpRoots);
-                tmpRoots.clear();
-            }
-            mNeedsSort = false;
-            if (mSortedNodes.size() != mNodes.size()) {
-                throw new IllegalStateException("Circular dependencies cannot exist"
-                        + " in AnimatorSet");
-            }
-        } else {
-            // Doesn't need sorting, but still need to add in the nodeDependencies list
-            // because these get removed as the event listeners fire and the dependencies
-            // are satisfied
-            int numNodes = mNodes.size();
-            for (int i = 0; i < numNodes; ++i) {
-                Node node = mNodes.get(i);
-                if (node.dependencies != null && node.dependencies.size() > 0) {
-                    int numDependencies = node.dependencies.size();
-                    for (int j = 0; j < numDependencies; ++j) {
-                        Dependency dependency = node.dependencies.get(j);
-                        if (node.nodeDependencies == null) {
-                            node.nodeDependencies = new ArrayList<Node>();
-                        }
-                        if (!node.nodeDependencies.contains(dependency.node)) {
-                            node.nodeDependencies.add(dependency.node);
-                        }
-                    }
-                }
-                // nodes are 'done' by default; they become un-done when started, and done
-                // again when ended
-                node.done = false;
-            }
-        }
-    }
-
-    /**
-     * Dependency holds information about the node that some other node is
-     * dependent upon and the nature of that dependency.
-     *
-     */
-    private static class Dependency {
-        static final int WITH = 0; // dependent node must start with this dependency node
-        static final int AFTER = 1; // dependent node must start when this dependency node finishes
-
-        // The node that the other node with this Dependency is dependent upon
-        public Node node;
-
-        // The nature of the dependency (WITH or AFTER)
-        public int rule;
-
-        public Dependency(Node node, int rule) {
-            this.node = node;
-            this.rule = rule;
-        }
-    }
-
-    /**
-     * 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 Animator animation;
-
-        /**
-         *  These are the dependencies that this node's animation has on other
-         *  nodes. For example, if this node's animation should begin with some
-         *  other animation ends, then there will be an item in this node's
-         *  dependencies list for that other animation's node.
-         */
-        public ArrayList<Dependency> dependencies = null;
-
-        /**
-         * tmpDependencies is a runtime detail. We use the dependencies list for sorting.
-         * 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 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;
-
-        /**
-         * nodeDependencies is just a list of the nodes that this Node is dependent upon.
-         * This information is used in sortNodes(), to determine when a node is a root.
-         */
-        public ArrayList<Node> nodeDependencies = null;
-
-        /**
-         * nodeDepdendents is the list of nodes that have this node as a dependency. This
-         * is a utility field used in sortNodes to facilitate removing this node as a
-         * dependency when it is a root node.
-         */
-        public ArrayList<Node> nodeDependents = null;
-
-        /**
-         * Flag indicating whether the animation in this node is finished. This flag
-         * 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;
-
-        /**
-         * Constructs the Node with the animation that it encapsulates. A Node has no
-         * dependencies by default; dependencies are added via the addDependency()
-         * method.
-         *
-         * @param animation The animation that the Node encapsulates.
-         */
-        public Node(Animator animation) {
-            this.animation = animation;
-        }
-
-        /**
-         * Add a dependency to this Node. The dependency includes information about the
-         * node that this node is dependency upon and the nature of the dependency.
-         * @param dependency
-         */
-        public void addDependency(Dependency dependency) {
-            if (dependencies == null) {
-                dependencies = new ArrayList<Dependency>();
-                nodeDependencies = new ArrayList<Node>();
-            }
-            dependencies.add(dependency);
-            if (!nodeDependencies.contains(dependency.node)) {
-                nodeDependencies.add(dependency.node);
-            }
-            Node dependencyNode = dependency.node;
-            if (dependencyNode.nodeDependents == null) {
-                dependencyNode.nodeDependents = new ArrayList<Node>();
-            }
-            dependencyNode.nodeDependents.add(this);
-        }
-
-        @Override
-        public Node clone() {
-            try {
-                Node node = (Node) super.clone();
-                node.animation = (Animator) animation.clone();
-                return node;
-            } catch (CloneNotSupportedException e) {
-               throw new AssertionError();
-            }
-        }
-    }
-
-    /**
-     * The <code>Builder</code> object is a utility class to facilitate adding animations to a
-     * <code>AnimatorSet</code> along with the relationships between the various animations. The
-     * intention of the <code>Builder</code> methods, along with the {@link
-     * 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 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 AnimatorSet#play(Animator)}.</p>
-     * <p/>
-     * <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>
-     *     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(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 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>
-     *   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>
-     *   AnimatorSet s = new AnimatorSet();
-     *   s.play(anim1).before(anim2);
-     *   s.play(anim2).before(anim3);
-     * </pre>
-     * <p/>
-     * <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 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 AnimatorSet and passed into the constructor of Builder.
-         */
-        private Node mCurrentNode;
-
-        /**
-         * 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(Animator anim) {
-            mCurrentNode = mNodeMap.get(anim);
-            if (mCurrentNode == null) {
-                mCurrentNode = new Node(anim);
-                mNodeMap.put(anim, mCurrentNode);
-                mNodes.add(mCurrentNode);
-            }
-        }
-
-        /**
-         * Sets up the given animation to play at the same time as the animation supplied in the
-         * {@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 AnimatorSet#play(Animator)} method starts.
-         */
-        public Builder with(Animator anim) {
-            Node node = mNodeMap.get(anim);
-            if (node == null) {
-                node = new Node(anim);
-                mNodeMap.put(anim, node);
-                mNodes.add(node);
-            }
-            Dependency dependency = new Dependency(mCurrentNode, Dependency.WITH);
-            node.addDependency(dependency);
-            return this;
-        }
-
-        /**
-         * Sets up the given animation to play when the animation supplied in the
-         * {@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 AnimatorSet#play(Animator)} method ends.
-         */
-        public Builder before(Animator anim) {
-            Node node = mNodeMap.get(anim);
-            if (node == null) {
-                node = new Node(anim);
-                mNodeMap.put(anim, node);
-                mNodes.add(node);
-            }
-            Dependency dependency = new Dependency(mCurrentNode, Dependency.AFTER);
-            node.addDependency(dependency);
-            return this;
-        }
-
-        /**
-         * Sets up the given animation to play when the animation supplied in the
-         * {@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 AnimatorSet#play(Animator)} method to play.
-         */
-        public Builder after(Animator anim) {
-            Node node = mNodeMap.get(anim);
-            if (node == null) {
-                node = new Node(anim);
-                mNodeMap.put(anim, node);
-                mNodes.add(node);
-            }
-            Dependency dependency = new Dependency(node, Dependency.AFTER);
-            mCurrentNode.addDependency(dependency);
-            return this;
-        }
-
-        /**
-         * Sets up the animation supplied in the
-         * {@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 Builder after(long delay) {
-            // setup dummy ValueAnimator just to run the clock
-            ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
-            anim.setDuration(delay);
-            after(anim);
-            return this;
-        }
-
-    }
-
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/ArgbEvaluator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-/**
- * This evaluator can be used to perform type interpolation between integer
- * values that represent ARGB colors.
- */
-public class ArgbEvaluator implements TypeEvaluator {
-
-    /**
-     * This function returns the calculated in-between value for a color
-     * given integers that represent the start and end values in the four
-     * bytes of the 32-bit int. Each channel is separately linearly interpolated
-     * and the resulting calculated values are recombined into the return value.
-     *
-     * @param fraction The fraction from the starting to the ending values
-     * @param startValue A 32-bit int value representing colors in the
-     * separate bytes of the parameter
-     * @param endValue A 32-bit int value representing colors in the
-     * separate bytes of the parameter
-     * @return A value that is calculated to be the linearly interpolated
-     * result, derived by separating the start and end values into separate
-     * color channels and interpolating each one separately, recombining the
-     * resulting values in the same way.
-     */
-    public Object evaluate(float fraction, Object startValue, Object endValue) {
-        int startInt = (Integer) startValue;
-        int startA = (startInt >> 24);
-        int startR = (startInt >> 16) & 0xff;
-        int startG = (startInt >> 8) & 0xff;
-        int startB = startInt & 0xff;
-
-        int endInt = (Integer) endValue;
-        int endA = (endInt >> 24);
-        int endR = (endInt >> 16) & 0xff;
-        int endG = (endInt >> 8) & 0xff;
-        int endB = endInt & 0xff;
-
-        return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
-                (int)((startR + (int)(fraction * (endR - startR))) << 16) |
-                (int)((startG + (int)(fraction * (endG - startG))) << 8) |
-                (int)((startB + (int)(fraction * (endB - startB))));
-    }
-}
\ No newline at end of file
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/FloatEvaluator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-/**
- * This evaluator can be used to perform type interpolation between <code>float</code> values.
- */
-public class FloatEvaluator implements TypeEvaluator<Number> {
-
-    /**
-     * This function returns the result of linearly interpolating the start and end values, with
-     * <code>fraction</code> representing the proportion between the start and end values. The
-     * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
-     * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
-     * and <code>t</code> is <code>fraction</code>.
-     *
-     * @param fraction   The fraction from the starting to the ending values
-     * @param startValue The start value; should be of type <code>float</code> or
-     *                   <code>Float</code>
-     * @param endValue   The end value; should be of type <code>float</code> or <code>Float</code>
-     * @return A linear interpolation between the start and end values, given the
-     *         <code>fraction</code> parameter.
-     */
-    public Float evaluate(float fraction, Number startValue, Number endValue) {
-        float startFloat = startValue.floatValue();
-        return startFloat + fraction * (endValue.floatValue() - startFloat);
-    }
-}
\ No newline at end of file
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/FloatKeyframeSet.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-import android.view.animation.Interpolator;
-
-import com.nineoldandroids.animation.Keyframe.FloatKeyframe;
-
-import java.util.ArrayList;
-
-/**
- * This class holds a collection of FloatKeyframe 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.
- *
- * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclass for
- * int, exists to speed up the getValue() method when there is no custom
- * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
- * Object equivalents of these primitive types.</p>
- */
-class FloatKeyframeSet extends KeyframeSet {
-    private float firstValue;
-    private float lastValue;
-    private float deltaValue;
-    private boolean firstTime = true;
-
-    public FloatKeyframeSet(FloatKeyframe... keyframes) {
-        super(keyframes);
-    }
-
-    @Override
-    public Object getValue(float fraction) {
-        return getFloatValue(fraction);
-    }
-
-    @Override
-    public FloatKeyframeSet clone() {
-        ArrayList<Keyframe> keyframes = mKeyframes;
-        int numKeyframes = mKeyframes.size();
-        FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes];
-        for (int i = 0; i < numKeyframes; ++i) {
-            newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone();
-        }
-        FloatKeyframeSet newSet = new FloatKeyframeSet(newKeyframes);
-        return newSet;
-    }
-
-    public float getFloatValue(float fraction) {
-        if (mNumKeyframes == 2) {
-            if (firstTime) {
-                firstTime = false;
-                firstValue = ((FloatKeyframe) mKeyframes.get(0)).getFloatValue();
-                lastValue = ((FloatKeyframe) mKeyframes.get(1)).getFloatValue();
-                deltaValue = lastValue - firstValue;
-            }
-            if (mInterpolator != null) {
-                fraction = mInterpolator.getInterpolation(fraction);
-            }
-            if (mEvaluator == null) {
-                return firstValue + fraction * deltaValue;
-            } else {
-                return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).floatValue();
-            }
-        }
-        if (fraction <= 0f) {
-            final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
-            final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1);
-            float prevValue = prevKeyframe.getFloatValue();
-            float nextValue = nextKeyframe.getFloatValue();
-            float prevFraction = prevKeyframe.getFraction();
-            float nextFraction = nextKeyframe.getFraction();
-            final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator();
-            if (interpolator != null) {
-                fraction = interpolator.getInterpolation(fraction);
-            }
-            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
-            return mEvaluator == null ?
-                    prevValue + intervalFraction * (nextValue - prevValue) :
-                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
-                            floatValue();
-        } else if (fraction >= 1f) {
-            final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2);
-            final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1);
-            float prevValue = prevKeyframe.getFloatValue();
-            float nextValue = nextKeyframe.getFloatValue();
-            float prevFraction = prevKeyframe.getFraction();
-            float nextFraction = nextKeyframe.getFraction();
-            final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator();
-            if (interpolator != null) {
-                fraction = interpolator.getInterpolation(fraction);
-            }
-            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
-            return mEvaluator == null ?
-                    prevValue + intervalFraction * (nextValue - prevValue) :
-                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
-                            floatValue();
-        }
-        FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
-        for (int i = 1; i < mNumKeyframes; ++i) {
-            FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i);
-            if (fraction < nextKeyframe.getFraction()) {
-                final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator();
-                if (interpolator != null) {
-                    fraction = interpolator.getInterpolation(fraction);
-                }
-                float intervalFraction = (fraction - prevKeyframe.getFraction()) /
-                    (nextKeyframe.getFraction() - prevKeyframe.getFraction());
-                float prevValue = prevKeyframe.getFloatValue();
-                float nextValue = nextKeyframe.getFloatValue();
-                return mEvaluator == null ?
-                        prevValue + intervalFraction * (nextValue - prevValue) :
-                        ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
-                            floatValue();
-            }
-            prevKeyframe = nextKeyframe;
-        }
-        // shouldn't get here
-        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
-    }
-
-}
-
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/IntEvaluator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-/**
- * This evaluator can be used to perform type interpolation between <code>int</code> values.
- */
-public class IntEvaluator implements TypeEvaluator<Integer> {
-
-    /**
-     * This function returns the result of linearly interpolating the start and end values, with
-     * <code>fraction</code> representing the proportion between the start and end values. The
-     * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
-     * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
-     * and <code>t</code> is <code>fraction</code>.
-     *
-     * @param fraction   The fraction from the starting to the ending values
-     * @param startValue The start value; should be of type <code>int</code> or
-     *                   <code>Integer</code>
-     * @param endValue   The end value; should be of type <code>int</code> or <code>Integer</code>
-     * @return A linear interpolation between the start and end values, given the
-     *         <code>fraction</code> parameter.
-     */
-    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
-        int startInt = startValue;
-        return (int)(startInt + fraction * (endValue - startInt));
-    }
-}
\ No newline at end of file
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/IntKeyframeSet.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-import android.view.animation.Interpolator;
-
-import com.nineoldandroids.animation.Keyframe.IntKeyframe;
-
-import java.util.ArrayList;
-
-/**
- * This class holds a collection of IntKeyframe 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.
- *
- * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclass for
- * float, exists to speed up the getValue() method when there is no custom
- * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
- * Object equivalents of these primitive types.</p>
- */
-class IntKeyframeSet extends KeyframeSet {
-    private int firstValue;
-    private int lastValue;
-    private int deltaValue;
-    private boolean firstTime = true;
-
-    public IntKeyframeSet(IntKeyframe... keyframes) {
-        super(keyframes);
-    }
-
-    @Override
-    public Object getValue(float fraction) {
-        return getIntValue(fraction);
-    }
-
-    @Override
-    public IntKeyframeSet clone() {
-        ArrayList<Keyframe> keyframes = mKeyframes;
-        int numKeyframes = mKeyframes.size();
-        IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes];
-        for (int i = 0; i < numKeyframes; ++i) {
-            newKeyframes[i] = (IntKeyframe) keyframes.get(i).clone();
-        }
-        IntKeyframeSet newSet = new IntKeyframeSet(newKeyframes);
-        return newSet;
-    }
-
-    public int getIntValue(float fraction) {
-        if (mNumKeyframes == 2) {
-            if (firstTime) {
-                firstTime = false;
-                firstValue = ((IntKeyframe) mKeyframes.get(0)).getIntValue();
-                lastValue = ((IntKeyframe) mKeyframes.get(1)).getIntValue();
-                deltaValue = lastValue - firstValue;
-            }
-            if (mInterpolator != null) {
-                fraction = mInterpolator.getInterpolation(fraction);
-            }
-            if (mEvaluator == null) {
-                return firstValue + (int)(fraction * deltaValue);
-            } else {
-                return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).intValue();
-            }
-        }
-        if (fraction <= 0f) {
-            final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
-            final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(1);
-            int prevValue = prevKeyframe.getIntValue();
-            int nextValue = nextKeyframe.getIntValue();
-            float prevFraction = prevKeyframe.getFraction();
-            float nextFraction = nextKeyframe.getFraction();
-            final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator();
-            if (interpolator != null) {
-                fraction = interpolator.getInterpolation(fraction);
-            }
-            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
-            return mEvaluator == null ?
-                    prevValue + (int)(intervalFraction * (nextValue - prevValue)) :
-                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
-                            intValue();
-        } else if (fraction >= 1f) {
-            final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 2);
-            final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 1);
-            int prevValue = prevKeyframe.getIntValue();
-            int nextValue = nextKeyframe.getIntValue();
-            float prevFraction = prevKeyframe.getFraction();
-            float nextFraction = nextKeyframe.getFraction();
-            final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator();
-            if (interpolator != null) {
-                fraction = interpolator.getInterpolation(fraction);
-            }
-            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
-            return mEvaluator == null ?
-                    prevValue + (int)(intervalFraction * (nextValue - prevValue)) :
-                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue();
-        }
-        IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
-        for (int i = 1; i < mNumKeyframes; ++i) {
-            IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(i);
-            if (fraction < nextKeyframe.getFraction()) {
-                final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator();
-                if (interpolator != null) {
-                    fraction = interpolator.getInterpolation(fraction);
-                }
-                float intervalFraction = (fraction - prevKeyframe.getFraction()) /
-                    (nextKeyframe.getFraction() - prevKeyframe.getFraction());
-                int prevValue = prevKeyframe.getIntValue();
-                int nextValue = nextKeyframe.getIntValue();
-                return mEvaluator == null ?
-                        prevValue + (int)(intervalFraction * (nextValue - prevValue)) :
-                        ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
-                                intValue();
-            }
-            prevKeyframe = nextKeyframe;
-        }
-        // shouldn't get here
-        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue();
-    }
-
-}
-
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/Keyframe.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-import android.view.animation.Interpolator;
-
-/**
- * This class holds a time/value pair for an animation. The Keyframe class is used
- * 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 optional {@link TimeInterpolator}
- * object, which defines the time interpolation over the intervalue preceding the keyframe.
- *
- * <p>The Keyframe class itself is abstract. The type-specific factory methods will return
- * a subclass of Keyframe specific to the type of value being stored. This is done to improve
- * performance when dealing with the most common cases (e.g., <code>float</code> and
- * <code>int</code> values). Other types will fall into a more general Keyframe class that
- * treats its values as Objects. Unless your animation requires dealing with a custom type
- * or a data structure that needs to be animated directly (and evaluated using an implementation
- * of {@link TypeEvaluator}), you should stick to using float and int as animations using those
- * types have lower runtime overhead than other types.</p>
- */
-public abstract class Keyframe implements Cloneable {
-    /**
-     * The time at which mValue will hold true.
-     */
-    float mFraction;
-
-    /**
-     * The type of the value in this Keyframe. This type is determined at construction time,
-     * based on the type of the <code>value</code> object passed into the constructor.
-     */
-    Class mValueType;
-
-    /**
-     * The optional time interpolator for the interval preceding this keyframe. A null interpolator
-     * (the default) results in linear interpolation over the interval.
-     */
-    private /*Time*/Interpolator mInterpolator = null;
-
-    /**
-     * Flag to indicate whether this keyframe has a valid value. This flag is used when an
-     * animation first starts, to populate placeholder keyframes with real values derived
-     * from the target object.
-     */
-    boolean mHasValue = false;
-
-    /**
-     * Constructs a Keyframe object with the given time and value. The time defines the
-     * time, as a proportion of an overall animation's duration, at which the value will hold true
-     * for the animation. The value for the animation between keyframes will be calculated as
-     * an interpolation between the values at those keyframes.
-     *
-     * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
-     * of time elapsed of the overall animation duration.
-     * @param value The value that the object will animate to as the animation time approaches
-     * the time in this keyframe, and the the value animated from as the time passes the time in
-     * this keyframe.
-     */
-    public static Keyframe ofInt(float fraction, int value) {
-        return new IntKeyframe(fraction, value);
-    }
-
-    /**
-     * Constructs a Keyframe object with the given time. The value at this time will be derived
-     * from the target object when the animation first starts (note that this implies that keyframes
-     * with no initial value must be used as part of an {@link ObjectAnimator}).
-     * The time defines the
-     * time, as a proportion of an overall animation's duration, at which the value will hold true
-     * for the animation. The value for the animation between keyframes will be calculated as
-     * an interpolation between the values at those keyframes.
-     *
-     * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
-     * of time elapsed of the overall animation duration.
-     */
-    public static Keyframe ofInt(float fraction) {
-        return new IntKeyframe(fraction);
-    }
-
-    /**
-     * Constructs a Keyframe object with the given time and value. The time defines the
-     * time, as a proportion of an overall animation's duration, at which the value will hold true
-     * for the animation. The value for the animation between keyframes will be calculated as
-     * an interpolation between the values at those keyframes.
-     *
-     * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
-     * of time elapsed of the overall animation duration.
-     * @param value The value that the object will animate to as the animation time approaches
-     * the time in this keyframe, and the the value animated from as the time passes the time in
-     * this keyframe.
-     */
-    public static Keyframe ofFloat(float fraction, float value) {
-        return new FloatKeyframe(fraction, value);
-    }
-
-    /**
-     * Constructs a Keyframe object with the given time. The value at this time will be derived
-     * from the target object when the animation first starts (note that this implies that keyframes
-     * with no initial value must be used as part of an {@link ObjectAnimator}).
-     * The time defines the
-     * time, as a proportion of an overall animation's duration, at which the value will hold true
-     * for the animation. The value for the animation between keyframes will be calculated as
-     * an interpolation between the values at those keyframes.
-     *
-     * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
-     * of time elapsed of the overall animation duration.
-     */
-    public static Keyframe ofFloat(float fraction) {
-        return new FloatKeyframe(fraction);
-    }
-
-    /**
-     * Constructs a Keyframe object with the given time and value. The time defines the
-     * time, as a proportion of an overall animation's duration, at which the value will hold true
-     * for the animation. The value for the animation between keyframes will be calculated as
-     * an interpolation between the values at those keyframes.
-     *
-     * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
-     * of time elapsed of the overall animation duration.
-     * @param value The value that the object will animate to as the animation time approaches
-     * the time in this keyframe, and the the value animated from as the time passes the time in
-     * this keyframe.
-     */
-    public static Keyframe ofObject(float fraction, Object value) {
-        return new ObjectKeyframe(fraction, value);
-    }
-
-    /**
-     * Constructs a Keyframe object with the given time. The value at this time will be derived
-     * from the target object when the animation first starts (note that this implies that keyframes
-     * with no initial value must be used as part of an {@link ObjectAnimator}).
-     * The time defines the
-     * time, as a proportion of an overall animation's duration, at which the value will hold true
-     * for the animation. The value for the animation between keyframes will be calculated as
-     * an interpolation between the values at those keyframes.
-     *
-     * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
-     * of time elapsed of the overall animation duration.
-     */
-    public static Keyframe ofObject(float fraction) {
-        return new ObjectKeyframe(fraction, null);
-    }
-
-    /**
-     * Indicates whether this keyframe has a valid value. This method is called internally when
-     * an {@link ObjectAnimator} first starts; keyframes without values are assigned values at
-     * that time by deriving the value for the property from the target object.
-     *
-     * @return boolean Whether this object has a value assigned.
-     */
-    public boolean hasValue() {
-        return mHasValue;
-    }
-
-    /**
-     * Gets the value for this Keyframe.
-     *
-     * @return The value for this Keyframe.
-     */
-    public abstract Object getValue();
-
-    /**
-     * Sets the value for this Keyframe.
-     *
-     * @param value value for this Keyframe.
-     */
-    public abstract void setValue(Object value);
-
-    /**
-     * Gets the time for this keyframe, as a fraction of the overall animation duration.
-     *
-     * @return The time associated with this keyframe, as a fraction of the overall animation
-     * duration. This should be a value between 0 and 1.
-     */
-    public float getFraction() {
-        return mFraction;
-    }
-
-    /**
-     * Sets the time for this keyframe, as a fraction of the overall animation duration.
-     *
-     * @param fraction time associated with this keyframe, as a fraction of the overall animation
-     * duration. This should be a value between 0 and 1.
-     */
-    public void setFraction(float fraction) {
-        mFraction = fraction;
-    }
-
-    /**
-     * Gets the optional interpolator for this Keyframe. A value of <code>null</code> indicates
-     * that there is no interpolation, which is the same as linear interpolation.
-     *
-     * @return The optional interpolator for this Keyframe.
-     */
-    public /*Time*/Interpolator getInterpolator() {
-        return mInterpolator;
-    }
-
-    /**
-     * Sets the optional interpolator for this Keyframe. A value of <code>null</code> indicates
-     * that there is no interpolation, which is the same as linear interpolation.
-     *
-     * @return The optional interpolator for this Keyframe.
-     */
-    public void setInterpolator(/*Time*/Interpolator interpolator) {
-        mInterpolator = interpolator;
-    }
-
-    /**
-     * 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.
-     *
-     * @return The type of the value stored in the Keyframe.
-     */
-    public Class getType() {
-        return mValueType;
-    }
-
-    @Override
-    public abstract Keyframe clone();
-
-    /**
-     * This internal subclass is used for all types which are not int or float.
-     */
-    static class ObjectKeyframe extends Keyframe {
-
-        /**
-         * The value of the animation at the time mFraction.
-         */
-        Object mValue;
-
-        ObjectKeyframe(float fraction, Object value) {
-            mFraction = fraction;
-            mValue = value;
-            mHasValue = (value != null);
-            mValueType = mHasValue ? value.getClass() : Object.class;
-        }
-
-        public Object getValue() {
-            return mValue;
-        }
-
-        public void setValue(Object value) {
-            mValue = value;
-            mHasValue = (value != null);
-        }
-
-        @Override
-        public ObjectKeyframe clone() {
-            ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mValue);
-            kfClone.setInterpolator(getInterpolator());
-            return kfClone;
-        }
-    }
-
-    /**
-     * Internal subclass used when the keyframe value is of type int.
-     */
-    static class IntKeyframe extends Keyframe {
-
-        /**
-         * The value of the animation at the time mFraction.
-         */
-        int mValue;
-
-        IntKeyframe(float fraction, int value) {
-            mFraction = fraction;
-            mValue = value;
-            mValueType = int.class;
-            mHasValue = true;
-        }
-
-        IntKeyframe(float fraction) {
-            mFraction = fraction;
-            mValueType = int.class;
-        }
-
-        public int getIntValue() {
-            return mValue;
-        }
-
-        public Object getValue() {
-            return mValue;
-        }
-
-        public void setValue(Object value) {
-            if (value != null && value.getClass() == Integer.class) {
-                mValue = ((Integer)value).intValue();
-                mHasValue = true;
-            }
-        }
-
-        @Override
-        public IntKeyframe clone() {
-            IntKeyframe kfClone = new IntKeyframe(getFraction(), mValue);
-            kfClone.setInterpolator(getInterpolator());
-            return kfClone;
-        }
-    }
-
-    /**
-     * Internal subclass used when the keyframe value is of type float.
-     */
-    static class FloatKeyframe extends Keyframe {
-        /**
-         * The value of the animation at the time mFraction.
-         */
-        float mValue;
-
-        FloatKeyframe(float fraction, float value) {
-            mFraction = fraction;
-            mValue = value;
-            mValueType = float.class;
-            mHasValue = true;
-        }
-
-        FloatKeyframe(float fraction) {
-            mFraction = fraction;
-            mValueType = float.class;
-        }
-
-        public float getFloatValue() {
-            return mValue;
-        }
-
-        public Object getValue() {
-            return mValue;
-        }
-
-        public void setValue(Object value) {
-            if (value != null && value.getClass() == Float.class) {
-                mValue = ((Float)value).floatValue();
-                mHasValue = true;
-            }
-        }
-
-        @Override
-        public FloatKeyframe clone() {
-            FloatKeyframe kfClone = new FloatKeyframe(getFraction(), mValue);
-            kfClone.setInterpolator(getInterpolator());
-            return kfClone;
-        }
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/KeyframeSet.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import android.view.animation.Interpolator;
-
-import com.nineoldandroids.animation.Keyframe.FloatKeyframe;
-import com.nineoldandroids.animation.Keyframe.IntKeyframe;
-import com.nineoldandroids.animation.Keyframe.ObjectKeyframe;
-
-/**
- * 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.
- */
-class KeyframeSet {
-
-    int mNumKeyframes;
-
-    Keyframe mFirstKeyframe;
-    Keyframe mLastKeyframe;
-    /*Time*/Interpolator mInterpolator; // only used in the 2-keyframe case
-    ArrayList<Keyframe> mKeyframes; // only used when there are not 2 keyframes
-    TypeEvaluator mEvaluator;
-
-
-    public KeyframeSet(Keyframe... keyframes) {
-        mNumKeyframes = keyframes.length;
-        mKeyframes = new ArrayList<Keyframe>();
-        mKeyframes.addAll(Arrays.asList(keyframes));
-        mFirstKeyframe = mKeyframes.get(0);
-        mLastKeyframe = mKeyframes.get(mNumKeyframes - 1);
-        mInterpolator = mLastKeyframe.getInterpolator();
-    }
-
-    public static KeyframeSet ofInt(int... values) {
-        int numKeyframes = values.length;
-        IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)];
-        if (numKeyframes == 1) {
-            keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f);
-            keyframes[1] = (IntKeyframe) Keyframe.ofInt(1f, values[0]);
-        } else {
-            keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f, values[0]);
-            for (int i = 1; i < numKeyframes; ++i) {
-                keyframes[i] = (IntKeyframe) Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]);
-            }
-        }
-        return new IntKeyframeSet(keyframes);
-    }
-
-    public static KeyframeSet ofFloat(float... values) {
-        int numKeyframes = values.length;
-        FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];
-        if (numKeyframes == 1) {
-            keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);
-            keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);
-        } else {
-            keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);
-            for (int i = 1; i < numKeyframes; ++i) {
-                keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);
-            }
-        }
-        return new FloatKeyframeSet(keyframes);
-    }
-
-    public static KeyframeSet ofKeyframe(Keyframe... keyframes) {
-        // if all keyframes of same primitive type, create the appropriate KeyframeSet
-        int numKeyframes = keyframes.length;
-        boolean hasFloat = false;
-        boolean hasInt = false;
-        boolean hasOther = false;
-        for (int i = 0; i < numKeyframes; ++i) {
-            if (keyframes[i] instanceof FloatKeyframe) {
-                hasFloat = true;
-            } else if (keyframes[i] instanceof IntKeyframe) {
-                hasInt = true;
-            } else {
-                hasOther = true;
-            }
-        }
-        if (hasFloat && !hasInt && !hasOther) {
-            FloatKeyframe floatKeyframes[] = new FloatKeyframe[numKeyframes];
-            for (int i = 0; i < numKeyframes; ++i) {
-                floatKeyframes[i] = (FloatKeyframe) keyframes[i];
-            }
-            return new FloatKeyframeSet(floatKeyframes);
-        } else if (hasInt && !hasFloat && !hasOther) {
-            IntKeyframe intKeyframes[] = new IntKeyframe[numKeyframes];
-            for (int i = 0; i < numKeyframes; ++i) {
-                intKeyframes[i] = (IntKeyframe) keyframes[i];
-            }
-            return new IntKeyframeSet(intKeyframes);
-        } else {
-            return new KeyframeSet(keyframes);
-        }
-    }
-
-    public static KeyframeSet ofObject(Object... values) {
-        int numKeyframes = values.length;
-        ObjectKeyframe keyframes[] = new ObjectKeyframe[Math.max(numKeyframes,2)];
-        if (numKeyframes == 1) {
-            keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f);
-            keyframes[1] = (ObjectKeyframe) Keyframe.ofObject(1f, values[0]);
-        } else {
-            keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f, values[0]);
-            for (int i = 1; i < numKeyframes; ++i) {
-                keyframes[i] = (ObjectKeyframe) Keyframe.ofObject((float) i / (numKeyframes - 1), values[i]);
-            }
-        }
-        return new KeyframeSet(keyframes);
-    }
-
-    /**
-     * Sets the TypeEvaluator to be used when calculating animated values. This object
-     * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet,
-     * both of which assume their own evaluator to speed up calculations with those primitive
-     * types.
-     *
-     * @param evaluator The TypeEvaluator to be used to calculate animated values.
-     */
-    public void setEvaluator(TypeEvaluator evaluator) {
-        mEvaluator = evaluator;
-    }
-
-    @Override
-    public KeyframeSet clone() {
-        ArrayList<Keyframe> keyframes = mKeyframes;
-        int numKeyframes = mKeyframes.size();
-        Keyframe[] newKeyframes = new Keyframe[numKeyframes];
-        for (int i = 0; i < numKeyframes; ++i) {
-            newKeyframes[i] = keyframes.get(i).clone();
-        }
-        KeyframeSet newSet = new KeyframeSet(newKeyframes);
-        return newSet;
-    }
-
-    /**
-     * Gets the animated value, given the elapsed fraction of the animation (interpolated by the
-     * animation's interpolator) and the evaluator used to calculate in-between values. This
-     * function maps the input fraction to the appropriate keyframe interval and a fraction
-     * between them and returns the interpolated value. Note that the input fraction may fall
-     * outside the [0-1] bounds, if the animation's interpolator made that happen (e.g., a
-     * spring interpolation that might send the fraction past 1.0). We handle this situation by
-     * just using the two keyframes at the appropriate end when the value is outside those bounds.
-     *
-     * @param fraction The elapsed fraction of the animation
-     * @return The animated value.
-     */
-    public Object getValue(float fraction) {
-
-        // Special-case optimization for the common case of only two keyframes
-        if (mNumKeyframes == 2) {
-            if (mInterpolator != null) {
-                fraction = mInterpolator.getInterpolation(fraction);
-            }
-            return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(),
-                    mLastKeyframe.getValue());
-        }
-        if (fraction <= 0f) {
-            final Keyframe nextKeyframe = mKeyframes.get(1);
-            final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator();
-            if (interpolator != null) {
-                fraction = interpolator.getInterpolation(fraction);
-            }
-            final float prevFraction = mFirstKeyframe.getFraction();
-            float intervalFraction = (fraction - prevFraction) /
-                (nextKeyframe.getFraction() - prevFraction);
-            return mEvaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(),
-                    nextKeyframe.getValue());
-        } else if (fraction >= 1f) {
-            final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2);
-            final /*Time*/Interpolator interpolator = mLastKeyframe.getInterpolator();
-            if (interpolator != null) {
-                fraction = interpolator.getInterpolation(fraction);
-            }
-            final float prevFraction = prevKeyframe.getFraction();
-            float intervalFraction = (fraction - prevFraction) /
-                (mLastKeyframe.getFraction() - prevFraction);
-            return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
-                    mLastKeyframe.getValue());
-        }
-        Keyframe prevKeyframe = mFirstKeyframe;
-        for (int i = 1; i < mNumKeyframes; ++i) {
-            Keyframe nextKeyframe = mKeyframes.get(i);
-            if (fraction < nextKeyframe.getFraction()) {
-                final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator();
-                if (interpolator != null) {
-                    fraction = interpolator.getInterpolation(fraction);
-                }
-                final float prevFraction = prevKeyframe.getFraction();
-                float intervalFraction = (fraction - prevFraction) /
-                    (nextKeyframe.getFraction() - prevFraction);
-                return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
-                        nextKeyframe.getValue());
-            }
-            prevKeyframe = nextKeyframe;
-        }
-        // shouldn't reach here
-        return mLastKeyframe.getValue();
-    }
-
-    @Override
-    public String toString() {
-        String returnVal = " ";
-        for (int i = 0; i < mNumKeyframes; ++i) {
-            returnVal += mKeyframes.get(i).getValue() + "  ";
-        }
-        return returnVal;
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/ObjectAnimator.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-import android.util.Log;
-import android.view.View;
-
-import com.nineoldandroids.util.Property;
-import com.nineoldandroids.view.animation.AnimatorProxy;
-
-/**
- * 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.
- *
- * @see #setPropertyName(String)
- *
- */
-public final class ObjectAnimator extends ValueAnimator {
-    private static final boolean DBG = false;
-    private static final Map<String, Property> PROXY_PROPERTIES = new HashMap<String, Property>();
-
-    static {
-        PROXY_PROPERTIES.put("alpha", PreHoneycombCompat.ALPHA);
-        PROXY_PROPERTIES.put("pivotX", PreHoneycombCompat.PIVOT_X);
-        PROXY_PROPERTIES.put("pivotY", PreHoneycombCompat.PIVOT_Y);
-        PROXY_PROPERTIES.put("translationX", PreHoneycombCompat.TRANSLATION_X);
-        PROXY_PROPERTIES.put("translationY", PreHoneycombCompat.TRANSLATION_Y);
-        PROXY_PROPERTIES.put("rotation", PreHoneycombCompat.ROTATION);
-        PROXY_PROPERTIES.put("rotationX", PreHoneycombCompat.ROTATION_X);
-        PROXY_PROPERTIES.put("rotationY", PreHoneycombCompat.ROTATION_Y);
-        PROXY_PROPERTIES.put("scaleX", PreHoneycombCompat.SCALE_X);
-        PROXY_PROPERTIES.put("scaleY", PreHoneycombCompat.SCALE_Y);
-        PROXY_PROPERTIES.put("scrollX", PreHoneycombCompat.SCROLL_X);
-        PROXY_PROPERTIES.put("scrollY", PreHoneycombCompat.SCROLL_Y);
-        PROXY_PROPERTIES.put("x", PreHoneycombCompat.X);
-        PROXY_PROPERTIES.put("y", PreHoneycombCompat.Y);
-    }
-
-    // The target object on which the property exists, set in the constructor
-    private Object mTarget;
-
-    private String mPropertyName;
-
-    private Property mProperty;
-
-    /**
-     * Sets the name of the property that will be animated. This name is used to derive
-     * a setter function that will be called to set animated values.
-     * For example, a property name of <code>foo</code> will result
-     * in a call to the function <code>setFoo()</code> on the target object. If either
-     * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will
-     * also be derived and called.
-     *
-     * <p>For best performance of the mechanism that calls the setter function determined by the
-     * name of the property being animated, use <code>float</code> or <code>int</code> typed values,
-     * and make the setter function for those properties have a <code>void</code> return value. This
-     * will cause the code to take an optimized path for these constrained circumstances. Other
-     * property types and return types will work, but will have more overhead in processing
-     * the requests due to normal reflection mechanisms.</p>
-     *
-     * <p>Note that the setter function derived from this property name
-     * must take the same parameter type as the
-     * <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to
-     * the setter function will fail.</p>
-     *
-     * <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>
-     *
-     * @param propertyName The name of the property being animated. Should not be null.
-     */
-    public void setPropertyName(String propertyName) {
-        // mValues could be null if this is being constructed piecemeal. Just record the
-        // propertyName to be used later when setValues() is called if so.
-        if (mValues != null) {
-            PropertyValuesHolder valuesHolder = mValues[0];
-            String oldName = valuesHolder.getPropertyName();
-            valuesHolder.setPropertyName(propertyName);
-            mValuesMap.remove(oldName);
-            mValuesMap.put(propertyName, valuesHolder);
-        }
-        mPropertyName = propertyName;
-        // New property/values/target should cause re-initialization prior to starting
-        mInitialized = false;
-    }
-
-    /**
-     * Sets the property that will be animated. Property objects will take precedence over
-     * properties specified by the {@link #setPropertyName(String)} method. Animations should
-     * be set up to use one or the other, not both.
-     *
-     * @param property The property being animated. Should not be null.
-     */
-    public void setProperty(Property property) {
-        // mValues could be null if this is being constructed piecemeal. Just record the
-        // propertyName to be used later when setValues() is called if so.
-        if (mValues != null) {
-            PropertyValuesHolder valuesHolder = mValues[0];
-            String oldName = valuesHolder.getPropertyName();
-            valuesHolder.setProperty(property);
-            mValuesMap.remove(oldName);
-            mValuesMap.put(mPropertyName, valuesHolder);
-        }
-        if (mProperty != null) {
-            mPropertyName = property.getName();
-        }
-        mProperty = property;
-        // New property/values/target should cause re-initialization prior to starting
-        mInitialized = false;
-    }
-
-    /**
-     * Gets the name of the property that will be animated. This name will be used to derive
-     * a setter function that will be called to set animated values.
-     * For example, a property name of <code>foo</code> will result
-     * in a call to the function <code>setFoo()</code> on the target object. If either
-     * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will
-     * also be derived and called.
-     */
-    public String getPropertyName() {
-        return mPropertyName;
-    }
-
-    /**
-     * Creates a new ObjectAnimator object. This default constructor is primarily for
-     * use internally; the other constructors which take parameters are more generally
-     * useful.
-     */
-    public ObjectAnimator() {
-    }
-
-    /**
-     * Private utility constructor that initializes the target object and name of the
-     * property being animated.
-     *
-     * @param target The object whose property is to be animated. This object should
-     * have a public method on it called <code>setName()</code>, where <code>name</code> is
-     * the value of the <code>propertyName</code> parameter.
-     * @param propertyName The name of the property being animated.
-     */
-    private ObjectAnimator(Object target, String propertyName) {
-        mTarget = target;
-        setPropertyName(propertyName);
-    }
-
-    /**
-     * Private utility constructor that initializes the target object and property being animated.
-     *
-     * @param target The object whose property is to be animated.
-     * @param property The property being animated.
-     */
-    private <T> ObjectAnimator(T target, Property<T, ?> property) {
-        mTarget = target;
-        setProperty(property);
-    }
-
-    /**
-     * Constructs and returns an ObjectAnimator that animates between int values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
-     * and ending values. More than two values imply a starting value, values to animate through
-     * along the way, and an ending value (these values will be distributed evenly across
-     * the duration of the animation).
-     *
-     * @param target The object whose property is to be animated. This object should
-     * have a public method on it called <code>setName()</code>, where <code>name</code> is
-     * the value of the <code>propertyName</code> parameter.
-     * @param propertyName The name of the property being animated.
-     * @param values A set of values that the animation will animate between over time.
-     * @return An ObjectAnimator object that is set up to animate between the given values.
-     */
-    public static ObjectAnimator ofInt(Object target, String propertyName, int... values) {
-        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
-        anim.setIntValues(values);
-        return anim;
-    }
-
-    /**
-     * Constructs and returns an ObjectAnimator that animates between int values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
-     * and ending values. More than two values imply a starting value, values to animate through
-     * along the way, and an ending value (these values will be distributed evenly across
-     * the duration of the animation).
-     *
-     * @param target The object whose property is to be animated.
-     * @param property The property being animated.
-     * @param values A set of values that the animation will animate between over time.
-     * @return An ObjectAnimator object that is set up to animate between the given values.
-     */
-    public static <T> ObjectAnimator ofInt(T target, Property<T, Integer> property, int... values) {
-        ObjectAnimator anim = new ObjectAnimator(target, property);
-        anim.setIntValues(values);
-        return anim;
-    }
-
-    /**
-     * Constructs and returns an ObjectAnimator that animates between float values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
-     * and ending values. More than two values imply a starting value, values to animate through
-     * along the way, and an ending value (these values will be distributed evenly across
-     * the duration of the animation).
-     *
-     * @param target The object whose property is to be animated. This object should
-     * have a public method on it called <code>setName()</code>, where <code>name</code> is
-     * the value of the <code>propertyName</code> parameter.
-     * @param propertyName The name of the property being animated.
-     * @param values A set of values that the animation will animate between over time.
-     * @return An ObjectAnimator object that is set up to animate between the given values.
-     */
-    public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
-        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
-        anim.setFloatValues(values);
-        return anim;
-    }
-
-    /**
-     * Constructs and returns an ObjectAnimator that animates between float values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
-     * and ending values. More than two values imply a starting value, values to animate through
-     * along the way, and an ending value (these values will be distributed evenly across
-     * the duration of the animation).
-     *
-     * @param target The object whose property is to be animated.
-     * @param property The property being animated.
-     * @param values A set of values that the animation will animate between over time.
-     * @return An ObjectAnimator object that is set up to animate between the given values.
-     */
-    public static <T> ObjectAnimator ofFloat(T target, Property<T, Float> property,
-            float... values) {
-        ObjectAnimator anim = new ObjectAnimator(target, property);
-        anim.setFloatValues(values);
-        return anim;
-    }
-
-    /**
-     * Constructs and returns an ObjectAnimator that animates between Object values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
-     * and ending values. More than two values imply a starting value, values to animate through
-     * along the way, and an ending value (these values will be distributed evenly across
-     * the duration of the animation).
-     *
-     * @param target The object whose property is to be animated. This object should
-     * have a public method on it called <code>setName()</code>, where <code>name</code> is
-     * the value of the <code>propertyName</code> parameter.
-     * @param propertyName The name of the property being animated.
-     * @param evaluator A TypeEvaluator that will be called on each animation frame to
-     * provide the necessary interpolation between the Object values to derive the animated
-     * value.
-     * @param values A set of values that the animation will animate between over time.
-     * @return An ObjectAnimator object that is set up to animate between the given values.
-     */
-    public static ObjectAnimator ofObject(Object target, String propertyName,
-            TypeEvaluator evaluator, Object... values) {
-        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
-        anim.setObjectValues(values);
-        anim.setEvaluator(evaluator);
-        return anim;
-    }
-
-    /**
-     * Constructs and returns an ObjectAnimator that animates between Object values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
-     * and ending values. More than two values imply a starting value, values to animate through
-     * along the way, and an ending value (these values will be distributed evenly across
-     * the duration of the animation).
-     *
-     * @param target The object whose property is to be animated.
-     * @param property The property being animated.
-     * @param evaluator A TypeEvaluator that will be called on each animation frame to
-     * provide the necessary interpolation between the Object values to derive the animated
-     * value.
-     * @param values A set of values that the animation will animate between over time.
-     * @return An ObjectAnimator object that is set up to animate between the given values.
-     */
-    public static <T, V> ObjectAnimator ofObject(T target, Property<T, V> property,
-            TypeEvaluator<V> evaluator, V... values) {
-        ObjectAnimator anim = new ObjectAnimator(target, property);
-        anim.setObjectValues(values);
-        anim.setEvaluator(evaluator);
-        return anim;
-    }
-
-    /**
-     * Constructs and returns an ObjectAnimator that animates between the sets of values specified
-     * in <code>PropertyValueHolder</code> objects. This variant should 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.
-     *
-     * @param target The object whose property is to be animated. Depending on how the
-     * PropertyValuesObjects were constructed, the target object should either have the {@link
-     * android.util.Property} objects used to construct the PropertyValuesHolder objects or (if the
-     * PropertyValuesHOlder objects were created with property names) the target object should have
-     * public methods on it called <code>setName()</code>, where <code>name</code> is the name of
-     * the property passed in as the <code>propertyName</code> parameter for each of the
-     * PropertyValuesHolder objects.
-     * @param values A set of PropertyValuesHolder objects whose values will be animated between
-     * over time.
-     * @return An ObjectAnimator object that is set up to animate between the given values.
-     */
-    public static ObjectAnimator ofPropertyValuesHolder(Object target,
-            PropertyValuesHolder... values) {
-        ObjectAnimator anim = new ObjectAnimator();
-        anim.mTarget = target;
-        anim.setValues(values);
-        return anim;
-    }
-
-    @Override
-    public void setIntValues(int... values) {
-        if (mValues == null || mValues.length == 0) {
-            // No values yet - this animator is being constructed piecemeal. Init the values with
-            // whatever the current propertyName is
-            if (mProperty != null) {
-                setValues(PropertyValuesHolder.ofInt(mProperty, values));
-            } else {
-                setValues(PropertyValuesHolder.ofInt(mPropertyName, values));
-            }
-        } else {
-            super.setIntValues(values);
-        }
-    }
-
-    @Override
-    public void setFloatValues(float... values) {
-        if (mValues == null || mValues.length == 0) {
-            // No values yet - this animator is being constructed piecemeal. Init the values with
-            // whatever the current propertyName is
-            if (mProperty != null) {
-                setValues(PropertyValuesHolder.ofFloat(mProperty, values));
-            } else {
-                setValues(PropertyValuesHolder.ofFloat(mPropertyName, values));
-            }
-        } else {
-            super.setFloatValues(values);
-        }
-    }
-
-    @Override
-    public void setObjectValues(Object... values) {
-        if (mValues == null || mValues.length == 0) {
-            // No values yet - this animator is being constructed piecemeal. Init the values with
-            // whatever the current propertyName is
-            if (mProperty != null) {
-                setValues(PropertyValuesHolder.ofObject(mProperty, (TypeEvaluator)null, values));
-            } else {
-                setValues(PropertyValuesHolder.ofObject(mPropertyName, (TypeEvaluator)null, values));
-            }
-        } else {
-            super.setObjectValues(values);
-        }
-    }
-
-    @Override
-    public void start() {
-        if (DBG) {
-            Log.d("ObjectAnimator", "Anim target, duration: " + mTarget + ", " + getDuration());
-            for (int i = 0; i < mValues.length; ++i) {
-                PropertyValuesHolder pvh = mValues[i];
-                ArrayList<Keyframe> keyframes = pvh.mKeyframeSet.mKeyframes;
-                Log.d("ObjectAnimator", "   Values[" + i + "]: " +
-                    pvh.getPropertyName() + ", " + keyframes.get(0).getValue() + ", " +
-                    keyframes.get(pvh.mKeyframeSet.mNumKeyframes - 1).getValue());
-            }
-        }
-        super.start();
-    }
-
-    /**
-     * 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. This includes setting mEvaluator, if the user has not yet
-     * set it up, and the setter/getter methods, if the user did not supply
-     * them.
-     *
-     *  <p>Overriders of this method should call the superclass method to cause
-     *  internal mechanisms to be set up correctly.</p>
-     */
-    @Override
-    void initAnimation() {
-        if (!mInitialized) {
-            // mValueType may change due to setter/getter setup; do this before calling super.init(),
-            // which uses mValueType to set up the default type evaluator.
-            if ((mProperty == null) && AnimatorProxy.NEEDS_PROXY && (mTarget instanceof View) && PROXY_PROPERTIES.containsKey(mPropertyName)) {
-                setProperty(PROXY_PROPERTIES.get(mPropertyName));
-            }
-            int numValues = mValues.length;
-            for (int i = 0; i < numValues; ++i) {
-                mValues[i].setupSetterAndGetter(mTarget);
-            }
-            super.initAnimation();
-        }
-    }
-
-    /**
-     * Sets the length of the animation. The default duration is 300 milliseconds.
-     *
-     * @param duration The length of the animation, in milliseconds.
-     * @return ObjectAnimator The object called with setDuration(). This return
-     * value makes it easier to compose statements together that construct and then set the
-     * duration, as in
-     * <code>ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start()</code>.
-     */
-    @Override
-    public ObjectAnimator setDuration(long duration) {
-        super.setDuration(duration);
-        return this;
-    }
-
-
-    /**
-     * The target object whose property will be animated by this animation
-     *
-     * @return The object being animated
-     */
-    public Object getTarget() {
-        return mTarget;
-    }
-
-    /**
-     * Sets the target object whose property will be animated by this animation
-     *
-     * @param target The object being animated
-     */
-    @Override
-    public void setTarget(Object target) {
-        if (mTarget != target) {
-            final Object oldTarget = mTarget;
-            mTarget = target;
-            if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) {
-                return;
-            }
-            // New target type should cause re-initialization prior to starting
-            mInitialized = false;
-        }
-    }
-
-    @Override
-    public void setupStartValues() {
-        initAnimation();
-        int numValues = mValues.length;
-        for (int i = 0; i < numValues; ++i) {
-            mValues[i].setupStartValue(mTarget);
-        }
-    }
-
-    @Override
-    public void setupEndValues() {
-        initAnimation();
-        int numValues = mValues.length;
-        for (int i = 0; i < numValues; ++i) {
-            mValues[i].setupEndValue(mTarget);
-        }
-    }
-
-    /**
-     * 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.
-     */
-    @Override
-    void animateValue(float fraction) {
-        super.animateValue(fraction);
-        int numValues = mValues.length;
-        for (int i = 0; i < numValues; ++i) {
-            mValues[i].setAnimatedValue(mTarget);
-        }
-    }
-
-    @Override
-    public ObjectAnimator clone() {
-        final ObjectAnimator anim = (ObjectAnimator) super.clone();
-        return anim;
-    }
-
-    @Override
-    public String toString() {
-        String returnVal = "ObjectAnimator@" + Integer.toHexString(hashCode()) + ", target " +
-            mTarget;
-        if (mValues != null) {
-            for (int i = 0; i < mValues.length; ++i) {
-                returnVal += "\n    " + mValues[i].toString();
-            }
-        }
-        return returnVal;
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/PreHoneycombCompat.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package com.nineoldandroids.animation;
-
-import android.view.View;
-import com.nineoldandroids.util.FloatProperty;
-import com.nineoldandroids.util.IntProperty;
-import com.nineoldandroids.util.Property;
-import com.nineoldandroids.view.animation.AnimatorProxy;
-
-final class PreHoneycombCompat {
-    static Property<View, Float> ALPHA = new FloatProperty<View>("alpha") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setAlpha(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getAlpha();
-        }
-    };
-    static Property<View, Float> PIVOT_X = new FloatProperty<View>("pivotX") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setPivotX(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getPivotX();
-        }
-    };
-    static Property<View, Float> PIVOT_Y = new FloatProperty<View>("pivotY") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setPivotY(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getPivotY();
-        }
-    };
-    static Property<View, Float> TRANSLATION_X = new FloatProperty<View>("translationX") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setTranslationX(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getTranslationX();
-        }
-    };
-    static Property<View, Float> TRANSLATION_Y = new FloatProperty<View>("translationY") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setTranslationY(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getTranslationY();
-        }
-    };
-    static Property<View, Float> ROTATION = new FloatProperty<View>("rotation") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setRotation(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getRotation();
-        }
-    };
-    static Property<View, Float> ROTATION_X = new FloatProperty<View>("rotationX") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setRotationX(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getRotationX();
-        }
-    };
-    static Property<View, Float> ROTATION_Y = new FloatProperty<View>("rotationY") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setRotationY(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getRotationY();
-        }
-    };
-    static Property<View, Float> SCALE_X = new FloatProperty<View>("scaleX") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setScaleX(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getScaleX();
-        }
-    };
-    static Property<View, Float> SCALE_Y = new FloatProperty<View>("scaleY") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setScaleY(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getScaleY();
-        }
-    };
-    static Property<View, Integer> SCROLL_X = new IntProperty<View>("scrollX") {
-        @Override
-        public void setValue(View object, int value) {
-            AnimatorProxy.wrap(object).setScrollX(value);
-        }
-
-        @Override
-        public Integer get(View object) {
-            return AnimatorProxy.wrap(object).getScrollX();
-        }
-    };
-    static Property<View, Integer> SCROLL_Y = new IntProperty<View>("scrollY") {
-        @Override
-        public void setValue(View object, int value) {
-            AnimatorProxy.wrap(object).setScrollY(value);
-        }
-
-        @Override
-        public Integer get(View object) {
-            return AnimatorProxy.wrap(object).getScrollY();
-        }
-    };
-    static Property<View, Float> X = new FloatProperty<View>("x") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setX(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getX();
-        }
-    };
-    static Property<View, Float> Y = new FloatProperty<View>("y") {
-        @Override
-        public void setValue(View object, float value) {
-            AnimatorProxy.wrap(object).setY(value);
-        }
-
-        @Override
-        public Float get(View object) {
-            return AnimatorProxy.wrap(object).getY();
-        }
-    };
-
-
-    //No instances
-    private PreHoneycombCompat() {}
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/PropertyValuesHolder.java
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-import android.util.Log;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import com.nineoldandroids.util.FloatProperty;
-import com.nineoldandroids.util.IntProperty;
-import com.nineoldandroids.util.Property;
-
-/**
- * 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 ValueAnimator or ObjectAnimator that operate on several different properties
- * in parallel.
- */
-public class PropertyValuesHolder 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 ObjectAnimator. But this is the name by which
-     * aniamted values are looked up with getAnimatedValue(String) in ValueAnimator.
-     */
-    String mPropertyName;
-
-    /**
-     * @hide
-     */
-    protected Property mProperty;
-
-    /**
-     * The setter function, if needed. ObjectAnimator hands off this functionality to
-     * PropertyValuesHolder, since it holds all of the per-property information. This
-     * property is automatically
-     * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator.
-     */
-    Method mSetter = null;
-
-    /**
-     * The getter function, if needed. ObjectAnimator hands off this functionality to
-     * PropertyValuesHolder, since it holds all of the per-property information. This
-     * property is automatically
-     * 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;
-
-    /**
-     * The type of values supplied. This information is used both in deriving the setter/getter
-     * functions and in deriving the type of TypeEvaluator.
-     */
-    Class mValueType;
-
-    /**
-     * The set of keyframes (time/value pairs) that define this animation.
-     */
-    KeyframeSet mKeyframeSet = null;
-
-
-    // type evaluators for the primitive types handled by this implementation
-    private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
-    private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator();
-
-    // We try several different types when searching for appropriate setter/getter functions.
-    // The caller may have supplied values in a type that does not match the setter/getter
-    // functions (such as the integers 0 and 1 to represent floating point values for alpha).
-    // Also, the use of generics in constructors means that we end up with the Object versions
-    // of primitive types (Float vs. float). But most likely, the setter/getter functions
-    // will take primitive types instead.
-    // So we supply an ordered array of other types to try before giving up.
-    private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class,
-            Double.class, Integer.class};
-    private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class,
-            Float.class, Double.class};
-    private static Class[] DOUBLE_VARIANTS = {double.class, Double.class, float.class, int.class,
-            Float.class, Integer.class};
-
-    // These maps hold all property entries for a particular class. This map
-    // is used to speed up property/setter/getter lookups for a given class/property
-    // combination. No need to use reflection on the combination more than once.
-    private static final HashMap<Class, HashMap<String, Method>> sSetterPropertyMap =
-            new HashMap<Class, HashMap<String, Method>>();
-    private static final HashMap<Class, HashMap<String, Method>> sGetterPropertyMap =
-            new HashMap<Class, HashMap<String, Method>>();
-
-    // This lock is used to ensure that only one thread is accessing the property maps
-    // at a time.
-    final ReentrantReadWriteLock mPropertyMapLock = new ReentrantReadWriteLock();
-
-    // Used to pass single value to varargs parameter in setter invocation
-    final Object[] mTmpValueArray = new Object[1];
-
-    /**
-     * The type evaluator used to calculate the animated values. This evaluator is determined
-     * automatically based on the type of the start/end objects passed into the constructor,
-     * but the system only knows about the primitive types int and float. Any other
-     * type will need to set the evaluator to a custom evaluator for that type.
-     */
-    private TypeEvaluator mEvaluator;
-
-    /**
-     * The value most recently calculated by calculateValue(). This is set during
-     * that function and might be retrieved later either by ValueAnimator.animatedValue() or
-     * by the property-setting logic in ObjectAnimator.animatedValue().
-     */
-    private Object mAnimatedValue;
-
-    /**
-     * Internal utility constructor, used by the factory methods to set the property name.
-     * @param propertyName The name of the property for this holder.
-     */
-    private PropertyValuesHolder(String propertyName) {
-        mPropertyName = propertyName;
-    }
-
-    /**
-     * Internal utility constructor, used by the factory methods to set the property.
-     * @param property The property for this holder.
-     */
-    private PropertyValuesHolder(Property property) {
-        mProperty = property;
-        if (property != null) {
-            mPropertyName = property.getName();
-        }
-    }
-
-    /**
-     * Constructs and returns a PropertyValuesHolder with a given property name and
-     * set of int values.
-     * @param propertyName The name of the property being animated.
-     * @param values The values that the named property will animate between.
-     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
-     */
-    public static PropertyValuesHolder ofInt(String propertyName, int... values) {
-        return new IntPropertyValuesHolder(propertyName, values);
-    }
-
-    /**
-     * Constructs and returns a PropertyValuesHolder with a given property and
-     * set of int values.
-     * @param property The property being animated. Should not be null.
-     * @param values The values that the property will animate between.
-     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
-     */
-    public static PropertyValuesHolder ofInt(Property<?, Integer> property, int... values) {
-        return new IntPropertyValuesHolder(property, values);
-    }
-
-    /**
-     * Constructs and returns a PropertyValuesHolder with a given property name and
-     * set of float values.
-     * @param propertyName The name of the property being animated.
-     * @param values The values that the named property will animate between.
-     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
-     */
-    public static PropertyValuesHolder ofFloat(String propertyName, float... values) {
-        return new FloatPropertyValuesHolder(propertyName, values);
-    }
-
-    /**
-     * Constructs and returns a PropertyValuesHolder with a given property and
-     * set of float values.
-     * @param property The property being animated. Should not be null.
-     * @param values The values that the property will animate between.
-     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
-     */
-    public static PropertyValuesHolder ofFloat(Property<?, Float> property, float... values) {
-        return new FloatPropertyValuesHolder(property, values);
-    }
-
-    /**
-     * Constructs and returns a PropertyValuesHolder with a given property name and
-     * set of Object values. This variant also takes a TypeEvaluator because the system
-     * cannot automatically interpolate between objects of unknown type.
-     *
-     * @param propertyName The name of the property being animated.
-     * @param evaluator A TypeEvaluator that will be called on each animation frame to
-     * provide the necessary interpolation between the Object values to derive the animated
-     * value.
-     * @param values The values that the named property will animate between.
-     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
-     */
-    public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,
-            Object... values) {
-        PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
-        pvh.setObjectValues(values);
-        pvh.setEvaluator(evaluator);
-        return pvh;
-    }
-
-    /**
-     * Constructs and returns a PropertyValuesHolder with a given property and
-     * set of Object values. This variant also takes a TypeEvaluator because the system
-     * cannot automatically interpolate between objects of unknown type.
-     *
-     * @param property The property being animated. Should not be null.
-     * @param evaluator A TypeEvaluator that will be called on each animation frame to
-     * provide the necessary interpolation between the Object values to derive the animated
-     * value.
-     * @param values The values that the property will animate between.
-     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
-     */
-    public static <V> PropertyValuesHolder ofObject(Property property,
-            TypeEvaluator<V> evaluator, V... values) {
-        PropertyValuesHolder pvh = new PropertyValuesHolder(property);
-        pvh.setObjectValues(values);
-        pvh.setEvaluator(evaluator);
-        return pvh;
-    }
-
-    /**
-     * Constructs and returns a PropertyValuesHolder object with the specified property name and set
-     * of values. These values can be of any type, but the type should be consistent so that
-     * an appropriate {@link android.animation.TypeEvaluator} can be found that matches
-     * the common type.
-     * <p>If there is only one value, it is assumed to be the end value of an animation,
-     * and an initial value will be derived, if possible, by calling a getter function
-     * 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 ObjectAnimator}, and with a getter function
-     * derived automatically from <code>propertyName</code>, 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 ObjectAnimator object, or
-     * just a name used to get animated values, such as if this object is used with an
-     * ValueAnimator object.
-     * @param values The set of values to animate between.
-     */
-    public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) {
-        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
-        if (keyframeSet instanceof IntKeyframeSet) {
-            return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet);
-        } else if (keyframeSet instanceof FloatKeyframeSet) {
-            return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet);
-        }
-        else {
-            PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
-            pvh.mKeyframeSet = keyframeSet;
-            pvh.mValueType = ((Keyframe)values[0]).getType();
-            return pvh;
-        }
-    }
-
-    /**
-     * Constructs and returns a PropertyValuesHolder object with the specified property and set
-     * of values. These values can be of any type, but the type should be consistent so that
-     * an appropriate {@link android.animation.TypeEvaluator} can be found that matches
-     * the common type.
-     * <p>If there is only one value, it is assumed to be the end value of an animation,
-     * and an initial value will be derived, if possible, by calling the property's
-     * {@link android.util.Property#get(Object)} function.
-     * 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 with
-     * {@link ObjectAnimator}, since otherwise PropertyValuesHolder has
-     * no way of determining what the value should be.
-     * @param property The property associated with this set of values. Should not be null.
-     * @param values The set of values to animate between.
-     */
-    public static PropertyValuesHolder ofKeyframe(Property property, Keyframe... values) {
-        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
-        if (keyframeSet instanceof IntKeyframeSet) {
-            return new IntPropertyValuesHolder(property, (IntKeyframeSet) keyframeSet);
-        } else if (keyframeSet instanceof FloatKeyframeSet) {
-            return new FloatPropertyValuesHolder(property, (FloatKeyframeSet) keyframeSet);
-        }
-        else {
-            PropertyValuesHolder pvh = new PropertyValuesHolder(property);
-            pvh.mKeyframeSet = keyframeSet;
-            pvh.mValueType = ((Keyframe)values[0]).getType();
-            return pvh;
-        }
-    }
-
-    /**
-     * Set the animated values for this object to this set of ints.
-     * If there is only one value, it is assumed to be the end value of an animation,
-     * and an initial value will be derived, if possible, by calling a getter function
-     * 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 ObjectAnimator}, and with a getter function
-     * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has
-     * no way of determining what the value should be.
-     *
-     * @param values One or more values that the animation will animate between.
-     */
-    public void setIntValues(int... values) {
-        mValueType = int.class;
-        mKeyframeSet = KeyframeSet.ofInt(values);
-    }
-
-    /**
-     * Set the animated values for this object to this set of floats.
-     * If there is only one value, it is assumed to be the end value of an animation,
-     * and an initial value will be derived, if possible, by calling a getter function
-     * 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 ObjectAnimator}, and with a getter function
-     * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has
-     * no way of determining what the value should be.
-     *
-     * @param values One or more values that the animation will animate between.
-     */
-    public void setFloatValues(float... values) {
-        mValueType = float.class;
-        mKeyframeSet = KeyframeSet.ofFloat(values);
-    }
-
-    /**
-     * Set the animated values for this object to this set of Keyframes.
-     *
-     * @param values One or more values that the animation will animate between.
-     */
-    public void setKeyframes(Keyframe... values) {
-        int numKeyframes = values.length;
-        Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
-        mValueType = ((Keyframe)values[0]).getType();
-        for (int i = 0; i < numKeyframes; ++i) {
-            keyframes[i] = (Keyframe)values[i];
-        }
-        mKeyframeSet = new KeyframeSet(keyframes);
-    }
-
-    /**
-     * Set the animated values for this object to this set of Objects.
-     * If there is only one value, it is assumed to be the end value of an animation,
-     * and an initial value will be derived, if possible, by calling a getter function
-     * 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 ObjectAnimator}, and with a getter function
-     * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has
-     * no way of determining what the value should be.
-     *
-     * @param values One or more values that the animation will animate between.
-     */
-    public void setObjectValues(Object... values) {
-        mValueType = values[0].getClass();
-        mKeyframeSet = KeyframeSet.ofObject(values);
-    }
-
-    /**
-     * Determine the setter or getter function using the JavaBeans convention of setFoo or
-     * getFoo for a property named 'foo'. This function figures out what the name of the
-     * function should be and uses reflection to find the Method with that name on the
-     * target object.
-     *
-     * @param targetClass The class to search for the method
-     * @param prefix "set" or "get", depending on whether we need a setter or getter.
-     * @param valueType The type of the parameter (in the case of a setter). This type
-     * is derived from the values set on this PropertyValuesHolder. This type is used as
-     * a first guess at the parameter type, but we check for methods with several different
-     * types to avoid problems with slight mis-matches between supplied values and actual
-     * value types used on the setter.
-     * @return Method the method associated with mPropertyName.
-     */
-    private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) {
-        // TODO: faster implementation...
-        Method returnVal = null;
-        String methodName = getMethodName(prefix, mPropertyName);
-        Class args[] = null;
-        if (valueType == null) {
-            try {
-                returnVal = targetClass.getMethod(methodName, args);
-            } catch (NoSuchMethodException e) {
-                /* The native implementation uses JNI to do reflection, which allows access to private methods.
-                 * getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
-                 */
-                try {
-                    returnVal = targetClass.getDeclaredMethod(methodName, args);
-                    returnVal.setAccessible(true);
-                } catch (NoSuchMethodException e2) {
-                    Log.e("PropertyValuesHolder",
-                            "Couldn't find no-arg method for property " + mPropertyName + ": " + e);
-                }
-            }
-        } else {
-            args = new Class[1];
-            Class typeVariants[];
-            if (mValueType.equals(Float.class)) {
-                typeVariants = FLOAT_VARIANTS;
-            } else if (mValueType.equals(Integer.class)) {
-                typeVariants = INTEGER_VARIANTS;
-            } else if (mValueType.equals(Double.class)) {
-                typeVariants = DOUBLE_VARIANTS;
-            } else {
-                typeVariants = new Class[1];
-                typeVariants[0] = mValueType;
-            }
-            for (Class typeVariant : typeVariants) {
-                args[0] = typeVariant;
-                try {
-                    returnVal = targetClass.getMethod(methodName, args);
-                    // change the value type to suit
-                    mValueType = typeVariant;
-                    return returnVal;
-                } catch (NoSuchMethodException e) {
-                    /* The native implementation uses JNI to do reflection, which allows access to private methods.
-                     * getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
-                     */
-                    try {
-                        returnVal = targetClass.getDeclaredMethod(methodName, args);
-                        returnVal.setAccessible(true);
-                        // change the value type to suit
-                        mValueType = typeVariant;
-                        return returnVal;
-                    } catch (NoSuchMethodException e2) {
-                        // Swallow the error and keep trying other variants
-                    }
-                }
-            }
-            // If we got here, then no appropriate function was found
-            Log.e("PropertyValuesHolder",
-                    "Couldn't find setter/getter for property " + mPropertyName +
-                            " with value type "+ mValueType);
-        }
-
-        return returnVal;
-    }
-
-
-    /**
-     * Returns the setter or getter requested. This utility function checks whether the
-     * requested method exists in the propertyMapMap cache. If not, it calls another
-     * utility function to request the Method from the targetClass directly.
-     * @param targetClass The Class on which the requested method should exist.
-     * @param propertyMapMap The cache of setters/getters derived so far.
-     * @param prefix "set" or "get", for the setter or getter.
-     * @param valueType The type of parameter passed into the method (null for getter).
-     * @return Method the method associated with mPropertyName.
-     */
-    private Method setupSetterOrGetter(Class targetClass,
-            HashMap<Class, HashMap<String, Method>> propertyMapMap,
-            String prefix, Class valueType) {
-        Method setterOrGetter = null;
-        try {
-            // Have to lock property map prior to reading it, to guard against
-            // another thread putting something in there after we've checked it
-            // but before we've added an entry to it
-            mPropertyMapLock.writeLock().lock();
-            HashMap<String, Method> propertyMap = propertyMapMap.get(targetClass);
-            if (propertyMap != null) {
-                setterOrGetter = propertyMap.get(mPropertyName);
-            }
-            if (setterOrGetter == null) {
-                setterOrGetter = getPropertyFunction(targetClass, prefix, valueType);
-                if (propertyMap == null) {
-                    propertyMap = new HashMap<String, Method>();
-                    propertyMapMap.put(targetClass, propertyMap);
-                }
-                propertyMap.put(mPropertyName, setterOrGetter);
-            }
-        } finally {
-            mPropertyMapLock.writeLock().unlock();
-        }
-        return setterOrGetter;
-    }
-
-    /**
-     * Utility function to get the setter from targetClass
-     * @param targetClass The Class on which the requested method should exist.
-     */
-    void setupSetter(Class targetClass) {
-        mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType);
-    }
-
-    /**
-     * Utility function to get the getter from targetClass
-     */
-    private void setupGetter(Class targetClass) {
-        mGetter = setupSetterOrGetter(targetClass, sGetterPropertyMap, "get", null);
-    }
-
-    /**
-     * 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
-     * supplied values was null. If there is a null value, then the getter (supplied or derived)
-     * will be called to set those null values to the current value of the property
-     * on the target object.
-     * @param target The object on which the setter (and possibly getter) exist.
-     */
-    void setupSetterAndGetter(Object target) {
-        if (mProperty != null) {
-            // check to make sure that mProperty is on the class of target
-            try {
-                Object testValue = mProperty.get(target);
-                for (Keyframe kf : mKeyframeSet.mKeyframes) {
-                    if (!kf.hasValue()) {
-                        kf.setValue(mProperty.get(target));
-                    }
-                }
-                return;
-            } catch (ClassCastException e) {
-                Log.e("PropertyValuesHolder","No such property (" + mProperty.getName() +
-                        ") on target object " + target + ". Trying reflection instead");
-                mProperty = null;
-            }
-        }
-        Class targetClass = target.getClass();
-        if (mSetter == null) {
-            setupSetter(targetClass);
-        }
-        for (Keyframe kf : mKeyframeSet.mKeyframes) {
-            if (!kf.hasValue()) {
-                if (mGetter == null) {
-                    setupGetter(targetClass);
-                }
-                try {
-                    kf.setValue(mGetter.invoke(target));
-                } catch (InvocationTargetException e) {
-                    Log.e("PropertyValuesHolder", e.toString());
-                } catch (IllegalAccessException e) {
-                    Log.e("PropertyValuesHolder", e.toString());
-                }
-            }
-        }
-    }
-
-    /**
-     * Utility function to set the value stored in a particular Keyframe. The value used is
-     * whatever the value is for the property name specified in the keyframe on the target object.
-     *
-     * @param target The target object from which the current value should be extracted.
-     * @param kf The keyframe which holds the property name and value.
-     */
-    private void setupValue(Object target, Keyframe kf) {
-        if (mProperty != null) {
-            kf.setValue(mProperty.get(target));
-        }
-        try {
-            if (mGetter == null) {
-                Class targetClass = target.getClass();
-                setupGetter(targetClass);
-            }
-            kf.setValue(mGetter.invoke(target));
-        } catch (InvocationTargetException e) {
-            Log.e("PropertyValuesHolder", e.toString());
-        } catch (IllegalAccessException e) {
-            Log.e("PropertyValuesHolder", e.toString());
-        }
-    }
-
-    /**
-     * 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.
-     *
-     * @param target The object which holds the start values that should be set.
-     */
-    void setupStartValue(Object target) {
-        setupValue(target, mKeyframeSet.mKeyframes.get(0));
-    }
-
-    /**
-     * 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.
-     *
-     * @param target The object which holds the start values that should be set.
-     */
-    void setupEndValue(Object target) {
-        setupValue(target, mKeyframeSet.mKeyframes.get(mKeyframeSet.mKeyframes.size() - 1));
-    }
-
-    @Override
-    public PropertyValuesHolder clone() {
-        try {
-            PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone();
-            newPVH.mPropertyName = mPropertyName;
-            newPVH.mProperty = mProperty;
-            newPVH.mKeyframeSet = mKeyframeSet.clone();
-            newPVH.mEvaluator = mEvaluator;
-            return newPVH;
-        } catch (CloneNotSupportedException e) {
-            // won't reach here
-            return null;
-        }
-    }
-
-    /**
-     * 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 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
-     */
-    void setAnimatedValue(Object target) {
-        if (mProperty != null) {
-            mProperty.set(target, getAnimatedValue());
-        }
-        if (mSetter != null) {
-            try {
-                mTmpValueArray[0] = getAnimatedValue();
-                mSetter.invoke(target, mTmpValueArray);
-            } catch (InvocationTargetException e) {
-                Log.e("PropertyValuesHolder", e.toString());
-            } catch (IllegalAccessException e) {
-                Log.e("PropertyValuesHolder", e.toString());
-            }
-        }
-    }
-
-    /**
-     * Internal function, called by ValueAnimator, to set up the TypeEvaluator that will be used
-     * to calculate animated values.
-     */
-    void init() {
-        if (mEvaluator == null) {
-            // We already handle int and float automatically, but not their Object
-            // equivalents
-            mEvaluator = (mValueType == Integer.class) ? sIntEvaluator :
-                    (mValueType == Float.class) ? sFloatEvaluator :
-                    null;
-        }
-        if (mEvaluator != null) {
-            // KeyframeSet knows how to evaluate the common types - only give it a custom
-            // evaluator if one has been set on this class
-            mKeyframeSet.setEvaluator(mEvaluator);
-        }
-    }
-
-    /**
-     * The TypeEvaluator will the automatically determined based on the type of values
-     * supplied to PropertyValuesHolder. The evaluator can be manually set, however, if so
-     * desired. This may be important in cases where either the type of the values supplied
-     * do not match the way that they should be interpolated between, or if the values
-     * are of a custom type or one not currently understood by the animation system. Currently,
-     * only values of type float and int (and their Object equivalents: Float
-     * and Integer) are  correctly interpolated; all other types require setting a TypeEvaluator.
-     * @param evaluator
-     */
-    public void setEvaluator(TypeEvaluator evaluator) {
-        mEvaluator = evaluator;
-        mKeyframeSet.setEvaluator(evaluator);
-    }
-
-    /**
-     * Function used to calculate the value according to the evaluator set up for
-     * this PropertyValuesHolder object. This function is called by ValueAnimator.animateValue().
-     *
-     * @param fraction The elapsed, interpolated fraction of the animation.
-     */
-    void calculateValue(float fraction) {
-        mAnimatedValue = mKeyframeSet.getValue(fraction);
-    }
-
-    /**
-     * Sets the name of the property that will be animated. This name is used to derive
-     * a setter function that will be called to set animated values.
-     * For example, a property name of <code>foo</code> will result
-     * in a call to the function <code>setFoo()</code> on the target object. If either
-     * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will
-     * also be derived and called.
-     *
-     * <p>Note that the setter function derived from this property name
-     * must take the same parameter type as the
-     * <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to
-     * the setter function will fail.</p>
-     *
-     * @param propertyName The name of the property being animated.
-     */
-    public void setPropertyName(String propertyName) {
-        mPropertyName = propertyName;
-    }
-
-    /**
-     * Sets the property that will be animated.
-     *
-     * <p>Note that if this PropertyValuesHolder object is used with ObjectAnimator, the property
-     * must exist on the target object specified in that ObjectAnimator.</p>
-     *
-     * @param property The property being animated.
-     */
-    public void setProperty(Property property) {
-        mProperty = property;
-    }
-
-    /**
-     * Gets the name of the property that will be animated. This name will be used to derive
-     * a setter function that will be called to set animated values.
-     * For example, a property name of <code>foo</code> will result
-     * in a call to the function <code>setFoo()</code> on the target object. If either
-     * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will
-     * also be derived and called.
-     */
-    public String getPropertyName() {
-        return mPropertyName;
-    }
-
-    /**
-     * Internal function, called by ValueAnimator and ObjectAnimator, to retrieve the value
-     * most recently calculated in calculateValue().
-     * @return
-     */
-    Object getAnimatedValue() {
-        return mAnimatedValue;
-    }
-
-    @Override
-    public String toString() {
-        return mPropertyName + ": " + mKeyframeSet.toString();
-    }
-
-    /**
-     * Utility method to derive a setter/getter method name from a property name, where the
-     * prefix is typically "set" or "get" and the first letter of the property name is
-     * capitalized.
-     *
-     * @param prefix The precursor to the method name, before the property name begins, typically
-     * "set" or "get".
-     * @param propertyName The name of the property that represents the bulk of the method name
-     * after the prefix. The first letter of this word will be capitalized in the resulting
-     * method name.
-     * @return String the property name converted to a method name according to the conventions
-     * specified above.
-     */
-    static String getMethodName(String prefix, String propertyName) {
-        if (propertyName == null || propertyName.length() == 0) {
-            // shouldn't get here
-            return prefix;
-        }
-        char firstLetter = Character.toUpperCase(propertyName.charAt(0));
-        String theRest = propertyName.substring(1);
-        return prefix + firstLetter + theRest;
-    }
-
-    static class IntPropertyValuesHolder extends PropertyValuesHolder {
-
-        // Cache JNI functions to avoid looking them up twice
-        //private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap =
-        //        new HashMap<Class, HashMap<String, Integer>>();
-        //int mJniSetter;
-        private IntProperty mIntProperty;
-
-        IntKeyframeSet mIntKeyframeSet;
-        int mIntAnimatedValue;
-
-        public IntPropertyValuesHolder(String propertyName, IntKeyframeSet keyframeSet) {
-            super(propertyName);
-            mValueType = int.class;
-            mKeyframeSet = keyframeSet;
-            mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
-        }
-
-        public IntPropertyValuesHolder(Property property, IntKeyframeSet keyframeSet) {
-            super(property);
-            mValueType = int.class;
-            mKeyframeSet = keyframeSet;
-            mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
-            if (property instanceof  IntProperty) {
-                mIntProperty = (IntProperty) mProperty;
-            }
-        }
-
-        public IntPropertyValuesHolder(String propertyName, int... values) {
-            super(propertyName);
-            setIntValues(values);
-        }
-
-        public IntPropertyValuesHolder(Property property, int... values) {
-            super(property);
-            setIntValues(values);
-            if (property instanceof  IntProperty) {
-                mIntProperty = (IntProperty) mProperty;
-            }
-        }
-
-        @Override
-        public void setIntValues(int... values) {
-            super.setIntValues(values);
-            mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
-        }
-
-        @Override
-        void calculateValue(float fraction) {
-            mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction);
-        }
-
-        @Override
-        Object getAnimatedValue() {
-            return mIntAnimatedValue;
-        }
-
-        @Override
-        public IntPropertyValuesHolder clone() {
-            IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone();
-            newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet;
-            return newPVH;
-        }
-
-        /**
-         * 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 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
-         */
-        @Override
-        void setAnimatedValue(Object target) {
-            if (mIntProperty != null) {
-                mIntProperty.setValue(target, mIntAnimatedValue);
-                return;
-            }
-            if (mProperty != null) {
-                mProperty.set(target, mIntAnimatedValue);
-                return;
-            }
-            //if (mJniSetter != 0) {
-            //    nCallIntMethod(target, mJniSetter, mIntAnimatedValue);
-            //    return;
-            //}
-            if (mSetter != null) {
-                try {
-                    mTmpValueArray[0] = mIntAnimatedValue;
-                    mSetter.invoke(target, mTmpValueArray);
-                } catch (InvocationTargetException e) {
-                    Log.e("PropertyValuesHolder", e.toString());
-                } catch (IllegalAccessException e) {
-                    Log.e("PropertyValuesHolder", e.toString());
-                }
-            }
-        }
-
-        @Override
-        void setupSetter(Class targetClass) {
-            if (mProperty != null) {
-                return;
-            }
-            // Check new static hashmap<propName, int> for setter method
-            //try {
-            //    mPropertyMapLock.writeLock().lock();
-            //    HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass);
-            //    if (propertyMap != null) {
-            //        Integer mJniSetterInteger = propertyMap.get(mPropertyName);
-            //        if (mJniSetterInteger != null) {
-            //            mJniSetter = mJniSetterInteger;
-            //        }
-            //    }
-            //    if (mJniSetter == 0) {
-            //        String methodName = getMethodName("set", mPropertyName);
-            //        mJniSetter = nGetIntMethod(targetClass, methodName);
-            //        if (mJniSetter != 0) {
-            //            if (propertyMap == null) {
-            //                propertyMap = new HashMap<String, Integer>();
-            //                sJNISetterPropertyMap.put(targetClass, propertyMap);
-            //            }
-            //            propertyMap.put(mPropertyName, mJniSetter);
-            //        }
-            //    }
-            //} catch (NoSuchMethodError e) {
-            //    Log.d("PropertyValuesHolder",
-            //            "Can't find native method using JNI, use reflection" + e);
-            //} finally {
-            //    mPropertyMapLock.writeLock().unlock();
-            //}
-            //if (mJniSetter == 0) {
-                // Couldn't find method through fast JNI approach - just use reflection
-                super.setupSetter(targetClass);
-            //}
-        }
-    }
-
-    static class FloatPropertyValuesHolder extends PropertyValuesHolder {
-
-        // Cache JNI functions to avoid looking them up twice
-        //private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap =
-        //        new HashMap<Class, HashMap<String, Integer>>();
-        //int mJniSetter;
-        private FloatProperty mFloatProperty;
-
-        FloatKeyframeSet mFloatKeyframeSet;
-        float mFloatAnimatedValue;
-
-        public FloatPropertyValuesHolder(String propertyName, FloatKeyframeSet keyframeSet) {
-            super(propertyName);
-            mValueType = float.class;
-            mKeyframeSet = keyframeSet;
-            mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
-        }
-
-        public FloatPropertyValuesHolder(Property property, FloatKeyframeSet keyframeSet) {
-            super(property);
-            mValueType = float.class;
-            mKeyframeSet = keyframeSet;
-            mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
-            if (property instanceof FloatProperty) {
-                mFloatProperty = (FloatProperty) mProperty;
-            }
-        }
-
-        public FloatPropertyValuesHolder(String propertyName, float... values) {
-            super(propertyName);
-            setFloatValues(values);
-        }
-
-        public FloatPropertyValuesHolder(Property property, float... values) {
-            super(property);
-            setFloatValues(values);
-            if (property instanceof  FloatProperty) {
-                mFloatProperty = (FloatProperty) mProperty;
-            }
-        }
-
-        @Override
-        public void setFloatValues(float... values) {
-            super.setFloatValues(values);
-            mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
-        }
-
-        @Override
-        void calculateValue(float fraction) {
-            mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction);
-        }
-
-        @Override
-        Object getAnimatedValue() {
-            return mFloatAnimatedValue;
-        }
-
-        @Override
-        public FloatPropertyValuesHolder clone() {
-            FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone();
-            newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet;
-            return newPVH;
-        }
-
-        /**
-         * 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 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
-         */
-        @Override
-        void setAnimatedValue(Object target) {
-            if (mFloatProperty != null) {
-                mFloatProperty.setValue(target, mFloatAnimatedValue);
-                return;
-            }
-            if (mProperty != null) {
-                mProperty.set(target, mFloatAnimatedValue);
-                return;
-            }
-            //if (mJniSetter != 0) {
-            //    nCallFloatMethod(target, mJniSetter, mFloatAnimatedValue);
-            //    return;
-            //}
-            if (mSetter != null) {
-                try {
-                    mTmpValueArray[0] = mFloatAnimatedValue;
-                    mSetter.invoke(target, mTmpValueArray);
-                } catch (InvocationTargetException e) {
-                    Log.e("PropertyValuesHolder", e.toString());
-                } catch (IllegalAccessException e) {
-                    Log.e("PropertyValuesHolder", e.toString());
-                }
-            }
-        }
-
-        @Override
-        void setupSetter(Class targetClass) {
-            if (mProperty != null) {
-                return;
-            }
-            // Check new static hashmap<propName, int> for setter method
-            //try {
-            //    mPropertyMapLock.writeLock().lock();
-            //    HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass);
-            //    if (propertyMap != null) {
-            //        Integer mJniSetterInteger = propertyMap.get(mPropertyName);
-            //        if (mJniSetterInteger != null) {
-            //            mJniSetter = mJniSetterInteger;
-            //        }
-            //    }
-            //    if (mJniSetter == 0) {
-            //        String methodName = getMethodName("set", mPropertyName);
-            //        mJniSetter = nGetFloatMethod(targetClass, methodName);
-            //        if (mJniSetter != 0) {
-            //            if (propertyMap == null) {
-            //                propertyMap = new HashMap<String, Integer>();
-            //                sJNISetterPropertyMap.put(targetClass, propertyMap);
-            //            }
-            //            propertyMap.put(mPropertyName, mJniSetter);
-            //        }
-            //    }
-            //} catch (NoSuchMethodError e) {
-            //    Log.d("PropertyValuesHolder",
-            //            "Can't find native method using JNI, use reflection" + e);
-            //} finally {
-            //    mPropertyMapLock.writeLock().unlock();
-            //}
-            //if (mJniSetter == 0) {
-                // Couldn't find method through fast JNI approach - just use reflection
-                super.setupSetter(targetClass);
-            //}
-        }
-
-    }
-
-    //native static private int nGetIntMethod(Class targetClass, String methodName);
-    //native static private int nGetFloatMethod(Class targetClass, String methodName);
-    //native static private void nCallIntMethod(Object target, int methodID, int arg);
-    //native static private void nCallFloatMethod(Object target, int methodID, float arg);
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/TimeAnimator.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.nineoldandroids.animation;
-
-/**
- * This class provides a simple callback mechanism to listeners that is synchronized with other
- * animators in the system. There is no duration, interpolation, or object value-setting
- * with this Animator. Instead, it is simply started and proceeds to send out events on every
- * animation frame to its TimeListener (if set), with information about this animator,
- * the total elapsed time, and the time since the last animation frame.
- *
- * @hide
- */
-public class TimeAnimator extends ValueAnimator {
-
-    private TimeListener mListener;
-    private long mPreviousTime = -1;
-
-    @Override
-    boolean animationFrame(long currentTime) {
-        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;
-            }
-        }
-        if (mListener != null) {
-            long totalTime = currentTime - mStartTime;
-            long deltaTime = (mPreviousTime < 0) ? 0 : (currentTime - mPreviousTime);
-            mPreviousTime = currentTime;
-            mListener.onTimeUpdate(this, totalTime, deltaTime);
-        }
-        return false;
-    }
-
-    /**
-     * Sets a listener that is sent update events throughout the life of
-     * an animation.
-     *
-     * @param listener the listener to be set.
-     */
-    public void setTimeListener(TimeListener listener) {
-        mListener = listener;
-    }
-
-    @Override
-    void animateValue(float fraction) {
-        // Noop
-    }
-
-    @Override
-    void initAnimation() {
-        // noop
-    }
-
-    /**
-     * Implementors of this interface can set themselves as update listeners
-     * to a <code>TimeAnimator</code> instance to receive callbacks on every animation
-     * frame to receive the total time since the animator started and the delta time
-     * since the last frame. The first time the listener is called, totalTime and
-     * deltaTime should both be zero.
-     *
-     * @hide
-     */
-    public static interface TimeListener {
-        /**
-         * <p>Notifies listeners of the occurrence of another frame of the animation,
-         * along with information about the elapsed time.</p>
-         *
-         * @param animation The animator sending out the notification.
-         * @param totalTime The
-         */
-        void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime);
-
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/TypeEvaluator.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-/**
- * 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 ValueAnimator#setEvaluator(TypeEvaluator)
- */
-public interface TypeEvaluator<T> {
-
-    /**
-     * This function returns the result of linearly interpolating the start and end values, with
-     * <code>fraction</code> representing the proportion between the start and end values. The
-     * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
-     * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
-     * and <code>t</code> is <code>fraction</code>.
-     *
-     * @param fraction   The fraction from the starting to the ending values
-     * @param startValue The start value.
-     * @param endValue   The end value.
-     * @return A linear interpolation between the start and end values, given the
-     *         <code>fraction</code> parameter.
-     */
-    public T evaluate(float fraction, T startValue, T endValue);
-
-}
\ No newline at end of file
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/animation/ValueAnimator.java
+++ /dev/null
@@ -1,1264 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.animation;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.AndroidRuntimeException;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-
-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(TimeInterpolator)}.</p>
- */
-public class ValueAnimator extends Animator {
-
-    /**
-     * Internal constants
-     */
-
-    /*
-     * The default amount of time in ms between animation frames
-     */
-    private static final long DEFAULT_FRAME_DELAY = 10;
-
-    /**
-     * 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
-     */
-    static final int ANIMATION_START = 0;
-    static final int ANIMATION_FRAME = 1;
-
-    /**
-     * Values used with internal variable mPlayingState to indicate the current state of an
-     * animation.
-     */
-    static final int STOPPED    = 0; // Not yet playing
-    static final int RUNNING    = 1; // Playing normally
-    static final int SEEKED     = 2; // 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()
-    long mStartTime;
-
-    /**
-     * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked
-     * to a value.
-     */
-    long mSeekTime = -1;
-
-    // TODO: We access the following ThreadLocal variables often, some of them on every update.
-    // If ThreadLocal access is significantly expensive, we may want to put all of these
-    // fields into a structure sot hat we just access ThreadLocal once to get the reference
-    // to that structure, then access the structure directly for each field.
-
-    // The static sAnimationHandler processes the internal timing loop on which all animations
-    // are based
-    private static ThreadLocal<AnimationHandler> sAnimationHandler =
-            new ThreadLocal<AnimationHandler>();
-
-    // The per-thread list of all active animations
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sAnimations =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
-    // The per-thread set of animations to be started on the next animation frame
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sPendingAnimations =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
-    /**
-     * Internal per-thread collections used to avoid set collisions as animations start and end
-     * while being processed.
-     */
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sDelayedAnims =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sEndingAnims =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sReadyAnims =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
-    // The time interpolator to be used if none is set on the animation
-    private static final /*Time*/Interpolator sDefaultInterpolator =
-            new AccelerateDecelerateInterpolator();
-
-    // type evaluators for the primitive types handled by this implementation
-    private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
-    private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator();
-
-    /**
-     * 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 current elapsed/eased fraction, for querying in getAnimatedFraction().
-     */
-    private float mCurrentFraction = 0f;
-
-    /**
-     * 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, SEEKED.
-     */
-    int mPlayingState = STOPPED;
-
-    /**
-     * Additional playing state to indicate whether an animator has been start()'d. There is
-     * some lag between a call to start() and the first animation frame. We should still note
-     * that the animation has been started, even if it's first animation frame has not yet
-     * happened, and reflect that state in isRunning().
-     * Note that delayed animations are different: they are not started until their first
-     * animation frame, which occurs after their delay elapses.
-     */
-    private boolean mRunning = false;
-
-    /**
-     * Additional playing state to indicate whether an animator has been start()'d, whether or
-     * not there is a nonzero startDelay.
-     */
-    private boolean mStarted = false;
-
-    /**
-     * 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 = 300;
-
-    // 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 /*Time*/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 factory methods which take parameters are more generally
-     * useful.
-     */
-    public ValueAnimator() {
-    }
-
-    /**
-     * Constructs and returns a ValueAnimator that animates between int values. A single
-     * value implies that that value is the one being animated to. However, this is not typically
-     * useful in a ValueAnimator object because there is no way for the object to determine the
-     * starting value for the animation (unlike ObjectAnimator, which can derive that value
-     * from the target object and property being animated). Therefore, there should typically
-     * be two or more values.
-     *
-     * @param values A set of values that the animation will animate between over time.
-     * @return A ValueAnimator object that is set up to animate between the given values.
-     */
-    public static ValueAnimator ofInt(int... values) {
-        ValueAnimator anim = new ValueAnimator();
-        anim.setIntValues(values);
-        return anim;
-    }
-
-    /**
-     * Constructs and returns a ValueAnimator that animates between float values. A single
-     * value implies that that value is the one being animated to. However, this is not typically
-     * useful in a ValueAnimator object because there is no way for the object to determine the
-     * starting value for the animation (unlike ObjectAnimator, which can derive that value
-     * from the target object and property being animated). Therefore, there should typically
-     * be two or more values.
-     *
-     * @param values A set of values that the animation will animate between over time.
-     * @return A ValueAnimator object that is set up to animate between the given values.
-     */
-    public static ValueAnimator ofFloat(float... values) {
-        ValueAnimator anim = new ValueAnimator();
-        anim.setFloatValues(values);
-        return anim;
-    }
-
-    /**
-     * Constructs and returns a ValueAnimator that animates between the values
-     * specified in the PropertyValuesHolder objects.
-     *
-     * @param values A set of PropertyValuesHolder objects whose values will be animated
-     * between over time.
-     * @return A ValueAnimator object that is set up to animate between the given values.
-     */
-    public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) {
-        ValueAnimator anim = new ValueAnimator();
-        anim.setValues(values);
-        return anim;
-    }
-    /**
-     * Constructs and returns a ValueAnimator that animates between Object values. A single
-     * value implies that that value is the one being animated to. However, this is not typically
-     * useful in a ValueAnimator object because there is no way for the object to determine the
-     * starting value for the animation (unlike ObjectAnimator, which can derive that value
-     * from the target object and property being animated). Therefore, there should typically
-     * be two or more values.
-     *
-     * <p>Since ValueAnimator does not know how to animate between arbitrary Objects, this
-     * factory method also takes a TypeEvaluator object that the ValueAnimator will use
-     * to perform that interpolation.
-     *
-     * @param evaluator A TypeEvaluator that will be called on each animation frame to
-     * provide the ncessry interpolation between the Object values to derive the animated
-     * value.
-     * @param values A set of values that the animation will animate between over time.
-     * @return A ValueAnimator object that is set up to animate between the given values.
-     */
-    public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
-        ValueAnimator anim = new ValueAnimator();
-        anim.setObjectValues(values);
-        anim.setEvaluator(evaluator);
-        return anim;
-    }
-
-    /**
-     * Sets int values that will be animated between. A single
-     * value implies that that value is the one being animated to. However, this is not typically
-     * useful in a ValueAnimator object because there is no way for the object to determine the
-     * starting value for the animation (unlike ObjectAnimator, which can derive that value
-     * from the target object and property being animated). Therefore, there should typically
-     * be two or more values.
-     *
-     * <p>If there are already multiple sets of values defined for this ValueAnimator via more
-     * than one PropertyValuesHolder object, this method will set the values for the first
-     * of those objects.</p>
-     *
-     * @param values A set of values that the animation will animate between over time.
-     */
-    public void setIntValues(int... values) {
-        if (values == null || values.length == 0) {
-            return;
-        }
-        if (mValues == null || mValues.length == 0) {
-            setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofInt("", values)});
-        } else {
-            PropertyValuesHolder valuesHolder = mValues[0];
-            valuesHolder.setIntValues(values);
-        }
-        // New property/values/target should cause re-initialization prior to starting
-        mInitialized = false;
-    }
-
-    /**
-     * Sets float values that will be animated between. A single
-     * value implies that that value is the one being animated to. However, this is not typically
-     * useful in a ValueAnimator object because there is no way for the object to determine the
-     * starting value for the animation (unlike ObjectAnimator, which can derive that value
-     * from the target object and property being animated). Therefore, there should typically
-     * be two or more values.
-     *
-     * <p>If there are already multiple sets of values defined for this ValueAnimator via more
-     * than one PropertyValuesHolder object, this method will set the values for the first
-     * of those objects.</p>
-     *
-     * @param values A set of values that the animation will animate between over time.
-     */
-    public void setFloatValues(float... values) {
-        if (values == null || values.length == 0) {
-            return;
-        }
-        if (mValues == null || mValues.length == 0) {
-            setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofFloat("", values)});
-        } else {
-            PropertyValuesHolder valuesHolder = mValues[0];
-            valuesHolder.setFloatValues(values);
-        }
-        // New property/values/target should cause re-initialization prior to starting
-        mInitialized = false;
-    }
-
-    /**
-     * Sets the values to animate between for this animation. A single
-     * value implies that that value is the one being animated to. However, this is not typically
-     * useful in a ValueAnimator object because there is no way for the object to determine the
-     * starting value for the animation (unlike ObjectAnimator, which can derive that value
-     * from the target object and property being animated). Therefore, there should typically
-     * be two or more values.
-     *
-     * <p>If there are already multiple sets of values defined for this ValueAnimator via more
-     * than one PropertyValuesHolder object, this method will set the values for the first
-     * of those objects.</p>
-     *
-     * <p>There should be a TypeEvaluator set on the ValueAnimator that knows how to interpolate
-     * between these value objects. ValueAnimator only knows how to interpolate between the
-     * primitive types specified in the other setValues() methods.</p>
-     *
-     * @param values The set of values to animate between.
-     */
-    public void setObjectValues(Object... values) {
-        if (values == null || values.length == 0) {
-            return;
-        }
-        if (mValues == null || mValues.length == 0) {
-            setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofObject("",
-                    (TypeEvaluator)null, values)});
-        } else {
-            PropertyValuesHolder valuesHolder = mValues[0];
-            valuesHolder.setObjectValues(values);
-        }
-        // New property/values/target should cause re-initialization prior to starting
-        mInitialized = false;
-    }
-
-    /**
-     * 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);
-        }
-        // New property/values/target should cause re-initialization prior to starting
-        mInitialized = false;
-    }
-
-    /**
-     * 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;
-    }
-
-    /**
-     * 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();
-            }
-            mInitialized = true;
-        }
-    }
-
-
-    /**
-     * Sets the length of the animation. The default duration is 300 milliseconds.
-     *
-     * @param duration The length of the animation, in milliseconds. This value cannot
-     * be negative.
-     * @return ValueAnimator The object called with setDuration(). This return
-     * value makes it easier to compose statements together that construct and then set the
-     * duration, as in <code>ValueAnimator.ofInt(0, 10).setDuration(500).start()</code>.
-     */
-    public ValueAnimator setDuration(long duration) {
-        if (duration < 0) {
-            throw new IllegalArgumentException("Animators cannot have negative duration: " +
-                    duration);
-        }
-        mDuration = duration;
-        return this;
-    }
-
-    /**
-     * Gets the length of the animation. The default duration is 300 milliseconds.
-     *
-     * @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;
-            ArrayList<ValueAnimator> animations = sAnimations.get();
-            ArrayList<ValueAnimator> delayedAnims = sDelayedAnims.get();
-            switch (msg.what) {
-                // TODO: should we avoid sending frame message when starting if we
-                // were already running?
-                case ANIMATION_START:
-                    ArrayList<ValueAnimator> pendingAnimations = sPendingAnimations.get();
-                    if (animations.size() > 0 || delayedAnims.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 (pendingAnimations.size() > 0) {
-                        ArrayList<ValueAnimator> pendingCopy =
-                                (ArrayList<ValueAnimator>) pendingAnimations.clone();
-                        pendingAnimations.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.startAnimation();
-                            } else {
-                                delayedAnims.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();
-                    ArrayList<ValueAnimator> readyAnims = sReadyAnims.get();
-                    ArrayList<ValueAnimator> endingAnims = sEndingAnims.get();
-
-                    // First, process animations currently sitting on the delayed queue, adding
-                    // them to the active animations if they are ready
-                    int numDelayedAnims = delayedAnims.size();
-                    for (int i = 0; i < numDelayedAnims; ++i) {
-                        ValueAnimator anim = delayedAnims.get(i);
-                        if (anim.delayedAnimationFrame(currentTime)) {
-                            readyAnims.add(anim);
-                        }
-                    }
-                    int numReadyAnims = readyAnims.size();
-                    if (numReadyAnims > 0) {
-                        for (int i = 0; i < numReadyAnims; ++i) {
-                            ValueAnimator anim = readyAnims.get(i);
-                            anim.startAnimation();
-                            anim.mRunning = true;
-                            delayedAnims.remove(anim);
-                        }
-                        readyAnims.clear();
-                    }
-
-                    // Now process all active animations. The return value from animationFrame()
-                    // tells the handler whether it should now be ended
-                    int numAnims = animations.size();
-                    int i = 0;
-                    while (i < numAnims) {
-                        ValueAnimator anim = animations.get(i);
-                        if (anim.animationFrame(currentTime)) {
-                            endingAnims.add(anim);
-                        }
-                        if (animations.size() == numAnims) {
-                            ++i;
-                        } else {
-                            // An animation might be canceled or ended by client code
-                            // during the animation frame. Check to see if this happened by
-                            // seeing whether the current index is the same as it was before
-                            // calling animationFrame(). Another approach would be to copy
-                            // animations to a temporary list and process that list instead,
-                            // but that entails garbage and processing overhead that would
-                            // be nice to avoid.
-                            --numAnims;
-                            endingAnims.remove(anim);
-                        }
-                    }
-                    if (endingAnims.size() > 0) {
-                        for (i = 0; i < endingAnims.size(); ++i) {
-                            endingAnims.get(i).endAnimation();
-                        }
-                        endingAnims.clear();
-                    }
-
-                    // If there are still active or delayed animations, call the handler again
-                    // after the frameDelay
-                    if (callAgain && (!animations.isEmpty() || !delayedAnims.isEmpty())) {
-                        sendEmptyMessageDelayed(ANIMATION_FRAME, Math.max(0, sFrameDelay -
-                            (AnimationUtils.currentAnimationTimeMillis() - currentTime)));
-                    }
-                    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 all listeners from the set listening to frame updates for this animation.
-     */
-    public void removeAllUpdateListeners() {
-        if (mUpdateListeners == null) {
-            return;
-        }
-        mUpdateListeners.clear();
-        mUpdateListeners = null;
-    }
-
-    /**
-     * 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. A value of <code>null</code>
-     * will result in linear interpolation.
-     */
-    @Override
-    public void setInterpolator(/*Time*/Interpolator value) {
-        if (value != null) {
-            mInterpolator = value;
-        } else {
-            mInterpolator = new LinearInterpolator();
-        }
-    }
-
-    /**
-     * Returns the timing interpolator that this ValueAnimator uses.
-     *
-     * @return The timing interpolator for this ValueAnimator.
-     */
-    public /*Time*/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 or int 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 ArgbEvaluator}
-     * 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.
-     *
-     * <p>The animation started by calling this method will be run on the thread that called
-     * this method. This thread should have a Looper on it (a runtime exception will be thrown if
-     * this is not the case). Also, if the animation will animate
-     * properties of objects in the view hierarchy, then the calling thread should be the UI
-     * thread for that view hierarchy.</p>
-     *
-     * @param playBackwards Whether the ValueAnimator should start playing in reverse.
-     */
-    private void start(boolean playBackwards) {
-        if (Looper.myLooper() == null) {
-            throw new AndroidRuntimeException("Animators may only be run on Looper threads");
-        }
-        mPlayingBackwards = playBackwards;
-        mCurrentIteration = 0;
-        mPlayingState = STOPPED;
-        mStarted = true;
-        mStartedDelay = false;
-        sPendingAnimations.get().add(this);
-        if (mStartDelay == 0) {
-            // This sets the initial value of the animation, prior to actually starting it running
-            setCurrentPlayTime(getCurrentPlayTime());
-            mPlayingState = STOPPED;
-            mRunning = true;
-
-            if (mListeners != null) {
-                ArrayList<AnimatorListener> tmpListeners =
-                        (ArrayList<AnimatorListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onAnimationStart(this);
-                }
-            }
-        }
-        AnimationHandler animationHandler = sAnimationHandler.get();
-        if (animationHandler == null) {
-            animationHandler = new AnimationHandler();
-            sAnimationHandler.set(animationHandler);
-        }
-        animationHandler.sendEmptyMessage(ANIMATION_START);
-    }
-
-    @Override
-    public void start() {
-        start(false);
-    }
-
-    @Override
-    public void cancel() {
-        // Only cancel if the animation is actually running or has been started and is about
-        // to run
-        if (mPlayingState != STOPPED || sPendingAnimations.get().contains(this) ||
-                sDelayedAnims.get().contains(this)) {
-            // Only notify listeners if the animator has actually started
-            if (mRunning && mListeners != null) {
-                ArrayList<AnimatorListener> tmpListeners =
-                        (ArrayList<AnimatorListener>) mListeners.clone();
-                for (AnimatorListener listener : tmpListeners) {
-                    listener.onAnimationCancel(this);
-                }
-            }
-            endAnimation();
-        }
-    }
-
-    @Override
-    public void end() {
-        if (!sAnimations.get().contains(this) && !sPendingAnimations.get().contains(this)) {
-            // Special case if the animation has not yet started; get it ready for ending
-            mStartedDelay = false;
-            startAnimation();
-        } else if (!mInitialized) {
-            initAnimation();
-        }
-        // 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);
-        }
-        endAnimation();
-    }
-
-    @Override
-    public boolean isRunning() {
-        return (mPlayingState == RUNNING || mRunning);
-    }
-
-    @Override
-    public boolean isStarted() {
-        return mStarted;
-    }
-
-    /**
-     * 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.get().remove(this);
-        sPendingAnimations.get().remove(this);
-        sDelayedAnims.get().remove(this);
-        mPlayingState = STOPPED;
-        if (mRunning && mListeners != null) {
-            ArrayList<AnimatorListener> tmpListeners =
-                    (ArrayList<AnimatorListener>) mListeners.clone();
-            int numListeners = tmpListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                tmpListeners.get(i).onAnimationEnd(this);
-            }
-        }
-        mRunning = false;
-        mStarted = false;
-    }
-
-    /**
-     * 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.get().add(this);
-        if (mStartDelay > 0 && mListeners != null) {
-            // Listeners were already notified in start() if startDelay is 0; this is
-            // just for delayed animations
-            ArrayList<AnimatorListener> tmpListeners =
-                    (ArrayList<AnimatorListener>) mListeners.clone();
-            int numListeners = tmpListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                tmpListeners.get(i).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 (!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.
-     */
-    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 = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
-            if (fraction >= 1f) {
-                if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
-                    // Time to repeat
-                    if (mListeners != null) {
-                        int numListeners = mListeners.size();
-                        for (int i = 0; i < numListeners; ++i) {
-                            mListeners.get(i).onAnimationRepeat(this);
-                        }
-                    }
-                    if (mRepeatMode == REVERSE) {
-                        mPlayingBackwards = mPlayingBackwards ? false : true;
-                    }
-                    mCurrentIteration += (int)fraction;
-                    fraction = fraction % 1f;
-                    mStartTime += mDuration;
-                } else {
-                    done = true;
-                    fraction = Math.min(fraction, 1.0f);
-                }
-            }
-            if (mPlayingBackwards) {
-                fraction = 1f - fraction;
-            }
-            animateValue(fraction);
-            break;
-        }
-
-        return done;
-    }
-
-    /**
-     * Returns the current animation fraction, which is the elapsed/interpolated fraction used in
-     * the most recent frame update on the animation.
-     *
-     * @return Elapsed/interpolated fraction of the animation.
-     */
-    public float getAnimatedFraction() {
-        return mCurrentFraction;
-    }
-
-    /**
-     * 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);
-        mCurrentFraction = 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];
-            anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
-            for (int i = 0; i < numValues; ++i) {
-                PropertyValuesHolder newValuesHolder = oldValues[i].clone();
-                anim.mValues[i] = newValuesHolder;
-                anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder);
-            }
-        }
-        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);
-
-    }
-
-    /**
-     * Return the number of animations currently running.
-     *
-     * Used by StrictMode internally to annotate violations.  Only
-     * called on the main thread.
-     *
-     * @hide
-     */
-    public static int getCurrentAnimationsCount() {
-        return sAnimations.get().size();
-    }
-
-    /**
-     * Clear all animations on this thread, without canceling or ending them.
-     * This should be used with caution.
-     *
-     * @hide
-     */
-    public static void clearAllAnimations() {
-        sAnimations.get().clear();
-        sPendingAnimations.get().clear();
-        sDelayedAnims.get().clear();
-    }
-
-    @Override
-    public String toString() {
-        String returnVal = "ValueAnimator@" + Integer.toHexString(hashCode());
-        if (mValues != null) {
-            for (int i = 0; i < mValues.length; ++i) {
-                returnVal += "\n    " + mValues[i].toString();
-            }
-        }
-        return returnVal;
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/util/FloatProperty.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.nineoldandroids.util;
-
-/**
- * An implementation of {@link android.util.Property} to be used specifically with fields of type
- * <code>float</code>. This type-specific subclass enables performance benefit by allowing
- * calls to a {@link #set(Object, Float) set()} function that takes the primitive
- * <code>float</code> type and avoids autoboxing and other overhead associated with the
- * <code>Float</code> class.
- *
- * @param <T> The class on which the Property is declared.
- *
- * @hide
- */
-public abstract class FloatProperty<T> extends Property<T, Float> {
-
-    public FloatProperty(String name) {
-        super(Float.class, name);
-    }
-
-    /**
-     * A type-specific override of the {@link #set(Object, Float)} that is faster when dealing
-     * with fields of type <code>float</code>.
-     */
-    public abstract void setValue(T object, float value);
-
-    @Override
-    final public void set(T object, Float value) {
-        setValue(object, value);
-    }
-
-}
\ No newline at end of file
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/util/IntProperty.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.nineoldandroids.util;
-
-/**
- * An implementation of {@link android.util.Property} to be used specifically with fields of type
- * <code>int</code>. This type-specific subclass enables performance benefit by allowing
- * calls to a {@link #set(Object, Integer) set()} function that takes the primitive
- * <code>int</code> type and avoids autoboxing and other overhead associated with the
- * <code>Integer</code> class.
- *
- * @param <T> The class on which the Property is declared.
- *
- * @hide
- */
-public abstract class IntProperty<T> extends Property<T, Integer> {
-
-    public IntProperty(String name) {
-        super(Integer.class, name);
-    }
-
-    /**
-     * A type-specific override of the {@link #set(Object, Integer)} that is faster when dealing
-     * with fields of type <code>int</code>.
-     */
-    public abstract void setValue(T object, int value);
-
-    @Override
-    final public void set(T object, Integer value) {
-        set(object, value.intValue());
-    }
-
-}
\ No newline at end of file
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/util/NoSuchPropertyException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.nineoldandroids.util;
-
-/**
- * Thrown when code requests a {@link Property} on a class that does
- * not expose the appropriate method or field.
- *
- * @see Property#of(java.lang.Class, java.lang.Class, java.lang.String)
- */
-public class NoSuchPropertyException extends RuntimeException {
-
-    public NoSuchPropertyException(String s) {
-        super(s);
-    }
-
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/util/Property.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.nineoldandroids.util;
-
-
-/**
- * A property is an abstraction that can be used to represent a <emb>mutable</em> value that is held
- * in a <em>host</em> object. The Property's {@link #set(Object, Object)} or {@link #get(Object)}
- * methods can be implemented in terms of the private fields of the host object, or via "setter" and
- * "getter" methods or by some other mechanism, as appropriate.
- *
- * @param <T> The class on which the property is declared.
- * @param <V> The type that this property represents.
- */
-public abstract class Property<T, V> {
-
-    private final String mName;
-    private final Class<V> mType;
-
-    /**
-     * This factory method creates and returns a Property given the <code>class</code> and
-     * <code>name</code> parameters, where the <code>"name"</code> parameter represents either:
-     * <ul>
-     *     <li>a public <code>getName()</code> method on the class which takes no arguments, plus an
-     *     optional public <code>setName()</code> method which takes a value of the same type
-     *     returned by <code>getName()</code>
-     *     <li>a public <code>isName()</code> method on the class which takes no arguments, plus an
-     *     optional public <code>setName()</code> method which takes a value of the same type
-     *     returned by <code>isName()</code>
-     *     <li>a public <code>name</code> field on the class
-     * </ul>
-     *
-     * <p>If either of the get/is method alternatives is found on the class, but an appropriate
-     * <code>setName()</code> method is not found, the <code>Property</code> will be
-     * {@link #isReadOnly() readOnly}. Calling the {@link #set(Object, Object)} method on such
-     * a property is allowed, but will have no effect.</p>
-     *
-     * <p>If neither the methods nor the field are found on the class a
-     * {@link NoSuchPropertyException} exception will be thrown.</p>
-     */
-    public static <T, V> Property<T, V> of(Class<T> hostType, Class<V> valueType, String name) {
-        return new ReflectiveProperty<T, V>(hostType, valueType, name);
-    }
-
-    /**
-     * A constructor that takes an identifying name and {@link #getType() type} for the property.
-     */
-    public Property(Class<V> type, String name) {
-        mName = name;
-        mType = type;
-    }
-
-    /**
-     * Returns true if the {@link #set(Object, Object)} method does not set the value on the target
-     * object (in which case the {@link #set(Object, Object) set()} method should throw a {@link
-     * NoSuchPropertyException} exception). This may happen if the Property wraps functionality that
-     * allows querying the underlying value but not setting it. For example, the {@link #of(Class,
-     * Class, String)} factory method may return a Property with name "foo" for an object that has
-     * only a <code>getFoo()</code> or <code>isFoo()</code> method, but no matching
-     * <code>setFoo()</code> method.
-     */
-    public boolean isReadOnly() {
-        return false;
-    }
-
-    /**
-     * Sets the value on <code>object</code> which this property represents. If the method is unable
-     * to set the value on the target object it will throw an {@link UnsupportedOperationException}
-     * exception.
-     */
-    public void set(T object, V value) {
-        throw new UnsupportedOperationException("Property " + getName() +" is read-only");
-    }
-
-    /**
-     * Returns the current value that this property represents on the given <code>object</code>.
-     */
-    public abstract V get(T object);
-
-    /**
-     * Returns the name for this property.
-     */
-    public String getName() {
-        return mName;
-    }
-
-    /**
-     * Returns the type for this property.
-     */
-    public Class<V> getType() {
-        return mType;
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/util/ReflectiveProperty.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.nineoldandroids.util;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Internal class to automatically generate a Property for a given class/name pair, given the
- * specification of {@link Property#of(java.lang.Class, java.lang.Class, java.lang.String)}
- */
-class ReflectiveProperty<T, V> extends Property<T, V> {
-
-    private static final String PREFIX_GET = "get";
-    private static final String PREFIX_IS = "is";
-    private static final String PREFIX_SET = "set";
-    private Method mSetter;
-    private Method mGetter;
-    private Field mField;
-
-    /**
-     * For given property name 'name', look for getName/isName method or 'name' field.
-     * Also look for setName method (optional - could be readonly). Failing method getters and
-     * field results in throwing NoSuchPropertyException.
-     *
-     * @param propertyHolder The class on which the methods or field are found
-     * @param name The name of the property, where this name is capitalized and appended to
-     * "get" and "is to search for the appropriate methods. If the get/is methods are not found,
-     * the constructor will search for a field with that exact name.
-     */
-    public ReflectiveProperty(Class<T> propertyHolder, Class<V> valueType, String name) {
-         // TODO: cache reflection info for each new class/name pair
-        super(valueType, name);
-        char firstLetter = Character.toUpperCase(name.charAt(0));
-        String theRest = name.substring(1);
-        String capitalizedName = firstLetter + theRest;
-        String getterName = PREFIX_GET + capitalizedName;
-        try {
-            mGetter = propertyHolder.getMethod(getterName, (Class<?>[]) null);
-        } catch (NoSuchMethodException e) {
-            try {
-                /* The native implementation uses JNI to do reflection, which allows access to private methods.
-                 * getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
-                 */
-                mGetter = propertyHolder.getDeclaredMethod(getterName, (Class<?>[]) null);
-                mGetter.setAccessible(true);
-            } catch (NoSuchMethodException e2) {
-                // getName() not available - try isName() instead
-                getterName = PREFIX_IS + capitalizedName;
-                try {
-                    mGetter = propertyHolder.getMethod(getterName, (Class<?>[]) null);
-                } catch (NoSuchMethodException e3) {
-                    try {
-                        /* The native implementation uses JNI to do reflection, which allows access to private methods.
-                         * getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
-                         */
-                        mGetter = propertyHolder.getDeclaredMethod(getterName, (Class<?>[]) null);
-                        mGetter.setAccessible(true);
-                    } catch (NoSuchMethodException e4) {
-                        // Try public field instead
-                        try {
-                            mField = propertyHolder.getField(name);
-                            Class fieldType = mField.getType();
-                            if (!typesMatch(valueType, fieldType)) {
-                                throw new NoSuchPropertyException("Underlying type (" + fieldType + ") " +
-                                        "does not match Property type (" + valueType + ")");
-                            }
-                            return;
-                        } catch (NoSuchFieldException e5) {
-                            // no way to access property - throw appropriate exception
-                            throw new NoSuchPropertyException("No accessor method or field found for"
-                                    + " property with name " + name);
-                        }
-                    }
-                }
-            }
-        }
-        Class getterType = mGetter.getReturnType();
-        // Check to make sure our getter type matches our valueType
-        if (!typesMatch(valueType, getterType)) {
-            throw new NoSuchPropertyException("Underlying type (" + getterType + ") " +
-                    "does not match Property type (" + valueType + ")");
-        }
-        String setterName = PREFIX_SET + capitalizedName;
-        try {
-            // mSetter = propertyHolder.getMethod(setterName, getterType);
-            // The native implementation uses JNI to do reflection, which allows access to private methods.
-            mSetter = propertyHolder.getDeclaredMethod(setterName, getterType);
-            mSetter.setAccessible(true);
-        } catch (NoSuchMethodException ignored) {
-            // Okay to not have a setter - just a readonly property
-        }
-    }
-
-    /**
-     * Utility method to check whether the type of the underlying field/method on the target
-     * object matches the type of the Property. The extra checks for primitive types are because
-     * generics will force the Property type to be a class, whereas the type of the underlying
-     * method/field will probably be a primitive type instead. Accept float as matching Float,
-     * etc.
-     */
-    private boolean typesMatch(Class<V> valueType, Class getterType) {
-        if (getterType != valueType) {
-            if (getterType.isPrimitive()) {
-                return (getterType == float.class && valueType == Float.class) ||
-                        (getterType == int.class && valueType == Integer.class) ||
-                        (getterType == boolean.class && valueType == Boolean.class) ||
-                        (getterType == long.class && valueType == Long.class) ||
-                        (getterType == double.class && valueType == Double.class) ||
-                        (getterType == short.class && valueType == Short.class) ||
-                        (getterType == byte.class && valueType == Byte.class) ||
-                        (getterType == char.class && valueType == Character.class);
-            }
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public void set(T object, V value) {
-        if (mSetter != null) {
-            try {
-                mSetter.invoke(object, value);
-            } catch (IllegalAccessException e) {
-                throw new AssertionError();
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException(e.getCause());
-            }
-        } else if (mField != null) {
-            try {
-                mField.set(object, value);
-            } catch (IllegalAccessException e) {
-                throw new AssertionError();
-            }
-        } else {
-            throw new UnsupportedOperationException("Property " + getName() +" is read-only");
-        }
-    }
-
-    @Override
-    public V get(T object) {
-        if (mGetter != null) {
-            try {
-                return (V) mGetter.invoke(object, (Object[])null);
-            } catch (IllegalAccessException e) {
-                throw new AssertionError();
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException(e.getCause());
-            }
-        } else if (mField != null) {
-            try {
-                return (V) mField.get(object);
-            } catch (IllegalAccessException e) {
-                throw new AssertionError();
-            }
-        }
-        // Should not get here: there should always be a non-null getter or field
-        throw new AssertionError();
-    }
-
-    /**
-     * Returns false if there is no setter or public field underlying this Property.
-     */
-    @Override
-    public boolean isReadOnly() {
-        return (mSetter == null && mField == null);
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/view/ViewHelper.java
+++ /dev/null
@@ -1,292 +0,0 @@
-package com.nineoldandroids.view;
-
-import android.view.View;
-
-import static com.nineoldandroids.view.animation.AnimatorProxy.NEEDS_PROXY;
-import static com.nineoldandroids.view.animation.AnimatorProxy.wrap;
-
-public final class ViewHelper {
-    private ViewHelper() {}
-
-    public static float getAlpha(View view) {
-        return NEEDS_PROXY ? wrap(view).getAlpha() : Honeycomb.getAlpha(view);
-    }
-
-    public static void setAlpha(View view, float alpha) {
-        if (NEEDS_PROXY) {
-            wrap(view).setAlpha(alpha);
-        } else {
-            Honeycomb.setAlpha(view, alpha);
-        }
-    }
-
-    public static float getPivotX(View view) {
-        return NEEDS_PROXY ? wrap(view).getPivotX() : Honeycomb.getPivotX(view);
-    }
-
-    public static void setPivotX(View view, float pivotX) {
-        if (NEEDS_PROXY) {
-            wrap(view).setPivotX(pivotX);
-        } else {
-            Honeycomb.setPivotX(view, pivotX);
-        }
-    }
-
-    public static float getPivotY(View view) {
-        return NEEDS_PROXY ? wrap(view).getPivotY() : Honeycomb.getPivotY(view);
-    }
-
-    public static void setPivotY(View view, float pivotY) {
-        if (NEEDS_PROXY) {
-            wrap(view).setPivotY(pivotY);
-        } else {
-            Honeycomb.setPivotY(view, pivotY);
-        }
-    }
-
-    public static float getRotation(View view) {
-        return NEEDS_PROXY ? wrap(view).getRotation() : Honeycomb.getRotation(view);
-    }
-
-    public static void setRotation(View view, float rotation) {
-        if (NEEDS_PROXY) {
-            wrap(view).setRotation(rotation);
-        } else {
-            Honeycomb.setRotation(view, rotation);
-        }
-    }
-
-    public static float getRotationX(View view) {
-        return NEEDS_PROXY ? wrap(view).getRotationX() : Honeycomb.getRotationX(view);
-    }
-
-    public static void setRotationX(View view, float rotationX) {
-        if (NEEDS_PROXY) {
-            wrap(view).setRotationX(rotationX);
-        } else {
-            Honeycomb.setRotationX(view, rotationX);
-        }
-    }
-
-    public static float getRotationY(View view) {
-        return NEEDS_PROXY ? wrap(view).getRotationY() : Honeycomb.getRotationY(view);
-    }
-
-    public static void setRotationY(View view, float rotationY) {
-        if (NEEDS_PROXY) {
-            wrap(view).setRotationY(rotationY);
-        } else {
-            Honeycomb.setRotationY(view, rotationY);
-        }
-    }
-
-    public static float getScaleX(View view) {
-        return NEEDS_PROXY ? wrap(view).getScaleX() : Honeycomb.getScaleX(view);
-    }
-
-    public static void setScaleX(View view, float scaleX) {
-        if (NEEDS_PROXY) {
-            wrap(view).setScaleX(scaleX);
-        } else {
-            Honeycomb.setScaleX(view, scaleX);
-        }
-    }
-
-    public static float getScaleY(View view) {
-        return NEEDS_PROXY ? wrap(view).getScaleY() : Honeycomb.getScaleY(view);
-    }
-
-    public static void setScaleY(View view, float scaleY) {
-        if (NEEDS_PROXY) {
-            wrap(view).setScaleY(scaleY);
-        } else {
-            Honeycomb.setScaleY(view, scaleY);
-        }
-    }
-
-    public static float getScrollX(View view) {
-        return NEEDS_PROXY ? wrap(view).getScrollX() : Honeycomb.getScrollX(view);
-    }
-
-    public static void setScrollX(View view, int scrollX) {
-        if (NEEDS_PROXY) {
-            wrap(view).setScrollX(scrollX);
-        } else {
-            Honeycomb.setScrollX(view, scrollX);
-        }
-    }
-
-    public static float getScrollY(View view) {
-        return NEEDS_PROXY ? wrap(view).getScrollY() : Honeycomb.getScrollY(view);
-    }
-
-    public static void setScrollY(View view, int scrollY) {
-        if (NEEDS_PROXY) {
-            wrap(view).setScrollY(scrollY);
-        } else {
-            Honeycomb.setScrollY(view, scrollY);
-        }
-    }
-
-    public static float getTranslationX(View view) {
-        return NEEDS_PROXY ? wrap(view).getTranslationX() : Honeycomb.getTranslationX(view);
-    }
-
-    public static void setTranslationX(View view, float translationX) {
-        if (NEEDS_PROXY) {
-            wrap(view).setTranslationX(translationX);
-        } else {
-            Honeycomb.setTranslationX(view, translationX);
-        }
-    }
-
-    public static float getTranslationY(View view) {
-        return NEEDS_PROXY ? wrap(view).getTranslationY() : Honeycomb.getTranslationY(view);
-    }
-
-    public static void setTranslationY(View view, float translationY) {
-        if (NEEDS_PROXY) {
-            wrap(view).setTranslationY(translationY);
-        } else {
-            Honeycomb.setTranslationY(view, translationY);
-        }
-    }
-
-    public static float getX(View view) {
-        return NEEDS_PROXY ? wrap(view).getX() : Honeycomb.getX(view);
-    }
-
-    public static void setX(View view, float x) {
-        if (NEEDS_PROXY) {
-            wrap(view).setX(x);
-        } else {
-            Honeycomb.setX(view, x);
-        }
-    }
-
-    public static float getY(View view) {
-        return NEEDS_PROXY ? wrap(view).getY() : Honeycomb.getY(view);
-    }
-
-    public static void setY(View view, float y) {
-        if (NEEDS_PROXY) {
-            wrap(view).setY(y);
-        } else {
-            Honeycomb.setY(view, y);
-        }
-    }
-
-    private static final class Honeycomb {
-        static float getAlpha(View view) {
-            return view.getAlpha();
-        }
-
-        static void setAlpha(View view, float alpha) {
-            view.setAlpha(alpha);
-        }
-
-        static float getPivotX(View view) {
-            return view.getPivotX();
-        }
-
-        static void setPivotX(View view, float pivotX) {
-            view.setPivotX(pivotX);
-        }
-
-        static float getPivotY(View view) {
-            return view.getPivotY();
-        }
-
-        static void setPivotY(View view, float pivotY) {
-            view.setPivotY(pivotY);
-        }
-
-        static float getRotation(View view) {
-            return view.getRotation();
-        }
-
-        static void setRotation(View view, float rotation) {
-            view.setRotation(rotation);
-        }
-
-        static float getRotationX(View view) {
-            return view.getRotationX();
-        }
-
-        static void setRotationX(View view, float rotationX) {
-            view.setRotationX(rotationX);
-        }
-
-        static float getRotationY(View view) {
-            return view.getRotationY();
-        }
-
-        static void setRotationY(View view, float rotationY) {
-            view.setRotationY(rotationY);
-        }
-
-        static float getScaleX(View view) {
-            return view.getScaleX();
-        }
-
-        static void setScaleX(View view, float scaleX) {
-            view.setScaleX(scaleX);
-        }
-
-        static float getScaleY(View view) {
-            return view.getScaleY();
-        }
-
-        static void setScaleY(View view, float scaleY) {
-            view.setScaleY(scaleY);
-        }
-
-        static float getScrollX(View view) {
-            return view.getScrollX();
-        }
-
-        static void setScrollX(View view, int scrollX) {
-            view.setScrollX(scrollX);
-        }
-
-        static float getScrollY(View view) {
-            return view.getScrollY();
-        }
-
-        static void setScrollY(View view, int scrollY) {
-            view.setScrollY(scrollY);
-        }
-
-        static float getTranslationX(View view) {
-            return view.getTranslationX();
-        }
-
-        static void setTranslationX(View view, float translationX) {
-            view.setTranslationX(translationX);
-        }
-
-        static float getTranslationY(View view) {
-            return view.getTranslationY();
-        }
-
-        static void setTranslationY(View view, float translationY) {
-            view.setTranslationY(translationY);
-        }
-
-        static float getX(View view) {
-            return view.getX();
-        }
-
-        static void setX(View view, float x) {
-            view.setX(x);
-        }
-
-        static float getY(View view) {
-            return view.getY();
-        }
-
-        static void setY(View view, float y) {
-            view.setY(y);
-        }
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/view/ViewPropertyAnimator.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.view;
-
-import java.util.WeakHashMap;
-import android.os.Build;
-import android.view.View;
-import android.view.animation.Interpolator;
-import com.nineoldandroids.animation.Animator;
-
-/**
- * This class enables automatic and optimized animation of select properties on View objects.
- * If only one or two properties on a View object are being animated, then using an
- * {@link android.animation.ObjectAnimator} is fine; the property setters called by ObjectAnimator
- * are well equipped to do the right thing to set the property and invalidate the view
- * appropriately. But if several properties are animated simultaneously, or if you just want a
- * more convenient syntax to animate a specific property, then ViewPropertyAnimator might be
- * more well-suited to the task.
- *
- * <p>This class may provide better performance for several simultaneous animations, because
- * it will optimize invalidate calls to take place only once for several properties instead of each
- * animated property independently causing its own invalidation. Also, the syntax of using this
- * class could be easier to use because the caller need only tell the View object which
- * property to animate, and the value to animate either to or by, and this class handles the
- * details of configuring the underlying Animator class and starting it.</p>
- *
- * <p>This class is not constructed by the caller, but rather by the View whose properties
- * it will animate. Calls to {@link android.view.View#animate()} will return a reference
- * to the appropriate ViewPropertyAnimator object for that View.</p>
- *
- */
-public abstract class ViewPropertyAnimator {
-    private static final WeakHashMap<View, ViewPropertyAnimator> ANIMATORS =
-            new WeakHashMap<View, ViewPropertyAnimator>(0);
-
-    /**
-     * This method returns a ViewPropertyAnimator object, which can be used to animate specific
-     * properties on this View.
-     *
-     * @param view View to animate.
-     * @return The ViewPropertyAnimator associated with this View.
-     */
-    public static ViewPropertyAnimator animate(View view) {
-        ViewPropertyAnimator animator = ANIMATORS.get(view);
-        if (animator == null) {
-            final int version = Integer.valueOf(Build.VERSION.SDK);
-            if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-                animator = new ViewPropertyAnimatorICS(view);
-            } else if (version >= Build.VERSION_CODES.HONEYCOMB) {
-                animator = new ViewPropertyAnimatorHC(view);
-            } else {
-                animator = new ViewPropertyAnimatorPreHC(view);
-            }
-            ANIMATORS.put(view, animator);
-        }
-        return animator;
-    }
-
-
-    /**
-     * Sets the duration for the underlying animator that animates the requested properties.
-     * By default, the animator uses the default value for ValueAnimator. Calling this method
-     * will cause the declared value to be used instead.
-     * @param duration The length of ensuing property animations, in milliseconds. The value
-     * cannot be negative.
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator setDuration(long duration);
-
-    /**
-     * Returns the current duration of property animations. If the duration was set on this
-     * object, that value is returned. Otherwise, the default value of the underlying Animator
-     * is returned.
-     *
-     * @see #setDuration(long)
-     * @return The duration of animations, in milliseconds.
-     */
-    public abstract long getDuration();
-
-    /**
-     * Returns the current startDelay of property animations. If the startDelay was set on this
-     * object, that value is returned. Otherwise, the default value of the underlying Animator
-     * is returned.
-     *
-     * @see #setStartDelay(long)
-     * @return The startDelay of animations, in milliseconds.
-     */
-    public abstract long getStartDelay();
-
-    /**
-     * Sets the startDelay for the underlying animator that animates the requested properties.
-     * By default, the animator uses the default value for ValueAnimator. Calling this method
-     * will cause the declared value to be used instead.
-     * @param startDelay The delay of ensuing property animations, in milliseconds. The value
-     * cannot be negative.
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator setStartDelay(long startDelay);
-
-    /**
-     * Sets the interpolator for the underlying animator that animates the requested properties.
-     * By default, the animator uses the default interpolator for ValueAnimator. Calling this method
-     * will cause the declared object to be used instead.
-     *
-     * @param interpolator The TimeInterpolator to be used for ensuing property animations.
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator setInterpolator(/*Time*/Interpolator interpolator);
-
-    /**
-     * Sets a listener for events in the underlying Animators that run the property
-     * animations.
-     *
-     * @param listener The listener to be called with AnimatorListener events.
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator setListener(Animator.AnimatorListener listener);
-
-    /**
-     * Starts the currently pending property animations immediately. Calling <code>start()</code>
-     * is optional because all animations start automatically at the next opportunity. However,
-     * if the animations are needed to start immediately and synchronously (not at the time when
-     * the next event is processed by the hierarchy, which is when the animations would begin
-     * otherwise), then this method can be used.
-     */
-    public abstract void start();
-
-    /**
-     * Cancels all property animations that are currently running or pending.
-     */
-    public abstract void cancel();
-
-    /**
-     * This method will cause the View's <code>x</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setX(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator x(float value);
-
-    /**
-     * This method will cause the View's <code>x</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setX(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator xBy(float value);
-
-    /**
-     * This method will cause the View's <code>y</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setY(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator y(float value);
-
-    /**
-     * This method will cause the View's <code>y</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setY(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator yBy(float value);
-
-    /**
-     * This method will cause the View's <code>rotation</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setRotation(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator rotation(float value);
-
-    /**
-     * This method will cause the View's <code>rotation</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setRotation(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator rotationBy(float value);
-
-    /**
-     * This method will cause the View's <code>rotationX</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setRotationX(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator rotationX(float value);
-
-    /**
-     * This method will cause the View's <code>rotationX</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setRotationX(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator rotationXBy(float value);
-
-    /**
-     * This method will cause the View's <code>rotationY</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setRotationY(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator rotationY(float value);
-
-    /**
-     * This method will cause the View's <code>rotationY</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setRotationY(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator rotationYBy(float value);
-
-    /**
-     * This method will cause the View's <code>translationX</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setTranslationX(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator translationX(float value);
-
-    /**
-     * This method will cause the View's <code>translationX</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setTranslationX(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator translationXBy(float value);
-
-    /**
-     * This method will cause the View's <code>translationY</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setTranslationY(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator translationY(float value);
-
-    /**
-     * This method will cause the View's <code>translationY</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setTranslationY(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator translationYBy(float value);
-
-    /**
-     * This method will cause the View's <code>scaleX</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setScaleX(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator scaleX(float value);
-
-    /**
-     * This method will cause the View's <code>scaleX</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setScaleX(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator scaleXBy(float value);
-
-    /**
-     * This method will cause the View's <code>scaleY</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setScaleY(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator scaleY(float value);
-
-    /**
-     * This method will cause the View's <code>scaleY</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setScaleY(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator scaleYBy(float value);
-
-    /**
-     * This method will cause the View's <code>alpha</code> property to be animated to the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The value to be animated to.
-     * @see View#setAlpha(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator alpha(float value);
-
-    /**
-     * This method will cause the View's <code>alpha</code> property to be animated by the
-     * specified value. Animations already running on the property will be canceled.
-     *
-     * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setAlpha(float)
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public abstract ViewPropertyAnimator alphaBy(float value);
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/view/ViewPropertyAnimatorHC.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.view;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Set;
-import android.view.View;
-import android.view.animation.Interpolator;
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.ValueAnimator;
-
-class ViewPropertyAnimatorHC extends ViewPropertyAnimator {
-
-    /**
-     * A WeakReference holding the View whose properties are being animated by this class.
-     * This is set at construction time.
-     */
-    private final WeakReference<View> mView;
-
-    /**
-     * The duration of the underlying Animator object. By default, we don't set the duration
-     * on the Animator and just use its default duration. If the duration is ever set on this
-     * Animator, then we use the duration that it was set to.
-     */
-    private long mDuration;
-
-    /**
-     * A flag indicating whether the duration has been set on this object. If not, we don't set
-     * the duration on the underlying Animator, but instead just use its default duration.
-     */
-    private boolean mDurationSet = false;
-
-    /**
-     * The startDelay of the underlying Animator object. By default, we don't set the startDelay
-     * on the Animator and just use its default startDelay. If the startDelay is ever set on this
-     * Animator, then we use the startDelay that it was set to.
-     */
-    private long mStartDelay = 0;
-
-    /**
-     * A flag indicating whether the startDelay has been set on this object. If not, we don't set
-     * the startDelay on the underlying Animator, but instead just use its default startDelay.
-     */
-    private boolean mStartDelaySet = false;
-
-    /**
-     * The interpolator of the underlying Animator object. By default, we don't set the interpolator
-     * on the Animator and just use its default interpolator. If the interpolator is ever set on
-     * this Animator, then we use the interpolator that it was set to.
-     */
-    private /*Time*/Interpolator mInterpolator;
-
-    /**
-     * A flag indicating whether the interpolator has been set on this object. If not, we don't set
-     * the interpolator on the underlying Animator, but instead just use its default interpolator.
-     */
-    private boolean mInterpolatorSet = false;
-
-    /**
-     * Listener for the lifecycle events of the underlying
-     */
-    private Animator.AnimatorListener mListener = null;
-
-    /**
-     * This listener is the mechanism by which the underlying Animator causes changes to the
-     * properties currently being animated, as well as the cleanup after an animation is
-     * complete.
-     */
-    private AnimatorEventListener mAnimatorEventListener = new AnimatorEventListener();
-
-    /**
-     * This list holds the properties that have been asked to animate. We allow the caller to
-     * request several animations prior to actually starting the underlying animator. This
-     * enables us to run one single animator to handle several properties in parallel. Each
-     * property is tossed onto the pending list until the animation actually starts (which is
-     * done by posting it onto mView), at which time the pending list is cleared and the properties
-     * on that list are added to the list of properties associated with that animator.
-     */
-    ArrayList<NameValuesHolder> mPendingAnimations = new ArrayList<NameValuesHolder>();
-
-    /**
-     * Constants used to associate a property being requested and the mechanism used to set
-     * the property (this class calls directly into View to set the properties in question).
-     */
-    private static final int NONE           = 0x0000;
-    private static final int TRANSLATION_X  = 0x0001;
-    private static final int TRANSLATION_Y  = 0x0002;
-    private static final int SCALE_X        = 0x0004;
-    private static final int SCALE_Y        = 0x0008;
-    private static final int ROTATION       = 0x0010;
-    private static final int ROTATION_X     = 0x0020;
-    private static final int ROTATION_Y     = 0x0040;
-    private static final int X              = 0x0080;
-    private static final int Y              = 0x0100;
-    private static final int ALPHA          = 0x0200;
-
-    private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | SCALE_X | SCALE_Y |
-            ROTATION | ROTATION_X | ROTATION_Y | X | Y;
-
-    /**
-     * The mechanism by which the user can request several properties that are then animated
-     * together works by posting this Runnable to start the underlying Animator. Every time
-     * a property animation is requested, we cancel any previous postings of the Runnable
-     * and re-post it. This means that we will only ever run the Runnable (and thus start the
-     * underlying animator) after the caller is done setting the properties that should be
-     * animated together.
-     */
-    private Runnable mAnimationStarter = new Runnable() {
-        @Override
-        public void run() {
-            startAnimation();
-        }
-    };
-
-    /**
-     * This class holds information about the overall animation being run on the set of
-     * properties. The mask describes which properties are being animated and the
-     * values holder is the list of all property/value objects.
-     */
-    private static class PropertyBundle {
-        int mPropertyMask;
-        ArrayList<NameValuesHolder> mNameValuesHolder;
-
-        PropertyBundle(int propertyMask, ArrayList<NameValuesHolder> nameValuesHolder) {
-            mPropertyMask = propertyMask;
-            mNameValuesHolder = nameValuesHolder;
-        }
-
-        /**
-         * Removes the given property from being animated as a part of this
-         * PropertyBundle. If the property was a part of this bundle, it returns
-         * true to indicate that it was, in fact, canceled. This is an indication
-         * to the caller that a cancellation actually occurred.
-         *
-         * @param propertyConstant The property whose cancellation is requested.
-         * @return true if the given property is a part of this bundle and if it
-         * has therefore been canceled.
-         */
-        boolean cancel(int propertyConstant) {
-            if ((mPropertyMask & propertyConstant) != 0 && mNameValuesHolder != null) {
-                int count = mNameValuesHolder.size();
-                for (int i = 0; i < count; ++i) {
-                    NameValuesHolder nameValuesHolder = mNameValuesHolder.get(i);
-                    if (nameValuesHolder.mNameConstant == propertyConstant) {
-                        mNameValuesHolder.remove(i);
-                        mPropertyMask &= ~propertyConstant;
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    /**
-     * This list tracks the list of properties being animated by any particular animator.
-     * In most situations, there would only ever be one animator running at a time. But it is
-     * possible to request some properties to animate together, then while those properties
-     * are animating, to request some other properties to animate together. The way that
-     * works is by having this map associate the group of properties being animated with the
-     * animator handling the animation. On every update event for an Animator, we ask the
-     * map for the associated properties and set them accordingly.
-     */
-    private HashMap<Animator, PropertyBundle> mAnimatorMap =
-            new HashMap<Animator, PropertyBundle>();
-
-    /**
-     * This is the information we need to set each property during the animation.
-     * mNameConstant is used to set the appropriate field in View, and the from/delta
-     * values are used to calculate the animated value for a given animation fraction
-     * during the animation.
-     */
-    private static class NameValuesHolder {
-        int mNameConstant;
-        float mFromValue;
-        float mDeltaValue;
-        NameValuesHolder(int nameConstant, float fromValue, float deltaValue) {
-            mNameConstant = nameConstant;
-            mFromValue = fromValue;
-            mDeltaValue = deltaValue;
-        }
-    }
-
-    /**
-     * Constructor, called by View. This is private by design, as the user should only
-     * get a ViewPropertyAnimator by calling View.animate().
-     *
-     * @param view The View associated with this ViewPropertyAnimator
-     */
-    ViewPropertyAnimatorHC(View view) {
-        mView = new WeakReference<View>(view);
-    }
-
-    /**
-     * Sets the duration for the underlying animator that animates the requested properties.
-     * By default, the animator uses the default value for ValueAnimator. Calling this method
-     * will cause the declared value to be used instead.
-     * @param duration The length of ensuing property animations, in milliseconds. The value
-     * cannot be negative.
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public ViewPropertyAnimator setDuration(long duration) {
-        if (duration < 0) {
-            throw new IllegalArgumentException("Animators cannot have negative duration: " +
-                    duration);
-        }
-        mDurationSet = true;
-        mDuration = duration;
-        return this;
-    }
-
-    /**
-     * Returns the current duration of property animations. If the duration was set on this
-     * object, that value is returned. Otherwise, the default value of the underlying Animator
-     * is returned.
-     *
-     * @see #setDuration(long)
-     * @return The duration of animations, in milliseconds.
-     */
-    public long getDuration() {
-        if (mDurationSet) {
-            return mDuration;
-        } else {
-            // Just return the default from ValueAnimator, since that's what we'd get if
-            // the value has not been set otherwise
-            return new ValueAnimator().getDuration();
-        }
-    }
-
-    @Override
-    public long getStartDelay() {
-        if (mStartDelaySet) {
-            return mStartDelay;
-        } else {
-            // Just return the default from ValueAnimator (0), since that's what we'd get if
-            // the value has not been set otherwise
-            return 0;
-        }
-    }
-
-    @Override
-    public ViewPropertyAnimator setStartDelay(long startDelay) {
-        if (startDelay < 0) {
-            throw new IllegalArgumentException("Animators cannot have negative duration: " +
-                    startDelay);
-        }
-        mStartDelaySet = true;
-        mStartDelay = startDelay;
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator setInterpolator(/*Time*/Interpolator interpolator) {
-        mInterpolatorSet = true;
-        mInterpolator = interpolator;
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator setListener(Animator.AnimatorListener listener) {
-        mListener = listener;
-        return this;
-    }
-
-    @Override
-    public void start() {
-        startAnimation();
-    }
-
-    @Override
-    public void cancel() {
-        if (mAnimatorMap.size() > 0) {
-            HashMap<Animator, PropertyBundle> mAnimatorMapCopy =
-                    (HashMap<Animator, PropertyBundle>)mAnimatorMap.clone();
-            Set<Animator> animatorSet = mAnimatorMapCopy.keySet();
-            for (Animator runningAnim : animatorSet) {
-                runningAnim.cancel();
-            }
-        }
-        mPendingAnimations.clear();
-        View v = mView.get();
-        if (v != null) {
-            v.removeCallbacks(mAnimationStarter);
-        }
-    }
-
-    @Override
-    public ViewPropertyAnimator x(float value) {
-        animateProperty(X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator xBy(float value) {
-        animatePropertyBy(X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator y(float value) {
-        animateProperty(Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator yBy(float value) {
-        animatePropertyBy(Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotation(float value) {
-        animateProperty(ROTATION, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationBy(float value) {
-        animatePropertyBy(ROTATION, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationX(float value) {
-        animateProperty(ROTATION_X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationXBy(float value) {
-        animatePropertyBy(ROTATION_X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationY(float value) {
-        animateProperty(ROTATION_Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationYBy(float value) {
-        animatePropertyBy(ROTATION_Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator translationX(float value) {
-        animateProperty(TRANSLATION_X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator translationXBy(float value) {
-        animatePropertyBy(TRANSLATION_X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator translationY(float value) {
-        animateProperty(TRANSLATION_Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator translationYBy(float value) {
-        animatePropertyBy(TRANSLATION_Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator scaleX(float value) {
-        animateProperty(SCALE_X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator scaleXBy(float value) {
-        animatePropertyBy(SCALE_X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator scaleY(float value) {
-        animateProperty(SCALE_Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator scaleYBy(float value) {
-        animatePropertyBy(SCALE_Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator alpha(float value) {
-        animateProperty(ALPHA, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator alphaBy(float value) {
-        animatePropertyBy(ALPHA, value);
-        return this;
-    }
-
-    /**
-     * Starts the underlying Animator for a set of properties. We use a single animator that
-     * simply runs from 0 to 1, and then use that fractional value to set each property
-     * value accordingly.
-     */
-    private void startAnimation() {
-        ValueAnimator animator = ValueAnimator.ofFloat(1.0f);
-        ArrayList<NameValuesHolder> nameValueList =
-                (ArrayList<NameValuesHolder>) mPendingAnimations.clone();
-        mPendingAnimations.clear();
-        int propertyMask = 0;
-        int propertyCount = nameValueList.size();
-        for (int i = 0; i < propertyCount; ++i) {
-            NameValuesHolder nameValuesHolder = nameValueList.get(i);
-            propertyMask |= nameValuesHolder.mNameConstant;
-        }
-        mAnimatorMap.put(animator, new PropertyBundle(propertyMask, nameValueList));
-        animator.addUpdateListener(mAnimatorEventListener);
-        animator.addListener(mAnimatorEventListener);
-        if (mStartDelaySet) {
-            animator.setStartDelay(mStartDelay);
-        }
-        if (mDurationSet) {
-            animator.setDuration(mDuration);
-        }
-        if (mInterpolatorSet) {
-            animator.setInterpolator(mInterpolator);
-        }
-        animator.start();
-    }
-
-    /**
-     * Utility function, called by the various x(), y(), etc. methods. This stores the
-     * constant name for the property along with the from/delta values that will be used to
-     * calculate and set the property during the animation. This structure is added to the
-     * pending animations, awaiting the eventual start() of the underlying animator. A
-     * Runnable is posted to start the animation, and any pending such Runnable is canceled
-     * (which enables us to end up starting just one animator for all of the properties
-     * specified at one time).
-     *
-     * @param constantName The specifier for the property being animated
-     * @param toValue The value to which the property will animate
-     */
-    private void animateProperty(int constantName, float toValue) {
-        float fromValue = getValue(constantName);
-        float deltaValue = toValue - fromValue;
-        animatePropertyBy(constantName, fromValue, deltaValue);
-    }
-
-    /**
-     * Utility function, called by the various xBy(), yBy(), etc. methods. This method is
-     * just like animateProperty(), except the value is an offset from the property's
-     * current value, instead of an absolute "to" value.
-     *
-     * @param constantName The specifier for the property being animated
-     * @param byValue The amount by which the property will change
-     */
-    private void animatePropertyBy(int constantName, float byValue) {
-        float fromValue = getValue(constantName);
-        animatePropertyBy(constantName, fromValue, byValue);
-    }
-
-    /**
-     * Utility function, called by animateProperty() and animatePropertyBy(), which handles the
-     * details of adding a pending animation and posting the request to start the animation.
-     *
-     * @param constantName The specifier for the property being animated
-     * @param startValue The starting value of the property
-     * @param byValue The amount by which the property will change
-     */
-    private void animatePropertyBy(int constantName, float startValue, float byValue) {
-        // First, cancel any existing animations on this property
-        if (mAnimatorMap.size() > 0) {
-            Animator animatorToCancel = null;
-            Set<Animator> animatorSet = mAnimatorMap.keySet();
-            for (Animator runningAnim : animatorSet) {
-                PropertyBundle bundle = mAnimatorMap.get(runningAnim);
-                if (bundle.cancel(constantName)) {
-                    // property was canceled - cancel the animation if it's now empty
-                    // Note that it's safe to break out here because every new animation
-                    // on a property will cancel a previous animation on that property, so
-                    // there can only ever be one such animation running.
-                    if (bundle.mPropertyMask == NONE) {
-                        // the animation is no longer changing anything - cancel it
-                        animatorToCancel = runningAnim;
-                        break;
-                    }
-                }
-            }
-            if (animatorToCancel != null) {
-                animatorToCancel.cancel();
-            }
-        }
-
-        NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue);
-        mPendingAnimations.add(nameValuePair);
-        View v = mView.get();
-        if (v != null) {
-            v.removeCallbacks(mAnimationStarter);
-            v.post(mAnimationStarter);
-        }
-    }
-
-    /**
-     * This method handles setting the property values directly in the View object's fields.
-     * propertyConstant tells it which property should be set, value is the value to set
-     * the property to.
-     *
-     * @param propertyConstant The property to be set
-     * @param value The value to set the property to
-     */
-    private void setValue(int propertyConstant, float value) {
-        //final View.TransformationInfo info = mView.mTransformationInfo;
-        View v = mView.get();
-        if (v != null) {
-            switch (propertyConstant) {
-                case TRANSLATION_X:
-                    //info.mTranslationX = value;
-                    v.setTranslationX(value);
-                    break;
-                case TRANSLATION_Y:
-                    //info.mTranslationY = value;
-                    v.setTranslationY(value);
-                    break;
-                case ROTATION:
-                    //info.mRotation = value;
-                    v.setRotation(value);
-                    break;
-                case ROTATION_X:
-                    //info.mRotationX = value;
-                    v.setRotationX(value);
-                    break;
-                case ROTATION_Y:
-                    //info.mRotationY = value;
-                    v.setRotationY(value);
-                    break;
-                case SCALE_X:
-                    //info.mScaleX = value;
-                    v.setScaleX(value);
-                    break;
-                case SCALE_Y:
-                    //info.mScaleY = value;
-                    v.setScaleY(value);
-                    break;
-                case X:
-                    //info.mTranslationX = value - v.mLeft;
-                    v.setX(value);
-                    break;
-                case Y:
-                    //info.mTranslationY = value - v.mTop;
-                    v.setY(value);
-                    break;
-                case ALPHA:
-                    //info.mAlpha = value;
-                    v.setAlpha(value);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * This method gets the value of the named property from the View object.
-     *
-     * @param propertyConstant The property whose value should be returned
-     * @return float The value of the named property
-     */
-    private float getValue(int propertyConstant) {
-        //final View.TransformationInfo info = mView.mTransformationInfo;
-        View v = mView.get();
-        if (v != null) {
-            switch (propertyConstant) {
-                case TRANSLATION_X:
-                    //return info.mTranslationX;
-                    return v.getTranslationX();
-                case TRANSLATION_Y:
-                    //return info.mTranslationY;
-                    return v.getTranslationY();
-                case ROTATION:
-                    //return info.mRotation;
-                    return v.getRotation();
-                case ROTATION_X:
-                    //return info.mRotationX;
-                    return v.getRotationX();
-                case ROTATION_Y:
-                    //return info.mRotationY;
-                    return v.getRotationY();
-                case SCALE_X:
-                    //return info.mScaleX;
-                    return v.getScaleX();
-                case SCALE_Y:
-                    //return info.mScaleY;
-                    return v.getScaleY();
-                case X:
-                    //return v.mLeft + info.mTranslationX;
-                    return v.getX();
-                case Y:
-                    //return v.mTop + info.mTranslationY;
-                    return v.getY();
-                case ALPHA:
-                    //return info.mAlpha;
-                    return v.getAlpha();
-            }
-        }
-        return 0;
-    }
-
-    /**
-     * Utility class that handles the various Animator events. The only ones we care
-     * about are the end event (which we use to clean up the animator map when an animator
-     * finishes) and the update event (which we use to calculate the current value of each
-     * property and then set it on the view object).
-     */
-    private class AnimatorEventListener
-            implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener {
-        @Override
-        public void onAnimationStart(Animator animation) {
-            if (mListener != null) {
-                mListener.onAnimationStart(animation);
-            }
-        }
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-            if (mListener != null) {
-                mListener.onAnimationCancel(animation);
-            }
-        }
-
-        @Override
-        public void onAnimationRepeat(Animator animation) {
-            if (mListener != null) {
-                mListener.onAnimationRepeat(animation);
-            }
-        }
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (mListener != null) {
-                mListener.onAnimationEnd(animation);
-            }
-            mAnimatorMap.remove(animation);
-            // If the map is empty, it means all animation are done or canceled, so the listener
-            // isn't needed anymore. Not nulling it would cause it to leak any objects used in
-            // its implementation
-            if (mAnimatorMap.isEmpty()) {
-                mListener = null;
-            }
-        }
-
-        /**
-         * Calculate the current value for each property and set it on the view. Invalidate
-         * the view object appropriately, depending on which properties are being animated.
-         *
-         * @param animation The animator associated with the properties that need to be
-         * set. This animator holds the animation fraction which we will use to calculate
-         * the current value of each property.
-         */
-        @Override
-        public void onAnimationUpdate(ValueAnimator animation) {
-            // alpha requires slightly different treatment than the other (transform) properties.
-            // The logic in setAlpha() is not simply setting mAlpha, plus the invalidation
-            // logic is dependent on how the view handles an internal call to onSetAlpha().
-            // We track what kinds of properties are set, and how alpha is handled when it is
-            // set, and perform the invalidation steps appropriately.
-            //boolean alphaHandled = false;
-            //mView.invalidateParentCaches();
-            float fraction = animation.getAnimatedFraction();
-            PropertyBundle propertyBundle = mAnimatorMap.get(animation);
-            int propertyMask = propertyBundle.mPropertyMask;
-            if ((propertyMask & TRANSFORM_MASK) != 0) {
-                View v = mView.get();
-                if (v != null) {
-                    v.invalidate(/*false*/);
-                }
-            }
-            ArrayList<NameValuesHolder> valueList = propertyBundle.mNameValuesHolder;
-            if (valueList != null) {
-                int count = valueList.size();
-                for (int i = 0; i < count; ++i) {
-                    NameValuesHolder values = valueList.get(i);
-                    float value = values.mFromValue + fraction * values.mDeltaValue;
-                    //if (values.mNameConstant == ALPHA) {
-                    //    alphaHandled = mView.setAlphaNoInvalidation(value);
-                    //} else {
-                        setValue(values.mNameConstant, value);
-                    //}
-                }
-            }
-            /*if ((propertyMask & TRANSFORM_MASK) != 0) {
-                mView.mTransformationInfo.mMatrixDirty = true;
-                mView.mPrivateFlags |= View.DRAWN; // force another invalidation
-            }*/
-            // invalidate(false) in all cases except if alphaHandled gets set to true
-            // via the call to setAlphaNoInvalidation(), above
-            View v = mView.get();
-            if (v != null) {
-                v.invalidate(/*alphaHandled*/);
-            }
-        }
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/view/ViewPropertyAnimatorICS.java
+++ /dev/null
@@ -1,298 +0,0 @@
-package com.nineoldandroids.view;
-
-import java.lang.ref.WeakReference;
-
-import android.view.View;
-import android.view.animation.Interpolator;
-import com.nineoldandroids.animation.Animator.AnimatorListener;
-
-class ViewPropertyAnimatorICS extends ViewPropertyAnimator {
-    /**
-     * A value to be returned when the WeakReference holding the native implementation
-     * returns <code>null</code>
-     */
-    private final static long RETURN_WHEN_NULL = -1L;
-
-    /**
-     * A WeakReference holding the native implementation of ViewPropertyAnimator
-     */
-    private final WeakReference<android.view.ViewPropertyAnimator> mNative;
-
-    ViewPropertyAnimatorICS(View view) {
-        mNative = new WeakReference<android.view.ViewPropertyAnimator>(view.animate());
-    }
-
-    @Override
-    public ViewPropertyAnimator setDuration(long duration) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.setDuration(duration);
-        }
-        return this;
-    }
-
-    @Override
-    public long getDuration() {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            return n.getDuration();
-        }
-        return RETURN_WHEN_NULL;
-    }
-
-    @Override
-    public ViewPropertyAnimator setStartDelay(long startDelay) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.setStartDelay(startDelay);
-        }
-        return this;
-    }
-
-    @Override
-    public long getStartDelay() {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            return n.getStartDelay();
-        }
-        return RETURN_WHEN_NULL;
-    }
-
-    @Override
-    public ViewPropertyAnimator setInterpolator(Interpolator interpolator) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.setInterpolator(interpolator);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator setListener(final AnimatorListener listener) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            if (listener == null) {
-                n.setListener(null);
-            } else {
-                n.setListener(new android.animation.Animator.AnimatorListener() {
-                    @Override
-                    public void onAnimationStart(android.animation.Animator animation) {
-                        listener.onAnimationStart(null);
-                    }
-
-                    @Override
-                    public void onAnimationRepeat(android.animation.Animator animation) {
-                        listener.onAnimationRepeat(null);
-                    }
-
-                    @Override
-                    public void onAnimationEnd(android.animation.Animator animation) {
-                        listener.onAnimationEnd(null);
-                    }
-
-                    @Override
-                    public void onAnimationCancel(android.animation.Animator animation) {
-                        listener.onAnimationCancel(null);
-                    }
-                });
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public void start() {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.start();
-        }
-    }
-
-    @Override
-    public void cancel() {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.cancel();
-        }
-    }
-
-    @Override
-    public ViewPropertyAnimator x(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.x(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator xBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.xBy(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator y(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.y(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator yBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.yBy(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotation(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.rotation(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.rotationBy(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationX(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.rotationX(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationXBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.rotationXBy(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationY(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.rotationY(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationYBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.rotationYBy(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator translationX(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.translationX(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator translationXBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.translationXBy(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator translationY(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.translationY(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator translationYBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.translationYBy(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator scaleX(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.scaleX(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator scaleXBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.scaleXBy(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator scaleY(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.scaleY(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator scaleYBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.scaleYBy(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator alpha(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.alpha(value);
-        }
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator alphaBy(float value) {
-        android.view.ViewPropertyAnimator n = mNative.get();
-        if (n != null) {
-            n.alphaBy(value);
-        }
-        return this;
-    }
-}
deleted file mode 100755
--- a/mobile/android/thirdparty/com/nineoldandroids/view/ViewPropertyAnimatorPreHC.java
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.nineoldandroids.view;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Set;
-import android.view.View;
-import android.view.animation.Interpolator;
-import com.nineoldandroids.animation.Animator;
-import com.nineoldandroids.animation.ValueAnimator;
-import com.nineoldandroids.view.animation.AnimatorProxy;
-
-class ViewPropertyAnimatorPreHC extends ViewPropertyAnimator {
-    /**
-     * Proxy animation class which will allow us access to post-Honeycomb properties that were not
-     * otherwise available.
-     */
-    private final AnimatorProxy mProxy;
-
-    /**
-     * A WeakReference holding the View whose properties are being animated by this class. This is
-     * set at construction time.
-     */
-    private final WeakReference<View> mView;
-
-    /**
-     * The duration of the underlying Animator object. By default, we don't set the duration
-     * on the Animator and just use its default duration. If the duration is ever set on this
-     * Animator, then we use the duration that it was set to.
-     */
-    private long mDuration;
-
-    /**
-     * A flag indicating whether the duration has been set on this object. If not, we don't set
-     * the duration on the underlying Animator, but instead just use its default duration.
-     */
-    private boolean mDurationSet = false;
-
-    /**
-     * The startDelay of the underlying Animator object. By default, we don't set the startDelay
-     * on the Animator and just use its default startDelay. If the startDelay is ever set on this
-     * Animator, then we use the startDelay that it was set to.
-     */
-    private long mStartDelay = 0;
-
-    /**
-     * A flag indicating whether the startDelay has been set on this object. If not, we don't set
-     * the startDelay on the underlying Animator, but instead just use its default startDelay.
-     */
-    private boolean mStartDelaySet = false;
-
-    /**
-     * The interpolator of the underlying Animator object. By default, we don't set the interpolator
-     * on the Animator and just use its default interpolator. If the interpolator is ever set on
-     * this Animator, then we use the interpolator that it was set to.
-     */
-    private /*Time*/Interpolator mInterpolator;
-
-    /**
-     * A flag indicating whether the interpolator has been set on this object. If not, we don't set
-     * the interpolator on the underlying Animator, but instead just use its default interpolator.
-     */
-    private boolean mInterpolatorSet = false;
-
-    /**
-     * Listener for the lifecycle events of the underlying
-     */
-    private Animator.AnimatorListener mListener = null;
-
-    /**
-     * This listener is the mechanism by which the underlying Animator causes changes to the
-     * properties currently being animated, as well as the cleanup after an animation is
-     * complete.
-     */
-    private AnimatorEventListener mAnimatorEventListener = new AnimatorEventListener();
-
-    /**
-     * This list holds the properties that have been asked to animate. We allow the caller to
-     * request several animations prior to actually starting the underlying animator. This
-     * enables us to run one single animator to handle several properties in parallel. Each
-     * property is tossed onto the pending list until the animation actually starts (which is
-     * done by posting it onto mView), at which time the pending list is cleared and the properties
-     * on that list are added to the list of properties associated with that animator.
-     */
-    ArrayList<NameValuesHolder> mPendingAnimations = new ArrayList<NameValuesHolder>();
-
-    /**
-     * Constants used to associate a property being requested and the mechanism used to set
-     * the property (this class calls directly into View to set the properties in question).
-     */
-    private static final int NONE           = 0x0000;
-    private static final int TRANSLATION_X  = 0x0001;
-    private static final int TRANSLATION_Y  = 0x0002;
-    private static final int SCALE_X        = 0x0004;
-    private static final int SCALE_Y        = 0x0008;
-    private static final int ROTATION       = 0x0010;
-    private static final int ROTATION_X     = 0x0020;
-    private static final int ROTATION_Y     = 0x0040;
-    private static final int X              = 0x0080;
-    private static final int Y              = 0x0100;
-    private static final int ALPHA          = 0x0200;
-
-    private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | SCALE_X | SCALE_Y |
-            ROTATION | ROTATION_X | ROTATION_Y | X | Y;
-
-    /**
-     * The mechanism by which the user can request several properties that are then animated
-     * together works by posting this Runnable to start the underlying Animator. Every time
-     * a property animation is requested, we cancel any previous postings of the Runnable
-     * and re-post it. This means that we will only ever run the Runnable (and thus start the
-     * underlying animator) after the caller is done setting the properties that should be
-     * animated together.
-     */
-    private Runnable mAnimationStarter = new Runnable() {
-        @Override
-        public void run() {
-            startAnimation();
-        }
-    };
-
-    /**
-     * This class holds information about the overall animation being run on the set of
-     * properties. The mask describes which properties are being animated and the
-     * values holder is the list of all property/value objects.
-     */
-    private static class PropertyBundle {
-        int mPropertyMask;
-        ArrayList<NameValuesHolder> mNameValuesHolder;
-
-        PropertyBundle(int propertyMask, ArrayList<NameValuesHolder> nameValuesHolder) {
-            mPropertyMask = propertyMask;
-            mNameValuesHolder = nameValuesHolder;
-        }
-
-        /**
-         * Removes the given property from being animated as a part of this
-         * PropertyBundle. If the property was a part of this bundle, it returns
-         * true to indicate that it was, in fact, canceled. This is an indication
-         * to the caller that a cancellation actually occurred.
-         *
-         * @param propertyConstant The property whose cancellation is requested.
-         * @return true if the given property is a part of this bundle and if it
-         * has therefore been canceled.
-         */
-        boolean cancel(int propertyConstant) {
-            if ((mPropertyMask & propertyConstant) != 0 && mNameValuesHolder != null) {
-                int count = mNameValuesHolder.size();
-                for (int i = 0; i < count; ++i) {
-                    NameValuesHolder nameValuesHolder = mNameValuesHolder.get(i);
-                    if (nameValuesHolder.mNameConstant == propertyConstant) {
-                        mNameValuesHolder.remove(i);
-                        mPropertyMask &= ~propertyConstant;
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    /**
-     * This list tracks the list of properties being animated by any particular animator.
-     * In most situations, there would only ever be one animator running at a time. But it is
-     * possible to request some properties to animate together, then while those properties
-     * are animating, to request some other properties to animate together. The way that
-     * works is by having this map associate the group of properties being animated with the
-     * animator handling the animation. On every update event for an Animator, we ask the
-     * map for the associated properties and set them accordingly.
-     */
-    private HashMap<Animator, PropertyBundle> mAnimatorMap =
-            new HashMap<Animator, PropertyBundle>();
-
-    /**
-     * This is the information we need to set each property during the animation.
-     * mNameConstant is used to set the appropriate field in View, and the from/delta
-     * values are used to calculate the animated value for a given animation fraction
-     * during the animation.
-     */
-    private static class NameValuesHolder {
-        int mNameConstant;
-        float mFromValue;
-        float mDeltaValue;
-        NameValuesHolder(int nameConstant, float fromValue, float deltaValue) {
-            mNameConstant = nameConstant;
-            mFromValue = fromValue;
-            mDeltaValue = deltaValue;
-        }
-    }
-
-    /**
-     * Constructor, called by View. This is private by design, as the user should only
-     * get a ViewPropertyAnimator by calling View.animate().
-     *
-     * @param view The View associated with this ViewPropertyAnimator
-     */
-    ViewPropertyAnimatorPreHC(View view) {
-        mView = new WeakReference<View>(view);
-        mProxy = AnimatorProxy.wrap(view);
-    }
-
-    /**
-     * Sets the duration for the underlying animator that animates the requested properties.
-     * By default, the animator uses the default value for ValueAnimator. Calling this method
-     * will cause the declared value to be used instead.
-     * @param duration The length of ensuing property animations, in milliseconds. The value
-     * cannot be negative.
-     * @return This object, allowing calls to methods in this class to be chained.
-     */
-    public ViewPropertyAnimator setDuration(long duration) {
-        if (duration < 0) {
-            throw new IllegalArgumentException("Animators cannot have negative duration: " +
-                    duration);
-        }
-        mDurationSet = true;
-        mDuration = duration;
-        return this;
-    }
-
-    /**
-     * Returns the current duration of property animations. If the duration was set on this
-     * object, that value is returned. Otherwise, the default value of the underlying Animator
-     * is returned.
-     *
-     * @see #setDuration(long)
-     * @return The duration of animations, in milliseconds.
-     */
-    public long getDuration() {
-        if (mDurationSet) {
-            return mDuration;
-        } else {
-            // Just return the default from ValueAnimator, since that's what we'd get if
-            // the value has not been set otherwise
-            return new ValueAnimator().getDuration();
-        }
-    }
-
-    @Override
-    public long getStartDelay() {
-        if (mStartDelaySet) {
-            return mStartDelay;
-        } else {
-            // Just return the default from ValueAnimator (0), since that's what we'd get if
-            // the value has not been set otherwise
-            return 0;
-        }
-    }
-
-    @Override
-    public ViewPropertyAnimator setStartDelay(long startDelay) {
-        if (startDelay < 0) {
-            throw new IllegalArgumentException("Animators cannot have negative duration: " +
-                    startDelay);
-        }
-        mStartDelaySet = true;
-        mStartDelay = startDelay;
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator setInterpolator(/*Time*/Interpolator interpolator) {
-        mInterpolatorSet = true;
-        mInterpolator = interpolator;
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator setListener(Animator.AnimatorListener listener) {
-        mListener = listener;
-        return this;
-    }
-
-    @Override
-    public void start() {
-        startAnimation();
-    }
-
-    @Override
-    public void cancel() {
-        if (mAnimatorMap.size() > 0) {
-            HashMap<Animator, PropertyBundle> mAnimatorMapCopy =
-                    (HashMap<Animator, PropertyBundle>)mAnimatorMap.clone();
-            Set<Animator> animatorSet = mAnimatorMapCopy.keySet();
-            for (Animator runningAnim : animatorSet) {
-                runningAnim.cancel();
-            }
-        }
-        mPendingAnimations.clear();
-        View v = mView.get();
-        if (v != null) {
-            v.removeCallbacks(mAnimationStarter);
-        }
-    }
-
-    @Override
-    public ViewPropertyAnimator x(float value) {
-        animateProperty(X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator xBy(float value) {
-        animatePropertyBy(X, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator y(float value) {
-        animateProperty(Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator yBy(float value) {
-        animatePropertyBy(Y, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotation(float value) {
-        animateProperty(ROTATION, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationBy(float value) {
-        animatePropertyBy(ROTATION, value);
-        return this;
-    }
-
-    @Override
-    public ViewPropertyAnimator rotationX(float value) {
-        animateProperty(ROTATION_X, value);