Merge "Fix @links in support docs." into nyc-support-25.1-dev am: f5a0b18193 am: 4cea56ab81 am: e0d616dcef
am: ab2bf78872

Change-Id: I3a3345792db96c91c0e43a27c367e9ea710f4e2d
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index a4645bc..b24c09a 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -3,5 +3,6 @@
   <component name="VcsDirectoryMappings">
     <mapping directory="" vcs="Git" />
     <mapping directory="$PROJECT_DIR$/../../external/doclava" vcs="Git" />
+    <mapping directory="$PROJECT_DIR$/../../external/jdiff" vcs="Git" />
   </component>
-</project>
+</project>
\ No newline at end of file
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 2811ea9..ecc61dd 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,5 +1,5 @@
 [Hook Scripts]
-checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
+checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT} -c ${REPO_ROOT}/frameworks/support/development/checkstyle/config/support-lib.xml -p development/checkstyle/prebuilt/com.android.support.checkstyle.jar
 
 [Builtin Hooks]
 commit_msg_changeid_field = true
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..46cb691
--- /dev/null
+++ b/README.md
@@ -0,0 +1,67 @@
+# AOSP Support Library Contribution Guide
+## Accepted Types of Contributions
+* Bug fixes (needs a corresponding bug report in b.android.com)
+* Each bug fix is expected to come with tests
+* Fixing spelling errors
+* Updating documentation
+* Adding new tests to the area that is not currently covered by tests
+
+We **are not** currently accepting new modules, features, or behavior changes.
+
+## Checking Out the Code
+Follow the [“Downloading the Source”](https://source.android.com/source/downloading.html) guide to install and set up `repo` tool, but instead of running the listed `repo` commands to initialize the repository, run the folowing:
+
+    repo init -u https://android.googlesource.com/platform/manifest -b ub-supportlib-master
+
+Now your repository is set to pull only what you need for building and running support library. Download the code (and grab a coffee while we pull down 10GB):
+
+    repo sync -j8 -c
+
+You will use this command to sync your checkout in the future - it’s similar to `git fetch`
+
+
+## Using Android Studio
+Open `path/to/checkout/frameworks/support/` in Android Studio. Now you're ready edit, run, and test!
+
+If you get “Unregistered VCS root detected” click “Add root” to enable git integration for Android Studio.
+
+If you see any warnings (red underlines) run `Build > Clean Project`.
+
+## Optional - Full Build
+You can do most of your work from Android Studio, however you can also build the full support library from command line:
+
+    cd path/to/checkout/frameworks/support/
+    ./gradlew createArchive
+
+## Running Tests
+
+### Single Test Class or Method
+1. Open the desired test file in Android Studio.
+2. Right-click on a test class or @Test method name and select `Run FooBarTest`
+
+### Full Test Package
+1. In the project side panel open the desired module.
+2. Find the directory with the tests
+3. Right-click on the directory and select `Run android.support.foobar`
+
+## Running Sample Apps
+Support library has a set of Android applications that exercise support library code. These applications can be useful when you want to debug a real running application, or reproduce a problem interactively, before writing test code.
+
+These applications are named support-\*-demos (e.g. support-4v-demos or support-leanback-demos. You can run them by clicking `Run > Run ...` and choosing the desired application.
+
+## Making a change
+    cd path/to/checkout/frameworks/support/
+    repo start my_branch_name .
+    (make needed modifications)
+    git commit -a
+    repo upload --current-branch .
+
+If you see the following prompt, choose `always`:
+
+    Run hook scripts from https://android.googlesource.com/platform/manifest (yes/always/NO)?
+
+## Getting reviewed
+* After you run repo upload, open [r.android.com](http://r.android.com)
+* Sign in into your account (or create one if you do not have one yet)
+* Add an appropriate reviewer (use git log to find who did most modifications on the file you are fixing)
+
diff --git a/annotations/build.gradle b/annotations/build.gradle
index 4907e2a..6071820 100644
--- a/annotations/build.gradle
+++ b/annotations/build.gradle
@@ -1,14 +1,14 @@
 apply plugin: 'java'
-sourceCompatibility = JavaVersion.VERSION_1_7
-targetCompatibility = JavaVersion.VERSION_1_7
 archivesBaseName = 'support-annotations'
 
 sourceSets {
     main.java.srcDir 'src'
 }
 
-sourceCompatibility = JavaVersion.VERSION_1_7
-targetCompatibility = JavaVersion.VERSION_1_7
+compileJava {
+    sourceCompatibility = JavaVersion.VERSION_1_7
+    targetCompatibility = JavaVersion.VERSION_1_7
+}
 
 jar {
     from sourceSets.main.output
diff --git a/annotations/src/android/support/annotation/ColorLong.java b/annotations/src/android/support/annotation/ColorLong.java
new file mode 100644
index 0000000..bb78138
--- /dev/null
+++ b/annotations/src/android/support/annotation/ColorLong.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Denotes that the annotated element represents a packed color
+ * long. If applied to a long array, every element in the array
+ * represents a color long. For more information on how colors
+ * are packed in a long, please refer to the documentation of
+ * the {@link android.graphics.Color} class.</p>
+ *
+ * <p>Example:</p>
+ *
+ * <pre>{@code
+ *  public void setFillColor(@ColorLong long color);
+ * }</pre>
+ *
+ * @see android.graphics.Color
+ */
+@Retention(SOURCE)
+@Target({PARAMETER, METHOD, LOCAL_VARIABLE, FIELD})
+public @interface ColorLong {
+}
diff --git a/annotations/src/android/support/annotation/HalfFloat.java b/annotations/src/android/support/annotation/HalfFloat.java
new file mode 100644
index 0000000..a01f05c
--- /dev/null
+++ b/annotations/src/android/support/annotation/HalfFloat.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * <p>Denotes that the annotated element represents a half-precision floating point
+ * value. Such values are stored in short data types and can be manipulated with
+ * the {@link android.util.Half} class. If applied to an array of short, every
+ * element in the array represents a half-precision float.</p>
+ *
+ * <p>Example:</p>
+ *
+ * <pre>{@code
+ * public abstract void setPosition(@HalfFloat short x, @HalfFloat short y, @HalfFloat short z);
+ * }</pre>
+ *
+ * @see android.util.Half
+ * @see android.util.Half#valueOf(float)
+ * @see android.util.Half#toFloat(short)
+ */
+@Retention(SOURCE)
+@Target({PARAMETER, METHOD, LOCAL_VARIABLE, FIELD})
+public @interface HalfFloat {
+}
diff --git a/api/26.0.0.txt b/api/26.0.0.txt
new file mode 100644
index 0000000..75f4a99
--- /dev/null
+++ b/api/26.0.0.txt
@@ -0,0 +1,10850 @@
+package android.support.app.recommendation {
+
+  public final class ContentRecommendation {
+    method public java.lang.String getBackgroundImageUri();
+    method public int getBadgeImageResourceId();
+    method public int getColor();
+    method public android.graphics.Bitmap getContentImage();
+    method public android.support.app.recommendation.ContentRecommendation.IntentData getContentIntent();
+    method public java.lang.String[] getContentTypes();
+    method public android.support.app.recommendation.ContentRecommendation.IntentData getDismissIntent();
+    method public java.lang.String[] getGenres();
+    method public java.lang.String getGroup();
+    method public java.lang.String getIdTag();
+    method public java.lang.String getMaturityRating();
+    method public android.app.Notification getNotificationObject(android.content.Context);
+    method public java.lang.String getPricingType();
+    method public java.lang.String getPricingValue();
+    method public java.lang.String getPrimaryContentType();
+    method public int getProgressMax();
+    method public int getProgressValue();
+    method public long getRunningTime();
+    method public java.lang.String getSortKey();
+    method public java.lang.String getSourceName();
+    method public int getStatus();
+    method public java.lang.String getText();
+    method public java.lang.String getTitle();
+    method public boolean hasProgressInfo();
+    method public boolean isAutoDismiss();
+    method public void setAutoDismiss(boolean);
+    method public void setGroup(java.lang.String);
+    method public void setProgress(int, int);
+    method public void setSortKey(java.lang.String);
+    method public void setStatus(int);
+    field public static final java.lang.String CONTENT_MATURITY_ALL = "android.contentMaturity.all";
+    field public static final java.lang.String CONTENT_MATURITY_HIGH = "android.contentMaturity.high";
+    field public static final java.lang.String CONTENT_MATURITY_LOW = "android.contentMaturity.low";
+    field public static final java.lang.String CONTENT_MATURITY_MEDIUM = "android.contentMaturity.medium";
+    field public static final java.lang.String CONTENT_PRICING_FREE = "android.contentPrice.free";
+    field public static final java.lang.String CONTENT_PRICING_PREORDER = "android.contentPrice.preorder";
+    field public static final java.lang.String CONTENT_PRICING_PURCHASE = "android.contentPrice.purchase";
+    field public static final java.lang.String CONTENT_PRICING_RENTAL = "android.contentPrice.rental";
+    field public static final java.lang.String CONTENT_PRICING_SUBSCRIPTION = "android.contentPrice.subscription";
+    field public static final int CONTENT_STATUS_AVAILABLE = 2; // 0x2
+    field public static final int CONTENT_STATUS_PENDING = 1; // 0x1
+    field public static final int CONTENT_STATUS_READY = 0; // 0x0
+    field public static final int CONTENT_STATUS_UNAVAILABLE = 3; // 0x3
+    field public static final java.lang.String CONTENT_TYPE_APP = "android.contentType.app";
+    field public static final java.lang.String CONTENT_TYPE_BOOK = "android.contentType.book";
+    field public static final java.lang.String CONTENT_TYPE_COMIC = "android.contentType.comic";
+    field public static final java.lang.String CONTENT_TYPE_GAME = "android.contentType.game";
+    field public static final java.lang.String CONTENT_TYPE_MAGAZINE = "android.contentType.magazine";
+    field public static final java.lang.String CONTENT_TYPE_MOVIE = "android.contentType.movie";
+    field public static final java.lang.String CONTENT_TYPE_MUSIC = "android.contentType.music";
+    field public static final java.lang.String CONTENT_TYPE_NEWS = "android.contentType.news";
+    field public static final java.lang.String CONTENT_TYPE_PODCAST = "android.contentType.podcast";
+    field public static final java.lang.String CONTENT_TYPE_RADIO = "android.contentType.radio";
+    field public static final java.lang.String CONTENT_TYPE_SERIAL = "android.contentType.serial";
+    field public static final java.lang.String CONTENT_TYPE_SPORTS = "android.contentType.sports";
+    field public static final java.lang.String CONTENT_TYPE_TRAILER = "android.contentType.trailer";
+    field public static final java.lang.String CONTENT_TYPE_VIDEO = "android.contentType.video";
+    field public static final java.lang.String CONTENT_TYPE_WEBSITE = "android.contentType.website";
+    field public static final int INTENT_TYPE_ACTIVITY = 1; // 0x1
+    field public static final int INTENT_TYPE_BROADCAST = 2; // 0x2
+    field public static final int INTENT_TYPE_SERVICE = 3; // 0x3
+  }
+
+  public static final class ContentRecommendation.Builder {
+    ctor public ContentRecommendation.Builder();
+    method public android.support.app.recommendation.ContentRecommendation build();
+    method public android.support.app.recommendation.ContentRecommendation.Builder setAutoDismiss(boolean);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setBackgroundImageUri(java.lang.String);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setBadgeIcon(int);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setColor(int);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setContentImage(android.graphics.Bitmap);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setContentIntentData(int, android.content.Intent, int, android.os.Bundle);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setContentTypes(java.lang.String[]);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setDismissIntentData(int, android.content.Intent, int, android.os.Bundle);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setGenres(java.lang.String[]);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setGroup(java.lang.String);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setIdTag(java.lang.String);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setMaturityRating(java.lang.String);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setPricingInformation(java.lang.String, java.lang.String);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setProgress(int, int);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setRunningTime(long);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setSortKey(java.lang.String);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setSourceName(java.lang.String);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setStatus(int);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setText(java.lang.String);
+    method public android.support.app.recommendation.ContentRecommendation.Builder setTitle(java.lang.String);
+  }
+
+  public static abstract class ContentRecommendation.ContentMaturity implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract class ContentRecommendation.ContentPricing implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract class ContentRecommendation.ContentStatus implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract class ContentRecommendation.ContentType implements java.lang.annotation.Annotation {
+  }
+
+  public static class ContentRecommendation.IntentData {
+    ctor public ContentRecommendation.IntentData();
+  }
+
+  public static abstract class ContentRecommendation.IntentType implements java.lang.annotation.Annotation {
+  }
+
+  public final class RecommendationExtender implements android.app.Notification.Extender {
+    ctor public RecommendationExtender();
+    ctor public RecommendationExtender(android.app.Notification);
+    method public android.app.Notification.Builder extend(android.app.Notification.Builder);
+    method public java.lang.String[] getContentTypes();
+    method public java.lang.String[] getGenres();
+    method public java.lang.String getMaturityRating();
+    method public java.lang.String getPricingType();
+    method public java.lang.String getPricingValue();
+    method public java.lang.String getPrimaryContentType();
+    method public long getRunningTime();
+    method public int getStatus();
+    method public android.support.app.recommendation.RecommendationExtender setContentTypes(java.lang.String[]);
+    method public android.support.app.recommendation.RecommendationExtender setGenres(java.lang.String[]);
+    method public android.support.app.recommendation.RecommendationExtender setMaturityRating(java.lang.String);
+    method public android.support.app.recommendation.RecommendationExtender setPricingInformation(java.lang.String, java.lang.String);
+    method public android.support.app.recommendation.RecommendationExtender setRunningTime(long);
+    method public android.support.app.recommendation.RecommendationExtender setStatus(int);
+  }
+
+}
+
+package android.support.customtabs {
+
+  public class CustomTabsCallback {
+    ctor public CustomTabsCallback();
+    method public void extraCallback(java.lang.String, android.os.Bundle);
+    method public void onNavigationEvent(int, android.os.Bundle);
+    field public static final int NAVIGATION_ABORTED = 4; // 0x4
+    field public static final int NAVIGATION_FAILED = 3; // 0x3
+    field public static final int NAVIGATION_FINISHED = 2; // 0x2
+    field public static final int NAVIGATION_STARTED = 1; // 0x1
+    field public static final int TAB_HIDDEN = 6; // 0x6
+    field public static final int TAB_SHOWN = 5; // 0x5
+  }
+
+  public class CustomTabsClient {
+    method public static boolean bindCustomTabsService(android.content.Context, java.lang.String, android.support.customtabs.CustomTabsServiceConnection);
+    method public static boolean connectAndInitialize(android.content.Context, java.lang.String);
+    method public android.os.Bundle extraCommand(java.lang.String, android.os.Bundle);
+    method public static java.lang.String getPackageName(android.content.Context, java.util.List<java.lang.String>);
+    method public static java.lang.String getPackageName(android.content.Context, java.util.List<java.lang.String>, boolean);
+    method public android.support.customtabs.CustomTabsSession newSession(android.support.customtabs.CustomTabsCallback);
+    method public boolean warmup(long);
+  }
+
+  public final class CustomTabsIntent {
+    method public static int getMaxToolbarItems();
+    method public void launchUrl(android.content.Context, android.net.Uri);
+    method public static android.content.Intent setAlwaysUseBrowserUI(android.content.Intent);
+    method public static boolean shouldAlwaysUseBrowserUI(android.content.Intent);
+    field public static final java.lang.String EXTRA_ACTION_BUTTON_BUNDLE = "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
+    field public static final java.lang.String EXTRA_CLOSE_BUTTON_ICON = "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
+    field public static final java.lang.String EXTRA_DEFAULT_SHARE_MENU_ITEM = "android.support.customtabs.extra.SHARE_MENU_ITEM";
+    field public static final java.lang.String EXTRA_ENABLE_INSTANT_APPS = "android.support.customtabs.extra.EXTRA_ENABLE_INSTANT_APPS";
+    field public static final java.lang.String EXTRA_ENABLE_URLBAR_HIDING = "android.support.customtabs.extra.ENABLE_URLBAR_HIDING";
+    field public static final java.lang.String EXTRA_EXIT_ANIMATION_BUNDLE = "android.support.customtabs.extra.EXIT_ANIMATION_BUNDLE";
+    field public static final java.lang.String EXTRA_MENU_ITEMS = "android.support.customtabs.extra.MENU_ITEMS";
+    field public static final java.lang.String EXTRA_REMOTEVIEWS = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS";
+    field public static final java.lang.String EXTRA_REMOTEVIEWS_CLICKED_ID = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_CLICKED_ID";
+    field public static final java.lang.String EXTRA_REMOTEVIEWS_PENDINGINTENT = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_PENDINGINTENT";
+    field public static final java.lang.String EXTRA_REMOTEVIEWS_VIEW_IDS = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_VIEW_IDS";
+    field public static final java.lang.String EXTRA_SECONDARY_TOOLBAR_COLOR = "android.support.customtabs.extra.SECONDARY_TOOLBAR_COLOR";
+    field public static final java.lang.String EXTRA_SESSION = "android.support.customtabs.extra.SESSION";
+    field public static final java.lang.String EXTRA_TINT_ACTION_BUTTON = "android.support.customtabs.extra.TINT_ACTION_BUTTON";
+    field public static final java.lang.String EXTRA_TITLE_VISIBILITY_STATE = "android.support.customtabs.extra.TITLE_VISIBILITY";
+    field public static final java.lang.String EXTRA_TOOLBAR_COLOR = "android.support.customtabs.extra.TOOLBAR_COLOR";
+    field public static final java.lang.String EXTRA_TOOLBAR_ITEMS = "android.support.customtabs.extra.TOOLBAR_ITEMS";
+    field public static final java.lang.String KEY_DESCRIPTION = "android.support.customtabs.customaction.DESCRIPTION";
+    field public static final java.lang.String KEY_ICON = "android.support.customtabs.customaction.ICON";
+    field public static final java.lang.String KEY_ID = "android.support.customtabs.customaction.ID";
+    field public static final java.lang.String KEY_MENU_ITEM_TITLE = "android.support.customtabs.customaction.MENU_ITEM_TITLE";
+    field public static final java.lang.String KEY_PENDING_INTENT = "android.support.customtabs.customaction.PENDING_INTENT";
+    field public static final int NO_TITLE = 0; // 0x0
+    field public static final int SHOW_PAGE_TITLE = 1; // 0x1
+    field public static final int TOOLBAR_ACTION_BUTTON_ID = 0; // 0x0
+    field public final android.content.Intent intent;
+    field public final android.os.Bundle startAnimationBundle;
+  }
+
+  public static final class CustomTabsIntent.Builder {
+    ctor public CustomTabsIntent.Builder();
+    ctor public CustomTabsIntent.Builder(android.support.customtabs.CustomTabsSession);
+    method public android.support.customtabs.CustomTabsIntent.Builder addDefaultShareMenuItem();
+    method public android.support.customtabs.CustomTabsIntent.Builder addMenuItem(java.lang.String, android.app.PendingIntent);
+    method public deprecated android.support.customtabs.CustomTabsIntent.Builder addToolbarItem(int, android.graphics.Bitmap, java.lang.String, android.app.PendingIntent) throws java.lang.IllegalStateException;
+    method public android.support.customtabs.CustomTabsIntent build();
+    method public android.support.customtabs.CustomTabsIntent.Builder enableUrlBarHiding();
+    method public android.support.customtabs.CustomTabsIntent.Builder setActionButton(android.graphics.Bitmap, java.lang.String, android.app.PendingIntent, boolean);
+    method public android.support.customtabs.CustomTabsIntent.Builder setActionButton(android.graphics.Bitmap, java.lang.String, android.app.PendingIntent);
+    method public android.support.customtabs.CustomTabsIntent.Builder setCloseButtonIcon(android.graphics.Bitmap);
+    method public android.support.customtabs.CustomTabsIntent.Builder setExitAnimations(android.content.Context, int, int);
+    method public android.support.customtabs.CustomTabsIntent.Builder setInstantAppsEnabled(boolean);
+    method public android.support.customtabs.CustomTabsIntent.Builder setSecondaryToolbarColor(int);
+    method public android.support.customtabs.CustomTabsIntent.Builder setSecondaryToolbarViews(android.widget.RemoteViews, int[], android.app.PendingIntent);
+    method public android.support.customtabs.CustomTabsIntent.Builder setShowTitle(boolean);
+    method public android.support.customtabs.CustomTabsIntent.Builder setStartAnimations(android.content.Context, int, int);
+    method public android.support.customtabs.CustomTabsIntent.Builder setToolbarColor(int);
+  }
+
+  public abstract class CustomTabsService extends android.app.Service {
+    ctor public CustomTabsService();
+    method protected boolean cleanUpSession(android.support.customtabs.CustomTabsSessionToken);
+    method protected abstract android.os.Bundle extraCommand(java.lang.String, android.os.Bundle);
+    method protected abstract boolean mayLaunchUrl(android.support.customtabs.CustomTabsSessionToken, android.net.Uri, android.os.Bundle, java.util.List<android.os.Bundle>);
+    method protected abstract boolean newSession(android.support.customtabs.CustomTabsSessionToken);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method protected abstract boolean updateVisuals(android.support.customtabs.CustomTabsSessionToken, android.os.Bundle);
+    method protected abstract boolean warmup(long);
+    field public static final java.lang.String ACTION_CUSTOM_TABS_CONNECTION = "android.support.customtabs.action.CustomTabsService";
+    field public static final java.lang.String KEY_URL = "android.support.customtabs.otherurls.URL";
+  }
+
+  public abstract class CustomTabsServiceConnection implements android.content.ServiceConnection {
+    ctor public CustomTabsServiceConnection();
+    method public abstract void onCustomTabsServiceConnected(android.content.ComponentName, android.support.customtabs.CustomTabsClient);
+    method public final void onServiceConnected(android.content.ComponentName, android.os.IBinder);
+  }
+
+  public final class CustomTabsSession {
+    method public boolean mayLaunchUrl(android.net.Uri, android.os.Bundle, java.util.List<android.os.Bundle>);
+    method public boolean setActionButton(android.graphics.Bitmap, java.lang.String);
+    method public boolean setSecondaryToolbarViews(android.widget.RemoteViews, int[], android.app.PendingIntent);
+    method public deprecated boolean setToolbarItem(int, android.graphics.Bitmap, java.lang.String);
+  }
+
+  public class CustomTabsSessionToken {
+    method public android.support.customtabs.CustomTabsCallback getCallback();
+    method public static android.support.customtabs.CustomTabsSessionToken getSessionTokenFromIntent(android.content.Intent);
+  }
+
+}
+
+package android.support.design.widget {
+
+  public class AppBarLayout extends android.widget.LinearLayout {
+    ctor public AppBarLayout(android.content.Context);
+    ctor public AppBarLayout(android.content.Context, android.util.AttributeSet);
+    method public void addOnOffsetChangedListener(android.support.design.widget.AppBarLayout.OnOffsetChangedListener);
+    method public deprecated float getTargetElevation();
+    method public final int getTotalScrollRange();
+    method public void removeOnOffsetChangedListener(android.support.design.widget.AppBarLayout.OnOffsetChangedListener);
+    method public void setExpanded(boolean);
+    method public void setExpanded(boolean, boolean);
+    method public deprecated void setTargetElevation(float);
+  }
+
+  public static class AppBarLayout.Behavior extends android.support.design.widget.HeaderBehavior {
+    ctor public AppBarLayout.Behavior();
+    ctor public AppBarLayout.Behavior(android.content.Context, android.util.AttributeSet);
+    method public boolean onLayoutChild(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, int);
+    method public boolean onMeasureChild(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, int, int, int, int);
+    method public boolean onNestedFling(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View, float, float, boolean);
+    method public void onNestedPreScroll(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View, int, int, int[]);
+    method public void onNestedScroll(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View, int, int, int, int);
+    method public void onRestoreInstanceState(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.os.Parcelable);
+    method public android.os.Parcelable onSaveInstanceState(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout);
+    method public boolean onStartNestedScroll(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View, android.view.View, int);
+    method public void onStopNestedScroll(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View);
+    method public void setDragCallback(android.support.design.widget.AppBarLayout.Behavior.DragCallback);
+  }
+
+  public static abstract class AppBarLayout.Behavior.DragCallback {
+    ctor public AppBarLayout.Behavior.DragCallback();
+    method public abstract boolean canDrag(android.support.design.widget.AppBarLayout);
+  }
+
+  protected static class AppBarLayout.Behavior.SavedState extends android.support.v4.view.AbsSavedState {
+    ctor public AppBarLayout.Behavior.SavedState(android.os.Parcel, java.lang.ClassLoader);
+    ctor public AppBarLayout.Behavior.SavedState(android.os.Parcelable);
+    field public static final android.os.Parcelable.Creator<android.support.design.widget.AppBarLayout.Behavior.SavedState> CREATOR;
+  }
+
+  public static class AppBarLayout.LayoutParams extends android.widget.LinearLayout.LayoutParams {
+    ctor public AppBarLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public AppBarLayout.LayoutParams(int, int);
+    ctor public AppBarLayout.LayoutParams(int, int, float);
+    ctor public AppBarLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public AppBarLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public AppBarLayout.LayoutParams(android.widget.LinearLayout.LayoutParams);
+    ctor public AppBarLayout.LayoutParams(android.support.design.widget.AppBarLayout.LayoutParams);
+    method public int getScrollFlags();
+    method public android.view.animation.Interpolator getScrollInterpolator();
+    method public void setScrollFlags(int);
+    method public void setScrollInterpolator(android.view.animation.Interpolator);
+    field public static final int SCROLL_FLAG_ENTER_ALWAYS = 4; // 0x4
+    field public static final int SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED = 8; // 0x8
+    field public static final int SCROLL_FLAG_EXIT_UNTIL_COLLAPSED = 2; // 0x2
+    field public static final int SCROLL_FLAG_SCROLL = 1; // 0x1
+    field public static final int SCROLL_FLAG_SNAP = 16; // 0x10
+  }
+
+  public static abstract interface AppBarLayout.OnOffsetChangedListener {
+    method public abstract void onOffsetChanged(android.support.design.widget.AppBarLayout, int);
+  }
+
+  public static class AppBarLayout.ScrollingViewBehavior extends android.support.design.widget.HeaderScrollingViewBehavior {
+    ctor public AppBarLayout.ScrollingViewBehavior();
+    ctor public AppBarLayout.ScrollingViewBehavior(android.content.Context, android.util.AttributeSet);
+    method public boolean layoutDependsOn(android.support.design.widget.CoordinatorLayout, android.view.View, android.view.View);
+    method public boolean onDependentViewChanged(android.support.design.widget.CoordinatorLayout, android.view.View, android.view.View);
+    method public boolean onRequestChildRectangleOnScreen(android.support.design.widget.CoordinatorLayout, android.view.View, android.graphics.Rect, boolean);
+  }
+
+  public abstract class BaseTransientBottomBar<B extends android.support.design.widget.BaseTransientBottomBar<B>> {
+    ctor protected BaseTransientBottomBar(android.view.ViewGroup, android.view.View, android.support.design.widget.BaseTransientBottomBar.ContentViewCallback);
+    method public B addCallback(android.support.design.widget.BaseTransientBottomBar.BaseCallback<B>);
+    method public void dismiss();
+    method public android.content.Context getContext();
+    method public int getDuration();
+    method public android.view.View getView();
+    method public boolean isShown();
+    method public boolean isShownOrQueued();
+    method public B removeCallback(android.support.design.widget.BaseTransientBottomBar.BaseCallback<B>);
+    method public deprecated B setCallback(android.support.design.widget.BaseTransientBottomBar.BaseCallback<B>);
+    method public B setDuration(int);
+    method public void show();
+    field public static final int LENGTH_INDEFINITE = -2; // 0xfffffffe
+    field public static final int LENGTH_LONG = 0; // 0x0
+    field public static final int LENGTH_SHORT = -1; // 0xffffffff
+  }
+
+  public static abstract class BaseTransientBottomBar.BaseCallback<B> {
+    ctor public BaseTransientBottomBar.BaseCallback();
+    method public void onDismissed(B, int);
+    method public void onShown(B);
+    field public static final int DISMISS_EVENT_ACTION = 1; // 0x1
+    field public static final int DISMISS_EVENT_CONSECUTIVE = 4; // 0x4
+    field public static final int DISMISS_EVENT_MANUAL = 3; // 0x3
+    field public static final int DISMISS_EVENT_SWIPE = 0; // 0x0
+    field public static final int DISMISS_EVENT_TIMEOUT = 2; // 0x2
+  }
+
+  public static abstract interface BaseTransientBottomBar.ContentViewCallback {
+    method public abstract void animateContentIn(int, int);
+    method public abstract void animateContentOut(int, int);
+  }
+
+  public class BottomNavigationView extends android.widget.FrameLayout {
+    ctor public BottomNavigationView(android.content.Context);
+    ctor public BottomNavigationView(android.content.Context, android.util.AttributeSet);
+    ctor public BottomNavigationView(android.content.Context, android.util.AttributeSet, int);
+    method public int getItemBackgroundResource();
+    method public android.content.res.ColorStateList getItemIconTintList();
+    method public android.content.res.ColorStateList getItemTextColor();
+    method public int getMaxItemCount();
+    method public android.view.Menu getMenu();
+    method public void inflateMenu(int);
+    method public void setItemBackgroundResource(int);
+    method public void setItemIconTintList(android.content.res.ColorStateList);
+    method public void setItemTextColor(android.content.res.ColorStateList);
+    method public void setOnNavigationItemSelectedListener(android.support.design.widget.BottomNavigationView.OnNavigationItemSelectedListener);
+  }
+
+  public static abstract interface BottomNavigationView.OnNavigationItemSelectedListener {
+    method public abstract boolean onNavigationItemSelected(android.view.MenuItem);
+  }
+
+  public class BottomSheetBehavior<V extends android.view.View> extends android.support.design.widget.CoordinatorLayout.Behavior {
+    ctor public BottomSheetBehavior();
+    ctor public BottomSheetBehavior(android.content.Context, android.util.AttributeSet);
+    method public static <V extends android.view.View> android.support.design.widget.BottomSheetBehavior<V> from(V);
+    method public final int getPeekHeight();
+    method public boolean getSkipCollapsed();
+    method public final int getState();
+    method public boolean isHideable();
+    method public void setBottomSheetCallback(android.support.design.widget.BottomSheetBehavior.BottomSheetCallback);
+    method public void setHideable(boolean);
+    method public final void setPeekHeight(int);
+    method public void setSkipCollapsed(boolean);
+    method public final void setState(int);
+    field public static final int PEEK_HEIGHT_AUTO = -1; // 0xffffffff
+    field public static final int STATE_COLLAPSED = 4; // 0x4
+    field public static final int STATE_DRAGGING = 1; // 0x1
+    field public static final int STATE_EXPANDED = 3; // 0x3
+    field public static final int STATE_HIDDEN = 5; // 0x5
+    field public static final int STATE_SETTLING = 2; // 0x2
+  }
+
+  public static abstract class BottomSheetBehavior.BottomSheetCallback {
+    ctor public BottomSheetBehavior.BottomSheetCallback();
+    method public abstract void onSlide(android.view.View, float);
+    method public abstract void onStateChanged(android.view.View, int);
+  }
+
+  protected static class BottomSheetBehavior.SavedState extends android.support.v4.view.AbsSavedState {
+    ctor public BottomSheetBehavior.SavedState(android.os.Parcel);
+    ctor public BottomSheetBehavior.SavedState(android.os.Parcel, java.lang.ClassLoader);
+    ctor public BottomSheetBehavior.SavedState(android.os.Parcelable, int);
+    field public static final android.os.Parcelable.Creator<android.support.design.widget.BottomSheetBehavior.SavedState> CREATOR;
+  }
+
+  public class BottomSheetDialog extends android.support.v7.app.AppCompatDialog {
+    ctor public BottomSheetDialog(android.content.Context);
+    ctor public BottomSheetDialog(android.content.Context, int);
+    ctor protected BottomSheetDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener);
+  }
+
+  public class BottomSheetDialogFragment extends android.support.v7.app.AppCompatDialogFragment {
+    ctor public BottomSheetDialogFragment();
+  }
+
+  public class CollapsingToolbarLayout extends android.widget.FrameLayout {
+    ctor public CollapsingToolbarLayout(android.content.Context);
+    ctor public CollapsingToolbarLayout(android.content.Context, android.util.AttributeSet);
+    ctor public CollapsingToolbarLayout(android.content.Context, android.util.AttributeSet, int);
+    method public int getCollapsedTitleGravity();
+    method public android.graphics.Typeface getCollapsedTitleTypeface();
+    method public android.graphics.drawable.Drawable getContentScrim();
+    method public int getExpandedTitleGravity();
+    method public int getExpandedTitleMarginBottom();
+    method public int getExpandedTitleMarginEnd();
+    method public int getExpandedTitleMarginStart();
+    method public int getExpandedTitleMarginTop();
+    method public android.graphics.Typeface getExpandedTitleTypeface();
+    method public long getScrimAnimationDuration();
+    method public int getScrimVisibleHeightTrigger();
+    method public android.graphics.drawable.Drawable getStatusBarScrim();
+    method public java.lang.CharSequence getTitle();
+    method public boolean isTitleEnabled();
+    method public void setCollapsedTitleGravity(int);
+    method public void setCollapsedTitleTextAppearance(int);
+    method public void setCollapsedTitleTextColor(int);
+    method public void setCollapsedTitleTextColor(android.content.res.ColorStateList);
+    method public void setCollapsedTitleTypeface(android.graphics.Typeface);
+    method public void setContentScrim(android.graphics.drawable.Drawable);
+    method public void setContentScrimColor(int);
+    method public void setContentScrimResource(int);
+    method public void setExpandedTitleColor(int);
+    method public void setExpandedTitleGravity(int);
+    method public void setExpandedTitleMargin(int, int, int, int);
+    method public void setExpandedTitleMarginBottom(int);
+    method public void setExpandedTitleMarginEnd(int);
+    method public void setExpandedTitleMarginStart(int);
+    method public void setExpandedTitleMarginTop(int);
+    method public void setExpandedTitleTextAppearance(int);
+    method public void setExpandedTitleTextColor(android.content.res.ColorStateList);
+    method public void setExpandedTitleTypeface(android.graphics.Typeface);
+    method public void setScrimAnimationDuration(long);
+    method public void setScrimVisibleHeightTrigger(int);
+    method public void setScrimsShown(boolean);
+    method public void setScrimsShown(boolean, boolean);
+    method public void setStatusBarScrim(android.graphics.drawable.Drawable);
+    method public void setStatusBarScrimColor(int);
+    method public void setStatusBarScrimResource(int);
+    method public void setTitle(java.lang.CharSequence);
+    method public void setTitleEnabled(boolean);
+  }
+
+  public static class CollapsingToolbarLayout.LayoutParams extends android.widget.FrameLayout.LayoutParams {
+    ctor public CollapsingToolbarLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public CollapsingToolbarLayout.LayoutParams(int, int);
+    ctor public CollapsingToolbarLayout.LayoutParams(int, int, int);
+    ctor public CollapsingToolbarLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public CollapsingToolbarLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public CollapsingToolbarLayout.LayoutParams(android.widget.FrameLayout.LayoutParams);
+    method public int getCollapseMode();
+    method public float getParallaxMultiplier();
+    method public void setCollapseMode(int);
+    method public void setParallaxMultiplier(float);
+    field public static final int COLLAPSE_MODE_OFF = 0; // 0x0
+    field public static final int COLLAPSE_MODE_PARALLAX = 2; // 0x2
+    field public static final int COLLAPSE_MODE_PIN = 1; // 0x1
+  }
+
+  public class CoordinatorLayout extends android.view.ViewGroup implements android.support.v4.view.NestedScrollingParent {
+    ctor public CoordinatorLayout(android.content.Context);
+    ctor public CoordinatorLayout(android.content.Context, android.util.AttributeSet);
+    ctor public CoordinatorLayout(android.content.Context, android.util.AttributeSet, int);
+    method public void dispatchDependentViewsChanged(android.view.View);
+    method public boolean doViewsOverlap(android.view.View, android.view.View);
+    method public java.util.List<android.view.View> getDependencies(android.view.View);
+    method public java.util.List<android.view.View> getDependents(android.view.View);
+    method public android.graphics.drawable.Drawable getStatusBarBackground();
+    method public boolean isPointInChildBounds(android.view.View, int, int);
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
+    method public void onDraw(android.graphics.Canvas);
+    method protected void onLayout(boolean, int, int, int, int);
+    method public void onLayoutChild(android.view.View, int);
+    method public void onMeasureChild(android.view.View, int, int, int, int);
+    method public void setStatusBarBackground(android.graphics.drawable.Drawable);
+    method public void setStatusBarBackgroundColor(int);
+    method public void setStatusBarBackgroundResource(int);
+  }
+
+  public static abstract class CoordinatorLayout.Behavior<V extends android.view.View> {
+    ctor public CoordinatorLayout.Behavior();
+    ctor public CoordinatorLayout.Behavior(android.content.Context, android.util.AttributeSet);
+    method public boolean blocksInteractionBelow(android.support.design.widget.CoordinatorLayout, V);
+    method public boolean getInsetDodgeRect(android.support.design.widget.CoordinatorLayout, V, android.graphics.Rect);
+    method public int getScrimColor(android.support.design.widget.CoordinatorLayout, V);
+    method public float getScrimOpacity(android.support.design.widget.CoordinatorLayout, V);
+    method public static java.lang.Object getTag(android.view.View);
+    method public deprecated boolean isDirty(android.support.design.widget.CoordinatorLayout, V);
+    method public boolean layoutDependsOn(android.support.design.widget.CoordinatorLayout, V, android.view.View);
+    method public android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.support.design.widget.CoordinatorLayout, V, android.support.v4.view.WindowInsetsCompat);
+    method public void onAttachedToLayoutParams(android.support.design.widget.CoordinatorLayout.LayoutParams);
+    method public boolean onDependentViewChanged(android.support.design.widget.CoordinatorLayout, V, android.view.View);
+    method public void onDependentViewRemoved(android.support.design.widget.CoordinatorLayout, V, android.view.View);
+    method public void onDetachedFromLayoutParams();
+    method public boolean onInterceptTouchEvent(android.support.design.widget.CoordinatorLayout, V, android.view.MotionEvent);
+    method public boolean onLayoutChild(android.support.design.widget.CoordinatorLayout, V, int);
+    method public boolean onMeasureChild(android.support.design.widget.CoordinatorLayout, V, int, int, int, int);
+    method public boolean onNestedFling(android.support.design.widget.CoordinatorLayout, V, android.view.View, float, float, boolean);
+    method public boolean onNestedPreFling(android.support.design.widget.CoordinatorLayout, V, android.view.View, float, float);
+    method public void onNestedPreScroll(android.support.design.widget.CoordinatorLayout, V, android.view.View, int, int, int[]);
+    method public void onNestedScroll(android.support.design.widget.CoordinatorLayout, V, android.view.View, int, int, int, int);
+    method public void onNestedScrollAccepted(android.support.design.widget.CoordinatorLayout, V, android.view.View, android.view.View, int);
+    method public boolean onRequestChildRectangleOnScreen(android.support.design.widget.CoordinatorLayout, V, android.graphics.Rect, boolean);
+    method public void onRestoreInstanceState(android.support.design.widget.CoordinatorLayout, V, android.os.Parcelable);
+    method public android.os.Parcelable onSaveInstanceState(android.support.design.widget.CoordinatorLayout, V);
+    method public boolean onStartNestedScroll(android.support.design.widget.CoordinatorLayout, V, android.view.View, android.view.View, int);
+    method public void onStopNestedScroll(android.support.design.widget.CoordinatorLayout, V, android.view.View);
+    method public boolean onTouchEvent(android.support.design.widget.CoordinatorLayout, V, android.view.MotionEvent);
+    method public static void setTag(android.view.View, java.lang.Object);
+  }
+
+  public static abstract class CoordinatorLayout.DefaultBehavior implements java.lang.annotation.Annotation {
+  }
+
+  public static class CoordinatorLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public CoordinatorLayout.LayoutParams(int, int);
+    ctor public CoordinatorLayout.LayoutParams(android.support.design.widget.CoordinatorLayout.LayoutParams);
+    ctor public CoordinatorLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public CoordinatorLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+    method public int getAnchorId();
+    method public android.support.design.widget.CoordinatorLayout.Behavior getBehavior();
+    method public void setAnchorId(int);
+    method public void setBehavior(android.support.design.widget.CoordinatorLayout.Behavior);
+    field public int anchorGravity;
+    field public int dodgeInsetEdges;
+    field public int gravity;
+    field public int insetEdge;
+    field public int keyline;
+  }
+
+  protected static class CoordinatorLayout.SavedState extends android.support.v4.view.AbsSavedState {
+    ctor public CoordinatorLayout.SavedState(android.os.Parcel, java.lang.ClassLoader);
+    ctor public CoordinatorLayout.SavedState(android.os.Parcelable);
+    field public static final android.os.Parcelable.Creator<android.support.design.widget.CoordinatorLayout.SavedState> CREATOR;
+  }
+
+  public class FloatingActionButton extends android.support.design.widget.VisibilityAwareImageButton {
+    ctor public FloatingActionButton(android.content.Context);
+    ctor public FloatingActionButton(android.content.Context, android.util.AttributeSet);
+    ctor public FloatingActionButton(android.content.Context, android.util.AttributeSet, int);
+    method public float getCompatElevation();
+    method public android.graphics.drawable.Drawable getContentBackground();
+    method public boolean getContentRect(android.graphics.Rect);
+    method public int getRippleColor();
+    method public int getSize();
+    method public boolean getUseCompatPadding();
+    method public void hide();
+    method public void hide(android.support.design.widget.FloatingActionButton.OnVisibilityChangedListener);
+    method public void setCompatElevation(float);
+    method public void setRippleColor(int);
+    method public void setSize(int);
+    method public void setUseCompatPadding(boolean);
+    method public void show();
+    method public void show(android.support.design.widget.FloatingActionButton.OnVisibilityChangedListener);
+    field public static final int SIZE_AUTO = -1; // 0xffffffff
+    field public static final int SIZE_MINI = 1; // 0x1
+    field public static final int SIZE_NORMAL = 0; // 0x0
+  }
+
+  public static class FloatingActionButton.Behavior extends android.support.design.widget.CoordinatorLayout.Behavior {
+    ctor public FloatingActionButton.Behavior();
+    ctor public FloatingActionButton.Behavior(android.content.Context, android.util.AttributeSet);
+    method public boolean getInsetDodgeRect(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.graphics.Rect);
+    method public boolean isAutoHideEnabled();
+    method public boolean onDependentViewChanged(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.view.View);
+    method public boolean onLayoutChild(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, int);
+    method public void setAutoHideEnabled(boolean);
+  }
+
+  public static abstract class FloatingActionButton.OnVisibilityChangedListener {
+    ctor public FloatingActionButton.OnVisibilityChangedListener();
+    method public void onHidden(android.support.design.widget.FloatingActionButton);
+    method public void onShown(android.support.design.widget.FloatingActionButton);
+  }
+
+   abstract class HeaderBehavior<V extends android.view.View> extends android.support.design.widget.ViewOffsetBehavior {
+    ctor public HeaderBehavior();
+    ctor public HeaderBehavior(android.content.Context, android.util.AttributeSet);
+  }
+
+   abstract class HeaderScrollingViewBehavior extends android.support.design.widget.ViewOffsetBehavior {
+    ctor public HeaderScrollingViewBehavior();
+    ctor public HeaderScrollingViewBehavior(android.content.Context, android.util.AttributeSet);
+    method public final int getOverlayTop();
+    method protected void layoutChild(android.support.design.widget.CoordinatorLayout, android.view.View, int);
+    method public boolean onMeasureChild(android.support.design.widget.CoordinatorLayout, android.view.View, int, int, int, int);
+    method public final void setOverlayTop(int);
+  }
+
+  public class NavigationView extends android.widget.FrameLayout {
+    ctor public NavigationView(android.content.Context);
+    ctor public NavigationView(android.content.Context, android.util.AttributeSet);
+    ctor public NavigationView(android.content.Context, android.util.AttributeSet, int);
+    method public void addHeaderView(android.view.View);
+    method public int getHeaderCount();
+    method public android.view.View getHeaderView(int);
+    method public android.graphics.drawable.Drawable getItemBackground();
+    method public android.content.res.ColorStateList getItemIconTintList();
+    method public android.content.res.ColorStateList getItemTextColor();
+    method public android.view.Menu getMenu();
+    method public android.view.View inflateHeaderView(int);
+    method public void inflateMenu(int);
+    method public void removeHeaderView(android.view.View);
+    method public void setCheckedItem(int);
+    method public void setItemBackground(android.graphics.drawable.Drawable);
+    method public void setItemBackgroundResource(int);
+    method public void setItemIconTintList(android.content.res.ColorStateList);
+    method public void setItemTextAppearance(int);
+    method public void setItemTextColor(android.content.res.ColorStateList);
+    method public void setNavigationItemSelectedListener(android.support.design.widget.NavigationView.OnNavigationItemSelectedListener);
+  }
+
+  public static abstract interface NavigationView.OnNavigationItemSelectedListener {
+    method public abstract boolean onNavigationItemSelected(android.view.MenuItem);
+  }
+
+  public static class NavigationView.SavedState extends android.support.v4.view.AbsSavedState {
+    ctor public NavigationView.SavedState(android.os.Parcel, java.lang.ClassLoader);
+    ctor public NavigationView.SavedState(android.os.Parcelable);
+    field public static final android.os.Parcelable.Creator<android.support.design.widget.NavigationView.SavedState> CREATOR;
+    field public android.os.Bundle menuState;
+  }
+
+  public final class Snackbar extends android.support.design.widget.BaseTransientBottomBar {
+    method public static android.support.design.widget.Snackbar make(android.view.View, java.lang.CharSequence, int);
+    method public static android.support.design.widget.Snackbar make(android.view.View, int, int);
+    method public android.support.design.widget.Snackbar setAction(int, android.view.View.OnClickListener);
+    method public android.support.design.widget.Snackbar setAction(java.lang.CharSequence, android.view.View.OnClickListener);
+    method public android.support.design.widget.Snackbar setActionTextColor(android.content.res.ColorStateList);
+    method public android.support.design.widget.Snackbar setActionTextColor(int);
+    method public deprecated android.support.design.widget.Snackbar setCallback(android.support.design.widget.Snackbar.Callback);
+    method public android.support.design.widget.Snackbar setText(java.lang.CharSequence);
+    method public android.support.design.widget.Snackbar setText(int);
+    field public static final int LENGTH_INDEFINITE = -2; // 0xfffffffe
+    field public static final int LENGTH_LONG = 0; // 0x0
+    field public static final int LENGTH_SHORT = -1; // 0xffffffff
+  }
+
+  public static class Snackbar.Callback extends android.support.design.widget.BaseTransientBottomBar.BaseCallback {
+    ctor public Snackbar.Callback();
+    method public void onDismissed(android.support.design.widget.Snackbar, int);
+    method public void onShown(android.support.design.widget.Snackbar);
+    field public static final int DISMISS_EVENT_ACTION = 1; // 0x1
+    field public static final int DISMISS_EVENT_CONSECUTIVE = 4; // 0x4
+    field public static final int DISMISS_EVENT_MANUAL = 3; // 0x3
+    field public static final int DISMISS_EVENT_SWIPE = 0; // 0x0
+    field public static final int DISMISS_EVENT_TIMEOUT = 2; // 0x2
+  }
+
+  public class SwipeDismissBehavior<V extends android.view.View> extends android.support.design.widget.CoordinatorLayout.Behavior {
+    ctor public SwipeDismissBehavior();
+    method public boolean canSwipeDismissView(android.view.View);
+    method public int getDragState();
+    method public void setDragDismissDistance(float);
+    method public void setEndAlphaSwipeDistance(float);
+    method public void setListener(android.support.design.widget.SwipeDismissBehavior.OnDismissListener);
+    method public void setSensitivity(float);
+    method public void setStartAlphaSwipeDistance(float);
+    method public void setSwipeDirection(int);
+    field public static final int STATE_DRAGGING = 1; // 0x1
+    field public static final int STATE_IDLE = 0; // 0x0
+    field public static final int STATE_SETTLING = 2; // 0x2
+    field public static final int SWIPE_DIRECTION_ANY = 2; // 0x2
+    field public static final int SWIPE_DIRECTION_END_TO_START = 1; // 0x1
+    field public static final int SWIPE_DIRECTION_START_TO_END = 0; // 0x0
+  }
+
+  public static abstract interface SwipeDismissBehavior.OnDismissListener {
+    method public abstract void onDismiss(android.view.View);
+    method public abstract void onDragStateChanged(int);
+  }
+
+  public final class TabItem extends android.view.View {
+    ctor public TabItem(android.content.Context);
+    ctor public TabItem(android.content.Context, android.util.AttributeSet);
+  }
+
+  public class TabLayout extends android.widget.HorizontalScrollView {
+    ctor public TabLayout(android.content.Context);
+    ctor public TabLayout(android.content.Context, android.util.AttributeSet);
+    ctor public TabLayout(android.content.Context, android.util.AttributeSet, int);
+    method public void addOnTabSelectedListener(android.support.design.widget.TabLayout.OnTabSelectedListener);
+    method public void addTab(android.support.design.widget.TabLayout.Tab);
+    method public void addTab(android.support.design.widget.TabLayout.Tab, int);
+    method public void addTab(android.support.design.widget.TabLayout.Tab, boolean);
+    method public void addTab(android.support.design.widget.TabLayout.Tab, int, boolean);
+    method public void clearOnTabSelectedListeners();
+    method public int getSelectedTabPosition();
+    method public android.support.design.widget.TabLayout.Tab getTabAt(int);
+    method public int getTabCount();
+    method public int getTabGravity();
+    method public int getTabMode();
+    method public android.content.res.ColorStateList getTabTextColors();
+    method public android.support.design.widget.TabLayout.Tab newTab();
+    method public void removeAllTabs();
+    method public void removeOnTabSelectedListener(android.support.design.widget.TabLayout.OnTabSelectedListener);
+    method public void removeTab(android.support.design.widget.TabLayout.Tab);
+    method public void removeTabAt(int);
+    method public deprecated void setOnTabSelectedListener(android.support.design.widget.TabLayout.OnTabSelectedListener);
+    method public void setScrollPosition(int, float, boolean);
+    method public void setSelectedTabIndicatorColor(int);
+    method public void setSelectedTabIndicatorHeight(int);
+    method public void setTabGravity(int);
+    method public void setTabMode(int);
+    method public void setTabTextColors(android.content.res.ColorStateList);
+    method public void setTabTextColors(int, int);
+    method public deprecated void setTabsFromPagerAdapter(android.support.v4.view.PagerAdapter);
+    method public void setupWithViewPager(android.support.v4.view.ViewPager);
+    method public void setupWithViewPager(android.support.v4.view.ViewPager, boolean);
+    field public static final int GRAVITY_CENTER = 1; // 0x1
+    field public static final int GRAVITY_FILL = 0; // 0x0
+    field public static final int MODE_FIXED = 1; // 0x1
+    field public static final int MODE_SCROLLABLE = 0; // 0x0
+  }
+
+  public static abstract interface TabLayout.OnTabSelectedListener {
+    method public abstract void onTabReselected(android.support.design.widget.TabLayout.Tab);
+    method public abstract void onTabSelected(android.support.design.widget.TabLayout.Tab);
+    method public abstract void onTabUnselected(android.support.design.widget.TabLayout.Tab);
+  }
+
+  public static final class TabLayout.Tab {
+    method public java.lang.CharSequence getContentDescription();
+    method public android.view.View getCustomView();
+    method public android.graphics.drawable.Drawable getIcon();
+    method public int getPosition();
+    method public java.lang.Object getTag();
+    method public java.lang.CharSequence getText();
+    method public boolean isSelected();
+    method public void select();
+    method public android.support.design.widget.TabLayout.Tab setContentDescription(int);
+    method public android.support.design.widget.TabLayout.Tab setContentDescription(java.lang.CharSequence);
+    method public android.support.design.widget.TabLayout.Tab setCustomView(android.view.View);
+    method public android.support.design.widget.TabLayout.Tab setCustomView(int);
+    method public android.support.design.widget.TabLayout.Tab setIcon(android.graphics.drawable.Drawable);
+    method public android.support.design.widget.TabLayout.Tab setIcon(int);
+    method public android.support.design.widget.TabLayout.Tab setTag(java.lang.Object);
+    method public android.support.design.widget.TabLayout.Tab setText(java.lang.CharSequence);
+    method public android.support.design.widget.TabLayout.Tab setText(int);
+    field public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  public static class TabLayout.TabLayoutOnPageChangeListener implements android.support.v4.view.ViewPager.OnPageChangeListener {
+    ctor public TabLayout.TabLayoutOnPageChangeListener(android.support.design.widget.TabLayout);
+    method public void onPageScrollStateChanged(int);
+    method public void onPageScrolled(int, float, int);
+    method public void onPageSelected(int);
+  }
+
+  public static class TabLayout.ViewPagerOnTabSelectedListener implements android.support.design.widget.TabLayout.OnTabSelectedListener {
+    ctor public TabLayout.ViewPagerOnTabSelectedListener(android.support.v4.view.ViewPager);
+    method public void onTabReselected(android.support.design.widget.TabLayout.Tab);
+    method public void onTabSelected(android.support.design.widget.TabLayout.Tab);
+    method public void onTabUnselected(android.support.design.widget.TabLayout.Tab);
+  }
+
+  public class TextInputEditText extends android.support.v7.widget.AppCompatEditText {
+    ctor public TextInputEditText(android.content.Context);
+    ctor public TextInputEditText(android.content.Context, android.util.AttributeSet);
+    ctor public TextInputEditText(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class TextInputLayout extends android.widget.LinearLayout {
+    ctor public TextInputLayout(android.content.Context);
+    ctor public TextInputLayout(android.content.Context, android.util.AttributeSet);
+    ctor public TextInputLayout(android.content.Context, android.util.AttributeSet, int);
+    method public int getCounterMaxLength();
+    method public android.widget.EditText getEditText();
+    method public java.lang.CharSequence getError();
+    method public java.lang.CharSequence getHint();
+    method public java.lang.CharSequence getPasswordVisibilityToggleContentDescription();
+    method public android.graphics.drawable.Drawable getPasswordVisibilityToggleDrawable();
+    method public android.graphics.Typeface getTypeface();
+    method public boolean isCounterEnabled();
+    method public boolean isErrorEnabled();
+    method public boolean isHintAnimationEnabled();
+    method public boolean isHintEnabled();
+    method public boolean isPasswordVisibilityToggleEnabled();
+    method public android.os.Parcelable onSaveInstanceState();
+    method public void setCounterEnabled(boolean);
+    method public void setCounterMaxLength(int);
+    method public void setError(java.lang.CharSequence);
+    method public void setErrorEnabled(boolean);
+    method public void setErrorTextAppearance(int);
+    method public void setHint(java.lang.CharSequence);
+    method public void setHintAnimationEnabled(boolean);
+    method public void setHintEnabled(boolean);
+    method public void setHintTextAppearance(int);
+    method public void setPasswordVisibilityToggleContentDescription(int);
+    method public void setPasswordVisibilityToggleContentDescription(java.lang.CharSequence);
+    method public void setPasswordVisibilityToggleDrawable(int);
+    method public void setPasswordVisibilityToggleDrawable(android.graphics.drawable.Drawable);
+    method public void setPasswordVisibilityToggleEnabled(boolean);
+    method public void setPasswordVisibilityToggleTintList(android.content.res.ColorStateList);
+    method public void setPasswordVisibilityToggleTintMode(android.graphics.PorterDuff.Mode);
+    method public void setTypeface(android.graphics.Typeface);
+  }
+
+   class ViewOffsetBehavior<V extends android.view.View> extends android.support.design.widget.CoordinatorLayout.Behavior {
+    ctor public ViewOffsetBehavior();
+    ctor public ViewOffsetBehavior(android.content.Context, android.util.AttributeSet);
+    method public int getLeftAndRightOffset();
+    method public int getTopAndBottomOffset();
+    method protected void layoutChild(android.support.design.widget.CoordinatorLayout, V, int);
+    method public boolean setLeftAndRightOffset(int);
+    method public boolean setTopAndBottomOffset(int);
+  }
+
+   class VisibilityAwareImageButton extends android.widget.ImageButton {
+    ctor public VisibilityAwareImageButton(android.content.Context);
+    ctor public VisibilityAwareImageButton(android.content.Context, android.util.AttributeSet);
+    ctor public VisibilityAwareImageButton(android.content.Context, android.util.AttributeSet, int);
+  }
+
+}
+
+package android.support.graphics.drawable {
+
+  public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon {
+    method public static android.support.graphics.drawable.AnimatedVectorDrawableCompat create(android.content.Context, int);
+    method public static android.support.graphics.drawable.AnimatedVectorDrawableCompat createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void draw(android.graphics.Canvas);
+    method public int getOpacity();
+    method public boolean isRunning();
+    method public void setAlpha(int);
+    method public void setColorFilter(android.graphics.ColorFilter);
+    method public void start();
+    method public void stop();
+  }
+
+   abstract class VectorDrawableCommon extends android.graphics.drawable.Drawable {
+  }
+
+  public class VectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon {
+    method public static android.support.graphics.drawable.VectorDrawableCompat create(android.content.res.Resources, int, android.content.res.Resources.Theme);
+    method public static android.support.graphics.drawable.VectorDrawableCompat createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void draw(android.graphics.Canvas);
+    method public int getOpacity();
+    method public void setAlpha(int);
+    method public void setColorFilter(android.graphics.ColorFilter);
+  }
+
+}
+
+package android.support.media {
+
+  public class ExifInterface {
+    ctor public ExifInterface(java.lang.String) throws java.io.IOException;
+    ctor public ExifInterface(java.io.InputStream) throws java.io.IOException;
+    method public double getAltitude(double);
+    method public java.lang.String getAttribute(java.lang.String);
+    method public double getAttributeDouble(java.lang.String, double);
+    method public int getAttributeInt(java.lang.String, int);
+    method public boolean getLatLong(float[]);
+    method public byte[] getThumbnail();
+    method public android.graphics.Bitmap getThumbnailBitmap();
+    method public byte[] getThumbnailBytes();
+    method public long[] getThumbnailRange();
+    method public boolean hasThumbnail();
+    method public boolean isThumbnailCompressed();
+    method public void saveAttributes() throws java.io.IOException;
+    method public void setAttribute(java.lang.String, java.lang.String);
+    field public static final int ORIENTATION_FLIP_HORIZONTAL = 2; // 0x2
+    field public static final int ORIENTATION_FLIP_VERTICAL = 4; // 0x4
+    field public static final int ORIENTATION_NORMAL = 1; // 0x1
+    field public static final int ORIENTATION_ROTATE_180 = 3; // 0x3
+    field public static final int ORIENTATION_ROTATE_270 = 8; // 0x8
+    field public static final int ORIENTATION_ROTATE_90 = 6; // 0x6
+    field public static final int ORIENTATION_TRANSPOSE = 5; // 0x5
+    field public static final int ORIENTATION_TRANSVERSE = 7; // 0x7
+    field public static final int ORIENTATION_UNDEFINED = 0; // 0x0
+    field public static final java.lang.String TAG_APERTURE_VALUE = "ApertureValue";
+    field public static final java.lang.String TAG_ARTIST = "Artist";
+    field public static final java.lang.String TAG_BITS_PER_SAMPLE = "BitsPerSample";
+    field public static final java.lang.String TAG_BRIGHTNESS_VALUE = "BrightnessValue";
+    field public static final java.lang.String TAG_CFA_PATTERN = "CFAPattern";
+    field public static final java.lang.String TAG_COLOR_SPACE = "ColorSpace";
+    field public static final java.lang.String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration";
+    field public static final java.lang.String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel";
+    field public static final java.lang.String TAG_COMPRESSION = "Compression";
+    field public static final java.lang.String TAG_CONTRAST = "Contrast";
+    field public static final java.lang.String TAG_COPYRIGHT = "Copyright";
+    field public static final java.lang.String TAG_CUSTOM_RENDERED = "CustomRendered";
+    field public static final java.lang.String TAG_DATETIME = "DateTime";
+    field public static final java.lang.String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
+    field public static final java.lang.String TAG_DATETIME_ORIGINAL = "DateTimeOriginal";
+    field public static final java.lang.String TAG_DEFAULT_CROP_SIZE = "DefaultCropSize";
+    field public static final java.lang.String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription";
+    field public static final java.lang.String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio";
+    field public static final java.lang.String TAG_DNG_VERSION = "DNGVersion";
+    field public static final java.lang.String TAG_EXIF_VERSION = "ExifVersion";
+    field public static final java.lang.String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue";
+    field public static final java.lang.String TAG_EXPOSURE_INDEX = "ExposureIndex";
+    field public static final java.lang.String TAG_EXPOSURE_MODE = "ExposureMode";
+    field public static final java.lang.String TAG_EXPOSURE_PROGRAM = "ExposureProgram";
+    field public static final java.lang.String TAG_EXPOSURE_TIME = "ExposureTime";
+    field public static final java.lang.String TAG_FILE_SOURCE = "FileSource";
+    field public static final java.lang.String TAG_FLASH = "Flash";
+    field public static final java.lang.String TAG_FLASHPIX_VERSION = "FlashpixVersion";
+    field public static final java.lang.String TAG_FLASH_ENERGY = "FlashEnergy";
+    field public static final java.lang.String TAG_FOCAL_LENGTH = "FocalLength";
+    field public static final java.lang.String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm";
+    field public static final java.lang.String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit";
+    field public static final java.lang.String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution";
+    field public static final java.lang.String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution";
+    field public static final java.lang.String TAG_F_NUMBER = "FNumber";
+    field public static final java.lang.String TAG_GAIN_CONTROL = "GainControl";
+    field public static final java.lang.String TAG_GPS_ALTITUDE = "GPSAltitude";
+    field public static final java.lang.String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef";
+    field public static final java.lang.String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation";
+    field public static final java.lang.String TAG_GPS_DATESTAMP = "GPSDateStamp";
+    field public static final java.lang.String TAG_GPS_DEST_BEARING = "GPSDestBearing";
+    field public static final java.lang.String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef";
+    field public static final java.lang.String TAG_GPS_DEST_DISTANCE = "GPSDestDistance";
+    field public static final java.lang.String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef";
+    field public static final java.lang.String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude";
+    field public static final java.lang.String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef";
+    field public static final java.lang.String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude";
+    field public static final java.lang.String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef";
+    field public static final java.lang.String TAG_GPS_DIFFERENTIAL = "GPSDifferential";
+    field public static final java.lang.String TAG_GPS_DOP = "GPSDOP";
+    field public static final java.lang.String TAG_GPS_IMG_DIRECTION = "GPSImgDirection";
+    field public static final java.lang.String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef";
+    field public static final java.lang.String TAG_GPS_LATITUDE = "GPSLatitude";
+    field public static final java.lang.String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
+    field public static final java.lang.String TAG_GPS_LONGITUDE = "GPSLongitude";
+    field public static final java.lang.String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
+    field public static final java.lang.String TAG_GPS_MAP_DATUM = "GPSMapDatum";
+    field public static final java.lang.String TAG_GPS_MEASURE_MODE = "GPSMeasureMode";
+    field public static final java.lang.String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod";
+    field public static final java.lang.String TAG_GPS_SATELLITES = "GPSSatellites";
+    field public static final java.lang.String TAG_GPS_SPEED = "GPSSpeed";
+    field public static final java.lang.String TAG_GPS_SPEED_REF = "GPSSpeedRef";
+    field public static final java.lang.String TAG_GPS_STATUS = "GPSStatus";
+    field public static final java.lang.String TAG_GPS_TIMESTAMP = "GPSTimeStamp";
+    field public static final java.lang.String TAG_GPS_TRACK = "GPSTrack";
+    field public static final java.lang.String TAG_GPS_TRACK_REF = "GPSTrackRef";
+    field public static final java.lang.String TAG_GPS_VERSION_ID = "GPSVersionID";
+    field public static final java.lang.String TAG_IMAGE_DESCRIPTION = "ImageDescription";
+    field public static final java.lang.String TAG_IMAGE_LENGTH = "ImageLength";
+    field public static final java.lang.String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID";
+    field public static final java.lang.String TAG_IMAGE_WIDTH = "ImageWidth";
+    field public static final java.lang.String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex";
+    field public static final java.lang.String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings";
+    field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat";
+    field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength";
+    field public static final java.lang.String TAG_LIGHT_SOURCE = "LightSource";
+    field public static final java.lang.String TAG_MAKE = "Make";
+    field public static final java.lang.String TAG_MAKER_NOTE = "MakerNote";
+    field public static final java.lang.String TAG_MAX_APERTURE_VALUE = "MaxApertureValue";
+    field public static final java.lang.String TAG_METERING_MODE = "MeteringMode";
+    field public static final java.lang.String TAG_MODEL = "Model";
+    field public static final java.lang.String TAG_NEW_SUBFILE_TYPE = "NewSubfileType";
+    field public static final java.lang.String TAG_OECF = "OECF";
+    field public static final java.lang.String TAG_ORF_ASPECT_FRAME = "AspectFrame";
+    field public static final java.lang.String TAG_ORF_PREVIEW_IMAGE_LENGTH = "PreviewImageLength";
+    field public static final java.lang.String TAG_ORF_PREVIEW_IMAGE_START = "PreviewImageStart";
+    field public static final java.lang.String TAG_ORF_THUMBNAIL_IMAGE = "ThumbnailImage";
+    field public static final java.lang.String TAG_ORIENTATION = "Orientation";
+    field public static final java.lang.String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation";
+    field public static final java.lang.String TAG_PIXEL_X_DIMENSION = "PixelXDimension";
+    field public static final java.lang.String TAG_PIXEL_Y_DIMENSION = "PixelYDimension";
+    field public static final java.lang.String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration";
+    field public static final java.lang.String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities";
+    field public static final java.lang.String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite";
+    field public static final java.lang.String TAG_RELATED_SOUND_FILE = "RelatedSoundFile";
+    field public static final java.lang.String TAG_RESOLUTION_UNIT = "ResolutionUnit";
+    field public static final java.lang.String TAG_ROWS_PER_STRIP = "RowsPerStrip";
+    field public static final java.lang.String TAG_RW2_ISO = "ISO";
+    field public static final java.lang.String TAG_RW2_JPG_FROM_RAW = "JpgFromRaw";
+    field public static final java.lang.String TAG_RW2_SENSOR_BOTTOM_BORDER = "SensorBottomBorder";
+    field public static final java.lang.String TAG_RW2_SENSOR_LEFT_BORDER = "SensorLeftBorder";
+    field public static final java.lang.String TAG_RW2_SENSOR_RIGHT_BORDER = "SensorRightBorder";
+    field public static final java.lang.String TAG_RW2_SENSOR_TOP_BORDER = "SensorTopBorder";
+    field public static final java.lang.String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel";
+    field public static final java.lang.String TAG_SATURATION = "Saturation";
+    field public static final java.lang.String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType";
+    field public static final java.lang.String TAG_SCENE_TYPE = "SceneType";
+    field public static final java.lang.String TAG_SENSING_METHOD = "SensingMethod";
+    field public static final java.lang.String TAG_SHARPNESS = "Sharpness";
+    field public static final java.lang.String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue";
+    field public static final java.lang.String TAG_SOFTWARE = "Software";
+    field public static final java.lang.String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse";
+    field public static final java.lang.String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity";
+    field public static final java.lang.String TAG_STRIP_BYTE_COUNTS = "StripByteCounts";
+    field public static final java.lang.String TAG_STRIP_OFFSETS = "StripOffsets";
+    field public static final java.lang.String TAG_SUBFILE_TYPE = "SubfileType";
+    field public static final java.lang.String TAG_SUBJECT_AREA = "SubjectArea";
+    field public static final java.lang.String TAG_SUBJECT_DISTANCE = "SubjectDistance";
+    field public static final java.lang.String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange";
+    field public static final java.lang.String TAG_SUBJECT_LOCATION = "SubjectLocation";
+    field public static final java.lang.String TAG_SUBSEC_TIME = "SubSecTime";
+    field public static final java.lang.String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized";
+    field public static final java.lang.String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal";
+    field public static final java.lang.String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength";
+    field public static final java.lang.String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth";
+    field public static final java.lang.String TAG_TRANSFER_FUNCTION = "TransferFunction";
+    field public static final java.lang.String TAG_USER_COMMENT = "UserComment";
+    field public static final java.lang.String TAG_WHITE_BALANCE = "WhiteBalance";
+    field public static final java.lang.String TAG_WHITE_POINT = "WhitePoint";
+    field public static final java.lang.String TAG_X_RESOLUTION = "XResolution";
+    field public static final java.lang.String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients";
+    field public static final java.lang.String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning";
+    field public static final java.lang.String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling";
+    field public static final java.lang.String TAG_Y_RESOLUTION = "YResolution";
+    field public static final int WHITEBALANCE_AUTO = 0; // 0x0
+    field public static final int WHITEBALANCE_MANUAL = 1; // 0x1
+  }
+
+}
+
+package android.support.percent {
+
+  public class PercentFrameLayout extends android.widget.FrameLayout {
+    ctor public PercentFrameLayout(android.content.Context);
+    ctor public PercentFrameLayout(android.content.Context, android.util.AttributeSet);
+    ctor public PercentFrameLayout(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public static class PercentFrameLayout.LayoutParams extends android.widget.FrameLayout.LayoutParams implements android.support.percent.PercentLayoutHelper.PercentLayoutParams {
+    ctor public PercentFrameLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public PercentFrameLayout.LayoutParams(int, int);
+    ctor public PercentFrameLayout.LayoutParams(int, int, int);
+    ctor public PercentFrameLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public PercentFrameLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public PercentFrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams);
+    ctor public PercentFrameLayout.LayoutParams(android.support.percent.PercentFrameLayout.LayoutParams);
+    method public android.support.percent.PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo();
+  }
+
+  public class PercentLayoutHelper {
+    ctor public PercentLayoutHelper(android.view.ViewGroup);
+    method public void adjustChildren(int, int);
+    method public static void fetchWidthAndHeight(android.view.ViewGroup.LayoutParams, android.content.res.TypedArray, int, int);
+    method public static android.support.percent.PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo(android.content.Context, android.util.AttributeSet);
+    method public boolean handleMeasuredStateTooSmall();
+    method public void restoreOriginalParams();
+  }
+
+  public static class PercentLayoutHelper.PercentLayoutInfo {
+    ctor public PercentLayoutHelper.PercentLayoutInfo();
+    method public void fillLayoutParams(android.view.ViewGroup.LayoutParams, int, int);
+    method public deprecated void fillMarginLayoutParams(android.view.ViewGroup.MarginLayoutParams, int, int);
+    method public void fillMarginLayoutParams(android.view.View, android.view.ViewGroup.MarginLayoutParams, int, int);
+    method public void restoreLayoutParams(android.view.ViewGroup.LayoutParams);
+    method public void restoreMarginLayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    field public float aspectRatio;
+    field public float bottomMarginPercent;
+    field public float endMarginPercent;
+    field public float heightPercent;
+    field public float leftMarginPercent;
+    field public float rightMarginPercent;
+    field public float startMarginPercent;
+    field public float topMarginPercent;
+    field public float widthPercent;
+  }
+
+  public static abstract interface PercentLayoutHelper.PercentLayoutParams {
+    method public abstract android.support.percent.PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo();
+  }
+
+  public class PercentRelativeLayout extends android.widget.RelativeLayout {
+    ctor public PercentRelativeLayout(android.content.Context);
+    ctor public PercentRelativeLayout(android.content.Context, android.util.AttributeSet);
+    ctor public PercentRelativeLayout(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public static class PercentRelativeLayout.LayoutParams extends android.widget.RelativeLayout.LayoutParams implements android.support.percent.PercentLayoutHelper.PercentLayoutParams {
+    ctor public PercentRelativeLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public PercentRelativeLayout.LayoutParams(int, int);
+    ctor public PercentRelativeLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public PercentRelativeLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    method public android.support.percent.PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo();
+  }
+
+}
+
+package android.support.transition {
+
+  public class AutoTransition extends android.support.transition.TransitionSet {
+    ctor public AutoTransition();
+  }
+
+  public class ChangeBounds extends android.support.transition.Transition {
+    ctor public ChangeBounds();
+    method public void captureEndValues(android.support.transition.TransitionValues);
+    method public void captureStartValues(android.support.transition.TransitionValues);
+    method public void setResizeClip(boolean);
+  }
+
+  public class Fade extends android.support.transition.Visibility {
+    ctor public Fade(int);
+    ctor public Fade();
+    field public static final int IN = 1; // 0x1
+    field public static final int OUT = 2; // 0x2
+  }
+
+  public class Scene {
+    ctor public Scene(android.view.ViewGroup);
+    ctor public Scene(android.view.ViewGroup, android.view.View);
+    method public void enter();
+    method public void exit();
+    method public static android.support.transition.Scene getSceneForLayout(android.view.ViewGroup, int, android.content.Context);
+    method public android.view.ViewGroup getSceneRoot();
+    method public void setEnterAction(java.lang.Runnable);
+    method public void setExitAction(java.lang.Runnable);
+  }
+
+  public abstract class Transition {
+    ctor public Transition();
+    method public android.support.transition.Transition addListener(android.support.transition.Transition.TransitionListener);
+    method public android.support.transition.Transition addTarget(android.view.View);
+    method public android.support.transition.Transition addTarget(int);
+    method public abstract void captureEndValues(android.support.transition.TransitionValues);
+    method public abstract void captureStartValues(android.support.transition.TransitionValues);
+    method public android.animation.Animator createAnimator(android.view.ViewGroup, android.support.transition.TransitionValues, android.support.transition.TransitionValues);
+    method public android.support.transition.Transition excludeChildren(android.view.View, boolean);
+    method public android.support.transition.Transition excludeChildren(int, boolean);
+    method public android.support.transition.Transition excludeChildren(java.lang.Class, boolean);
+    method public android.support.transition.Transition excludeTarget(android.view.View, boolean);
+    method public android.support.transition.Transition excludeTarget(int, boolean);
+    method public android.support.transition.Transition excludeTarget(java.lang.Class, boolean);
+    method public long getDuration();
+    method public android.animation.TimeInterpolator getInterpolator();
+    method public java.lang.String getName();
+    method public long getStartDelay();
+    method public java.util.List<java.lang.Integer> getTargetIds();
+    method public java.util.List<android.view.View> getTargets();
+    method public java.lang.String[] getTransitionProperties();
+    method public android.support.transition.TransitionValues getTransitionValues(android.view.View, boolean);
+    method public android.support.transition.Transition removeListener(android.support.transition.Transition.TransitionListener);
+    method public android.support.transition.Transition removeTarget(android.view.View);
+    method public android.support.transition.Transition removeTarget(int);
+    method public android.support.transition.Transition setDuration(long);
+    method public android.support.transition.Transition setInterpolator(android.animation.TimeInterpolator);
+    method public android.support.transition.Transition setStartDelay(long);
+  }
+
+  public static abstract interface Transition.TransitionListener {
+    method public abstract void onTransitionCancel(android.support.transition.Transition);
+    method public abstract void onTransitionEnd(android.support.transition.Transition);
+    method public abstract void onTransitionPause(android.support.transition.Transition);
+    method public abstract void onTransitionResume(android.support.transition.Transition);
+    method public abstract void onTransitionStart(android.support.transition.Transition);
+  }
+
+  public class TransitionManager {
+    ctor public TransitionManager();
+    method public static void beginDelayedTransition(android.view.ViewGroup);
+    method public static void beginDelayedTransition(android.view.ViewGroup, android.support.transition.Transition);
+    method public static void go(android.support.transition.Scene);
+    method public static void go(android.support.transition.Scene, android.support.transition.Transition);
+    method public void setTransition(android.support.transition.Scene, android.support.transition.Transition);
+    method public void setTransition(android.support.transition.Scene, android.support.transition.Scene, android.support.transition.Transition);
+    method public void transitionTo(android.support.transition.Scene);
+  }
+
+  public class TransitionSet extends android.support.transition.Transition {
+    ctor public TransitionSet();
+    method public android.support.transition.TransitionSet addTransition(android.support.transition.Transition);
+    method public void captureEndValues(android.support.transition.TransitionValues);
+    method public void captureStartValues(android.support.transition.TransitionValues);
+    method public int getOrdering();
+    method public android.support.transition.TransitionSet removeTransition(android.support.transition.Transition);
+    method public android.support.transition.TransitionSet setOrdering(int);
+    field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
+    field public static final int ORDERING_TOGETHER = 0; // 0x0
+  }
+
+  public class TransitionValues {
+    ctor public TransitionValues();
+    field public final java.util.Map<java.lang.String, java.lang.Object> values;
+    field public android.view.View view;
+  }
+
+  public abstract class Visibility extends android.support.transition.Transition {
+    ctor public Visibility();
+    method public void captureEndValues(android.support.transition.TransitionValues);
+    method public void captureStartValues(android.support.transition.TransitionValues);
+    method public boolean isVisible(android.support.transition.TransitionValues);
+    method public android.animation.Animator onAppear(android.view.ViewGroup, android.support.transition.TransitionValues, int, android.support.transition.TransitionValues, int);
+    method public android.animation.Animator onDisappear(android.view.ViewGroup, android.support.transition.TransitionValues, int, android.support.transition.TransitionValues, int);
+  }
+
+}
+
+package android.support.v13.app {
+
+  public class ActivityCompat extends android.support.v4.app.ActivityCompat {
+    ctor protected ActivityCompat();
+    method public static android.support.v13.view.DragAndDropPermissionsCompat requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent);
+  }
+
+  public class FragmentCompat {
+    ctor public FragmentCompat();
+    method public static void requestPermissions(android.app.Fragment, java.lang.String[], int);
+    method public static void setMenuVisibility(android.app.Fragment, boolean);
+    method public static void setUserVisibleHint(android.app.Fragment, boolean);
+    method public static boolean shouldShowRequestPermissionRationale(android.app.Fragment, java.lang.String);
+  }
+
+  public static abstract interface FragmentCompat.OnRequestPermissionsResultCallback {
+    method public abstract void onRequestPermissionsResult(int, java.lang.String[], int[]);
+  }
+
+  public abstract class FragmentPagerAdapter extends android.support.v4.view.PagerAdapter {
+    ctor public FragmentPagerAdapter(android.app.FragmentManager);
+    method public abstract android.app.Fragment getItem(int);
+    method public long getItemId(int);
+    method public boolean isViewFromObject(android.view.View, java.lang.Object);
+  }
+
+  public abstract class FragmentStatePagerAdapter extends android.support.v4.view.PagerAdapter {
+    ctor public FragmentStatePagerAdapter(android.app.FragmentManager);
+    method public abstract android.app.Fragment getItem(int);
+    method public boolean isViewFromObject(android.view.View, java.lang.Object);
+  }
+
+  public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
+    ctor public FragmentTabHost(android.content.Context);
+    ctor public FragmentTabHost(android.content.Context, android.util.AttributeSet);
+    method public void addTab(android.widget.TabHost.TabSpec, java.lang.Class<?>, android.os.Bundle);
+    method public void onTabChanged(java.lang.String);
+    method public void setup(android.content.Context, android.app.FragmentManager);
+    method public void setup(android.content.Context, android.app.FragmentManager, int);
+  }
+
+}
+
+package android.support.v13.view {
+
+  public final class DragAndDropPermissionsCompat {
+    method public void release();
+  }
+
+  public class DragStartHelper {
+    ctor public DragStartHelper(android.view.View, android.support.v13.view.DragStartHelper.OnDragStartListener);
+    method public void attach();
+    method public void detach();
+    method public void getTouchPosition(android.graphics.Point);
+    method public boolean onLongClick(android.view.View);
+    method public boolean onTouch(android.view.View, android.view.MotionEvent);
+  }
+
+  public static abstract interface DragStartHelper.OnDragStartListener {
+    method public abstract boolean onDragStart(android.view.View, android.support.v13.view.DragStartHelper);
+  }
+
+  public class ViewCompat extends android.support.v4.view.ViewCompat {
+    method public static void cancelDragAndDrop(android.view.View);
+    method public static boolean startDragAndDrop(android.view.View, android.content.ClipData, android.view.View.DragShadowBuilder, java.lang.Object, int);
+    method public static void updateDragShadow(android.view.View, android.view.View.DragShadowBuilder);
+  }
+
+}
+
+package android.support.v13.view.inputmethod {
+
+  public final class EditorInfoCompat {
+    ctor public EditorInfoCompat();
+    method public static java.lang.String[] getContentMimeTypes(android.view.inputmethod.EditorInfo);
+    method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, java.lang.String[]);
+  }
+
+  public final class InputConnectionCompat {
+    ctor public InputConnectionCompat();
+    method public static boolean commitContent(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, android.support.v13.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle);
+    method public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, android.support.v13.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
+    field public static int INPUT_CONTENT_GRANT_READ_URI_PERMISSION;
+  }
+
+  public static abstract interface InputConnectionCompat.OnCommitContentListener {
+    method public abstract boolean onCommitContent(android.support.v13.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle);
+  }
+
+  public final class InputContentInfoCompat {
+    ctor public InputContentInfoCompat(android.net.Uri, android.content.ClipDescription, android.net.Uri);
+    method public android.net.Uri getContentUri();
+    method public android.content.ClipDescription getDescription();
+    method public android.net.Uri getLinkUri();
+    method public void releasePermission();
+    method public void requestPermission();
+    method public java.lang.Object unwrap();
+    method public static android.support.v13.view.inputmethod.InputContentInfoCompat wrap(java.lang.Object);
+  }
+
+}
+
+package android.support.v14.preference {
+
+  public class EditTextPreferenceDialogFragment extends android.support.v14.preference.PreferenceDialogFragment {
+    ctor public EditTextPreferenceDialogFragment();
+    method public static android.support.v14.preference.EditTextPreferenceDialogFragment newInstance(java.lang.String);
+    method public void onDialogClosed(boolean);
+  }
+
+  public class ListPreferenceDialogFragment extends android.support.v14.preference.PreferenceDialogFragment {
+    ctor public ListPreferenceDialogFragment();
+    method public static android.support.v14.preference.ListPreferenceDialogFragment newInstance(java.lang.String);
+    method public void onDialogClosed(boolean);
+  }
+
+  public class MultiSelectListPreference extends android.support.v7.preference.DialogPreference {
+    ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet);
+    ctor public MultiSelectListPreference(android.content.Context);
+    method public int findIndexOfValue(java.lang.String);
+    method public java.lang.CharSequence[] getEntries();
+    method public java.lang.CharSequence[] getEntryValues();
+    method protected boolean[] getSelectedItems();
+    method public java.util.Set<java.lang.String> getValues();
+    method public void setEntries(java.lang.CharSequence[]);
+    method public void setEntries(int);
+    method public void setEntryValues(java.lang.CharSequence[]);
+    method public void setEntryValues(int);
+    method public void setValues(java.util.Set<java.lang.String>);
+  }
+
+  public class MultiSelectListPreferenceDialogFragment extends android.support.v14.preference.PreferenceDialogFragment {
+    ctor public MultiSelectListPreferenceDialogFragment();
+    method public static android.support.v14.preference.MultiSelectListPreferenceDialogFragment newInstance(java.lang.String);
+    method public void onDialogClosed(boolean);
+  }
+
+  public abstract class PreferenceDialogFragment extends android.app.DialogFragment implements android.content.DialogInterface.OnClickListener {
+    ctor public PreferenceDialogFragment();
+    method public android.support.v7.preference.DialogPreference getPreference();
+    method protected void onBindDialogView(android.view.View);
+    method public void onClick(android.content.DialogInterface, int);
+    method protected android.view.View onCreateDialogView(android.content.Context);
+    method public abstract void onDialogClosed(boolean);
+    method protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder);
+    field protected static final java.lang.String ARG_KEY = "key";
+  }
+
+  public abstract class PreferenceFragment extends android.app.Fragment implements android.support.v7.preference.DialogPreference.TargetFragment android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener {
+    ctor public PreferenceFragment();
+    method public void addPreferencesFromResource(int);
+    method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+    method public final android.support.v7.widget.RecyclerView getListView();
+    method public android.support.v7.preference.PreferenceManager getPreferenceManager();
+    method public android.support.v7.preference.PreferenceScreen getPreferenceScreen();
+    method protected android.support.v7.widget.RecyclerView.Adapter onCreateAdapter(android.support.v7.preference.PreferenceScreen);
+    method public android.support.v7.widget.RecyclerView.LayoutManager onCreateLayoutManager();
+    method public abstract void onCreatePreferences(android.os.Bundle, java.lang.String);
+    method public android.support.v7.widget.RecyclerView onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method public void onDisplayPreferenceDialog(android.support.v7.preference.Preference);
+    method public void onNavigateToScreen(android.support.v7.preference.PreferenceScreen);
+    method public boolean onPreferenceTreeClick(android.support.v7.preference.Preference);
+    method public void scrollToPreference(java.lang.String);
+    method public void scrollToPreference(android.support.v7.preference.Preference);
+    method public void setDivider(android.graphics.drawable.Drawable);
+    method public void setDividerHeight(int);
+    method public void setPreferenceScreen(android.support.v7.preference.PreferenceScreen);
+    method public void setPreferencesFromResource(int, java.lang.String);
+    field public static final java.lang.String ARG_PREFERENCE_ROOT = "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT";
+  }
+
+  public static abstract interface PreferenceFragment.OnPreferenceDisplayDialogCallback {
+    method public abstract boolean onPreferenceDisplayDialog(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
+  }
+
+  public static abstract interface PreferenceFragment.OnPreferenceStartFragmentCallback {
+    method public abstract boolean onPreferenceStartFragment(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
+  }
+
+  public static abstract interface PreferenceFragment.OnPreferenceStartScreenCallback {
+    method public abstract boolean onPreferenceStartScreen(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.PreferenceScreen);
+  }
+
+  public class SwitchPreference extends android.support.v7.preference.TwoStatePreference {
+    ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public SwitchPreference(android.content.Context, android.util.AttributeSet);
+    ctor public SwitchPreference(android.content.Context);
+    method public java.lang.CharSequence getSwitchTextOff();
+    method public java.lang.CharSequence getSwitchTextOn();
+    method public void setSwitchTextOff(java.lang.CharSequence);
+    method public void setSwitchTextOff(int);
+    method public void setSwitchTextOn(java.lang.CharSequence);
+    method public void setSwitchTextOn(int);
+  }
+
+}
+
+package android.support.v17.leanback.app {
+
+  public final class BackgroundManager {
+    method public void attach(android.view.Window);
+    method public void attachToView(android.view.View);
+    method public void clearDrawable();
+    method public final int getColor();
+    method public deprecated android.graphics.drawable.Drawable getDefaultDimLayer();
+    method public deprecated android.graphics.drawable.Drawable getDimLayer();
+    method public android.graphics.drawable.Drawable getDrawable();
+    method public static android.support.v17.leanback.app.BackgroundManager getInstance(android.app.Activity);
+    method public boolean isAttached();
+    method public boolean isAutoReleaseOnStop();
+    method public void release();
+    method public void setAutoReleaseOnStop(boolean);
+    method public void setBitmap(android.graphics.Bitmap);
+    method public void setColor(int);
+    method public deprecated void setDimLayer(android.graphics.drawable.Drawable);
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setThemeDrawableResourceId(int);
+  }
+
+   abstract class BaseRowFragment extends android.app.Fragment {
+    method public final android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public final android.support.v17.leanback.widget.PresenterSelector getPresenterSelector();
+    method public int getSelectedPosition();
+    method public final android.support.v17.leanback.widget.VerticalGridView getVerticalGridView();
+    method public void onTransitionEnd();
+    method public boolean onTransitionPrepare();
+    method public void onTransitionStart();
+    method public final void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setAlignment(int);
+    method public final void setPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+    method public void setSelectedPosition(int);
+    method public void setSelectedPosition(int, boolean);
+  }
+
+   abstract class BaseRowSupportFragment extends android.support.v4.app.Fragment {
+    method public final android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public final android.support.v17.leanback.widget.PresenterSelector getPresenterSelector();
+    method public int getSelectedPosition();
+    method public final android.support.v17.leanback.widget.VerticalGridView getVerticalGridView();
+    method public void onTransitionEnd();
+    method public boolean onTransitionPrepare();
+    method public void onTransitionStart();
+    method public final void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setAlignment(int);
+    method public final void setPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+    method public void setSelectedPosition(int);
+    method public void setSelectedPosition(int, boolean);
+  }
+
+  public class BrandedFragment extends android.app.Fragment {
+    ctor public BrandedFragment();
+    method public android.graphics.drawable.Drawable getBadgeDrawable();
+    method public int getSearchAffordanceColor();
+    method public android.support.v17.leanback.widget.SearchOrbView.Colors getSearchAffordanceColors();
+    method public java.lang.CharSequence getTitle();
+    method public android.view.View getTitleView();
+    method public android.support.v17.leanback.widget.TitleViewAdapter getTitleViewAdapter();
+    method public void installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method public final boolean isShowingTitle();
+    method public android.view.View onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+    method public void setOnSearchClickedListener(android.view.View.OnClickListener);
+    method public void setSearchAffordanceColor(int);
+    method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setTitle(java.lang.CharSequence);
+    method public void setTitleView(android.view.View);
+    method public void showTitle(boolean);
+    method public void showTitle(int);
+  }
+
+  public class BrandedSupportFragment extends android.support.v4.app.Fragment {
+    ctor public BrandedSupportFragment();
+    method public android.graphics.drawable.Drawable getBadgeDrawable();
+    method public int getSearchAffordanceColor();
+    method public android.support.v17.leanback.widget.SearchOrbView.Colors getSearchAffordanceColors();
+    method public java.lang.CharSequence getTitle();
+    method public android.view.View getTitleView();
+    method public android.support.v17.leanback.widget.TitleViewAdapter getTitleViewAdapter();
+    method public void installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method public final boolean isShowingTitle();
+    method public android.view.View onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+    method public void setOnSearchClickedListener(android.view.View.OnClickListener);
+    method public void setSearchAffordanceColor(int);
+    method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setTitle(java.lang.CharSequence);
+    method public void setTitleView(android.view.View);
+    method public void showTitle(boolean);
+    method public void showTitle(int);
+  }
+
+  public class BrowseFragment extends android.support.v17.leanback.app.BrandedFragment {
+    ctor public BrowseFragment();
+    method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String, int);
+    method protected java.lang.Object createEntranceTransition();
+    method public void enableMainFragmentScaling(boolean);
+    method public deprecated void enableRowScaling(boolean);
+    method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public int getBrandColor();
+    method public android.support.v17.leanback.app.HeadersFragment getHeadersFragment();
+    method public int getHeadersState();
+    method public android.app.Fragment getMainFragment();
+    method public final android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapterRegistry getMainFragmentRegistry();
+    method public android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+    method public android.support.v17.leanback.widget.OnItemViewSelectedListener getOnItemViewSelectedListener();
+    method public android.support.v17.leanback.app.RowsFragment getRowsFragment();
+    method public int getSelectedPosition();
+    method public android.support.v17.leanback.widget.RowPresenter.ViewHolder getSelectedRowViewHolder();
+    method public final boolean isHeadersTransitionOnBackEnabled();
+    method public boolean isInHeadersTransition();
+    method public boolean isShowingHeaders();
+    method protected void onEntranceTransitionEnd();
+    method protected void onEntranceTransitionPrepare();
+    method protected void onEntranceTransitionStart();
+    method protected void runEntranceTransition(java.lang.Object);
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setBrandColor(int);
+    method public void setBrowseTransitionListener(android.support.v17.leanback.app.BrowseFragment.BrowseTransitionListener);
+    method public void setHeaderPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+    method public void setHeadersState(int);
+    method public final void setHeadersTransitionOnBackEnabled(boolean);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+    method public void setSelectedPosition(int);
+    method public void setSelectedPosition(int, boolean);
+    method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+    method public void startHeadersTransition(boolean);
+    field public static final int HEADERS_DISABLED = 3; // 0x3
+    field public static final int HEADERS_ENABLED = 1; // 0x1
+    field public static final int HEADERS_HIDDEN = 2; // 0x2
+  }
+
+  public static class BrowseFragment.BrowseTransitionListener {
+    ctor public BrowseFragment.BrowseTransitionListener();
+    method public void onHeadersTransitionStart(boolean);
+    method public void onHeadersTransitionStop(boolean);
+  }
+
+  public static abstract class BrowseFragment.FragmentFactory<T extends android.app.Fragment> {
+    ctor public BrowseFragment.FragmentFactory();
+    method public abstract T createFragment(java.lang.Object);
+  }
+
+  public static abstract interface BrowseFragment.FragmentHost {
+    method public abstract void notifyDataReady(android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter);
+    method public abstract void notifyViewCreated(android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter);
+    method public abstract void showTitleView(boolean);
+  }
+
+  public static class BrowseFragment.ListRowFragmentFactory extends android.support.v17.leanback.app.BrowseFragment.FragmentFactory {
+    ctor public BrowseFragment.ListRowFragmentFactory();
+    method public android.support.v17.leanback.app.RowsFragment createFragment(java.lang.Object);
+  }
+
+  public static class BrowseFragment.MainFragmentAdapter<T extends android.app.Fragment> {
+    ctor public BrowseFragment.MainFragmentAdapter(T);
+    method public final T getFragment();
+    method public final android.support.v17.leanback.app.BrowseFragment.FragmentHost getFragmentHost();
+    method public boolean isScalingEnabled();
+    method public boolean isScrolling();
+    method public void onTransitionEnd();
+    method public boolean onTransitionPrepare();
+    method public void onTransitionStart();
+    method public void setAlignment(int);
+    method public void setEntranceTransitionState(boolean);
+    method public void setExpand(boolean);
+    method public void setScalingEnabled(boolean);
+  }
+
+  public static abstract interface BrowseFragment.MainFragmentAdapterProvider {
+    method public abstract android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter getMainFragmentAdapter();
+  }
+
+  public static final class BrowseFragment.MainFragmentAdapterRegistry {
+    ctor public BrowseFragment.MainFragmentAdapterRegistry();
+    method public android.app.Fragment createFragment(java.lang.Object);
+    method public void registerFragment(java.lang.Class, android.support.v17.leanback.app.BrowseFragment.FragmentFactory);
+  }
+
+  public static class BrowseFragment.MainFragmentRowsAdapter<T extends android.app.Fragment> {
+    ctor public BrowseFragment.MainFragmentRowsAdapter(T);
+    method public android.support.v17.leanback.widget.RowPresenter.ViewHolder findRowViewHolderByPosition(int);
+    method public final T getFragment();
+    method public int getSelectedPosition();
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+    method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+    method public void setSelectedPosition(int, boolean);
+  }
+
+  public static abstract interface BrowseFragment.MainFragmentRowsAdapterProvider {
+    method public abstract android.support.v17.leanback.app.BrowseFragment.MainFragmentRowsAdapter getMainFragmentRowsAdapter();
+  }
+
+  public class BrowseSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
+    ctor public BrowseSupportFragment();
+    method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String, int);
+    method protected java.lang.Object createEntranceTransition();
+    method public void enableMainFragmentScaling(boolean);
+    method public deprecated void enableRowScaling(boolean);
+    method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public int getBrandColor();
+    method public int getHeadersState();
+    method public android.support.v17.leanback.app.HeadersSupportFragment getHeadersSupportFragment();
+    method public android.support.v4.app.Fragment getMainFragment();
+    method public final android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapterRegistry getMainFragmentRegistry();
+    method public android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+    method public android.support.v17.leanback.widget.OnItemViewSelectedListener getOnItemViewSelectedListener();
+    method public android.support.v17.leanback.app.RowsSupportFragment getRowsSupportFragment();
+    method public int getSelectedPosition();
+    method public android.support.v17.leanback.widget.RowPresenter.ViewHolder getSelectedRowViewHolder();
+    method public final boolean isHeadersTransitionOnBackEnabled();
+    method public boolean isInHeadersTransition();
+    method public boolean isShowingHeaders();
+    method protected void onEntranceTransitionEnd();
+    method protected void onEntranceTransitionPrepare();
+    method protected void onEntranceTransitionStart();
+    method protected void runEntranceTransition(java.lang.Object);
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setBrandColor(int);
+    method public void setBrowseTransitionListener(android.support.v17.leanback.app.BrowseSupportFragment.BrowseTransitionListener);
+    method public void setHeaderPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+    method public void setHeadersState(int);
+    method public final void setHeadersTransitionOnBackEnabled(boolean);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+    method public void setSelectedPosition(int);
+    method public void setSelectedPosition(int, boolean);
+    method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+    method public void startHeadersTransition(boolean);
+    field public static final int HEADERS_DISABLED = 3; // 0x3
+    field public static final int HEADERS_ENABLED = 1; // 0x1
+    field public static final int HEADERS_HIDDEN = 2; // 0x2
+  }
+
+  public static class BrowseSupportFragment.BrowseTransitionListener {
+    ctor public BrowseSupportFragment.BrowseTransitionListener();
+    method public void onHeadersTransitionStart(boolean);
+    method public void onHeadersTransitionStop(boolean);
+  }
+
+  public static abstract class BrowseSupportFragment.FragmentFactory<T extends android.support.v4.app.Fragment> {
+    ctor public BrowseSupportFragment.FragmentFactory();
+    method public abstract T createFragment(java.lang.Object);
+  }
+
+  public static abstract interface BrowseSupportFragment.FragmentHost {
+    method public abstract void notifyDataReady(android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter);
+    method public abstract void notifyViewCreated(android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter);
+    method public abstract void showTitleView(boolean);
+  }
+
+  public static class BrowseSupportFragment.ListRowFragmentFactory extends android.support.v17.leanback.app.BrowseSupportFragment.FragmentFactory {
+    ctor public BrowseSupportFragment.ListRowFragmentFactory();
+    method public android.support.v17.leanback.app.RowsSupportFragment createFragment(java.lang.Object);
+  }
+
+  public static class BrowseSupportFragment.MainFragmentAdapter<T extends android.support.v4.app.Fragment> {
+    ctor public BrowseSupportFragment.MainFragmentAdapter(T);
+    method public final T getFragment();
+    method public final android.support.v17.leanback.app.BrowseSupportFragment.FragmentHost getFragmentHost();
+    method public boolean isScalingEnabled();
+    method public boolean isScrolling();
+    method public void onTransitionEnd();
+    method public boolean onTransitionPrepare();
+    method public void onTransitionStart();
+    method public void setAlignment(int);
+    method public void setEntranceTransitionState(boolean);
+    method public void setExpand(boolean);
+    method public void setScalingEnabled(boolean);
+  }
+
+  public static abstract interface BrowseSupportFragment.MainFragmentAdapterProvider {
+    method public abstract android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter getMainFragmentAdapter();
+  }
+
+  public static final class BrowseSupportFragment.MainFragmentAdapterRegistry {
+    ctor public BrowseSupportFragment.MainFragmentAdapterRegistry();
+    method public android.support.v4.app.Fragment createFragment(java.lang.Object);
+    method public void registerFragment(java.lang.Class, android.support.v17.leanback.app.BrowseSupportFragment.FragmentFactory);
+  }
+
+  public static class BrowseSupportFragment.MainFragmentRowsAdapter<T extends android.support.v4.app.Fragment> {
+    ctor public BrowseSupportFragment.MainFragmentRowsAdapter(T);
+    method public android.support.v17.leanback.widget.RowPresenter.ViewHolder findRowViewHolderByPosition(int);
+    method public final T getFragment();
+    method public int getSelectedPosition();
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+    method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+    method public void setSelectedPosition(int, boolean);
+  }
+
+  public static abstract interface BrowseSupportFragment.MainFragmentRowsAdapterProvider {
+    method public abstract android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter getMainFragmentRowsAdapter();
+  }
+
+  public class DetailsFragment extends android.support.v17.leanback.app.BrandedFragment {
+    ctor public DetailsFragment();
+    method protected java.lang.Object createEntranceTransition();
+    method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+    method public android.support.v17.leanback.app.RowsFragment getRowsFragment();
+    method protected deprecated android.view.View inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method protected void onEntranceTransitionEnd();
+    method protected void onEntranceTransitionPrepare();
+    method protected void onEntranceTransitionStart();
+    method protected void onSetDetailsOverviewRowStatus(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int);
+    method protected void onSetRowStatus(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int);
+    method protected void runEntranceTransition(java.lang.Object);
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+    method public void setSelectedPosition(int);
+    method public void setSelectedPosition(int, boolean);
+    method protected void setupDetailsOverviewRowPresenter(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter);
+    method protected void setupPresenter(android.support.v17.leanback.widget.Presenter);
+  }
+
+  public class DetailsSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
+    ctor public DetailsSupportFragment();
+    method protected java.lang.Object createEntranceTransition();
+    method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+    method public android.support.v17.leanback.app.RowsSupportFragment getRowsSupportFragment();
+    method protected deprecated android.view.View inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method protected void onEntranceTransitionEnd();
+    method protected void onEntranceTransitionPrepare();
+    method protected void onEntranceTransitionStart();
+    method protected void onSetDetailsOverviewRowStatus(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int);
+    method protected void onSetRowStatus(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int);
+    method protected void runEntranceTransition(java.lang.Object);
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+    method public void setSelectedPosition(int);
+    method public void setSelectedPosition(int, boolean);
+    method protected void setupDetailsOverviewRowPresenter(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter);
+    method protected void setupPresenter(android.support.v17.leanback.widget.Presenter);
+  }
+
+  public class ErrorFragment extends android.support.v17.leanback.app.BrandedFragment {
+    ctor public ErrorFragment();
+    method public android.graphics.drawable.Drawable getBackgroundDrawable();
+    method public android.view.View.OnClickListener getButtonClickListener();
+    method public java.lang.String getButtonText();
+    method public android.graphics.drawable.Drawable getImageDrawable();
+    method public java.lang.CharSequence getMessage();
+    method public boolean isBackgroundTranslucent();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
+    method public void setButtonClickListener(android.view.View.OnClickListener);
+    method public void setButtonText(java.lang.String);
+    method public void setDefaultBackground(boolean);
+    method public void setImageDrawable(android.graphics.drawable.Drawable);
+    method public void setMessage(java.lang.CharSequence);
+  }
+
+  public class ErrorSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
+    ctor public ErrorSupportFragment();
+    method public android.graphics.drawable.Drawable getBackgroundDrawable();
+    method public android.view.View.OnClickListener getButtonClickListener();
+    method public java.lang.String getButtonText();
+    method public android.graphics.drawable.Drawable getImageDrawable();
+    method public java.lang.CharSequence getMessage();
+    method public boolean isBackgroundTranslucent();
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
+    method public void setButtonClickListener(android.view.View.OnClickListener);
+    method public void setButtonText(java.lang.String);
+    method public void setDefaultBackground(boolean);
+    method public void setImageDrawable(android.graphics.drawable.Drawable);
+    method public void setMessage(java.lang.CharSequence);
+  }
+
+  public class GuidedStepFragment extends android.app.Fragment {
+    ctor public GuidedStepFragment();
+    method public static int add(android.app.FragmentManager, android.support.v17.leanback.app.GuidedStepFragment);
+    method public static int add(android.app.FragmentManager, android.support.v17.leanback.app.GuidedStepFragment, int);
+    method public static int addAsRoot(android.app.Activity, android.support.v17.leanback.app.GuidedStepFragment, int);
+    method public void collapseAction(boolean);
+    method public void collapseSubActions();
+    method public void expandAction(android.support.v17.leanback.widget.GuidedAction, boolean);
+    method public void expandSubActions(android.support.v17.leanback.widget.GuidedAction);
+    method public android.support.v17.leanback.widget.GuidedAction findActionById(long);
+    method public int findActionPositionById(long);
+    method public android.support.v17.leanback.widget.GuidedAction findButtonActionById(long);
+    method public int findButtonActionPositionById(long);
+    method public void finishGuidedStepFragments();
+    method public android.view.View getActionItemView(int);
+    method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getActions();
+    method public android.view.View getButtonActionItemView(int);
+    method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getButtonActions();
+    method public static android.support.v17.leanback.app.GuidedStepFragment getCurrentGuidedStepFragment(android.app.FragmentManager);
+    method public android.support.v17.leanback.widget.GuidanceStylist getGuidanceStylist();
+    method public android.support.v17.leanback.widget.GuidedActionsStylist getGuidedActionsStylist();
+    method public android.support.v17.leanback.widget.GuidedActionsStylist getGuidedButtonActionsStylist();
+    method public int getSelectedActionPosition();
+    method public int getSelectedButtonActionPosition();
+    method public int getUiStyle();
+    method public boolean isExpanded();
+    method public boolean isFocusOutEndAllowed();
+    method public boolean isFocusOutStartAllowed();
+    method public boolean isSubActionsExpanded();
+    method public void notifyActionChanged(int);
+    method public void notifyButtonActionChanged(int);
+    method protected void onAddSharedElementTransition(android.app.FragmentTransaction, android.support.v17.leanback.app.GuidedStepFragment);
+    method public void onCreateActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>, android.os.Bundle);
+    method public android.support.v17.leanback.widget.GuidedActionsStylist onCreateActionsStylist();
+    method public android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method public void onCreateButtonActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>, android.os.Bundle);
+    method public android.support.v17.leanback.widget.GuidedActionsStylist onCreateButtonActionsStylist();
+    method public android.support.v17.leanback.widget.GuidanceStylist.Guidance onCreateGuidance(android.os.Bundle);
+    method public android.support.v17.leanback.widget.GuidanceStylist onCreateGuidanceStylist();
+    method public void onGuidedActionClicked(android.support.v17.leanback.widget.GuidedAction);
+    method public void onGuidedActionEditCanceled(android.support.v17.leanback.widget.GuidedAction);
+    method public deprecated void onGuidedActionEdited(android.support.v17.leanback.widget.GuidedAction);
+    method public long onGuidedActionEditedAndProceed(android.support.v17.leanback.widget.GuidedAction);
+    method public void onGuidedActionFocused(android.support.v17.leanback.widget.GuidedAction);
+    method protected void onProvideFragmentTransitions();
+    method public int onProvideTheme();
+    method public boolean onSubGuidedActionClicked(android.support.v17.leanback.widget.GuidedAction);
+    method public void popBackStackToGuidedStepFragment(java.lang.Class, int);
+    method public void setActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+    method public void setButtonActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+    method public void setSelectedActionPosition(int);
+    method public void setSelectedButtonActionPosition(int);
+    method public void setUiStyle(int);
+    field public static final java.lang.String EXTRA_UI_STYLE = "uiStyle";
+    field public static final int UI_STYLE_ACTIVITY_ROOT = 2; // 0x2
+    field public static final deprecated int UI_STYLE_DEFAULT = 0; // 0x0
+    field public static final int UI_STYLE_ENTRANCE = 1; // 0x1
+    field public static final int UI_STYLE_REPLACE = 0; // 0x0
+  }
+
+  public class GuidedStepSupportFragment extends android.support.v4.app.Fragment {
+    ctor public GuidedStepSupportFragment();
+    method public static int add(android.support.v4.app.FragmentManager, android.support.v17.leanback.app.GuidedStepSupportFragment);
+    method public static int add(android.support.v4.app.FragmentManager, android.support.v17.leanback.app.GuidedStepSupportFragment, int);
+    method public static int addAsRoot(android.support.v4.app.FragmentActivity, android.support.v17.leanback.app.GuidedStepSupportFragment, int);
+    method public void collapseAction(boolean);
+    method public void collapseSubActions();
+    method public void expandAction(android.support.v17.leanback.widget.GuidedAction, boolean);
+    method public void expandSubActions(android.support.v17.leanback.widget.GuidedAction);
+    method public android.support.v17.leanback.widget.GuidedAction findActionById(long);
+    method public int findActionPositionById(long);
+    method public android.support.v17.leanback.widget.GuidedAction findButtonActionById(long);
+    method public int findButtonActionPositionById(long);
+    method public void finishGuidedStepSupportFragments();
+    method public android.view.View getActionItemView(int);
+    method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getActions();
+    method public android.view.View getButtonActionItemView(int);
+    method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getButtonActions();
+    method public static android.support.v17.leanback.app.GuidedStepSupportFragment getCurrentGuidedStepSupportFragment(android.support.v4.app.FragmentManager);
+    method public android.support.v17.leanback.widget.GuidanceStylist getGuidanceStylist();
+    method public android.support.v17.leanback.widget.GuidedActionsStylist getGuidedActionsStylist();
+    method public android.support.v17.leanback.widget.GuidedActionsStylist getGuidedButtonActionsStylist();
+    method public int getSelectedActionPosition();
+    method public int getSelectedButtonActionPosition();
+    method public int getUiStyle();
+    method public boolean isExpanded();
+    method public boolean isFocusOutEndAllowed();
+    method public boolean isFocusOutStartAllowed();
+    method public boolean isSubActionsExpanded();
+    method public void notifyActionChanged(int);
+    method public void notifyButtonActionChanged(int);
+    method protected void onAddSharedElementTransition(android.support.v4.app.FragmentTransaction, android.support.v17.leanback.app.GuidedStepSupportFragment);
+    method public void onCreateActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>, android.os.Bundle);
+    method public android.support.v17.leanback.widget.GuidedActionsStylist onCreateActionsStylist();
+    method public android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method public void onCreateButtonActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>, android.os.Bundle);
+    method public android.support.v17.leanback.widget.GuidedActionsStylist onCreateButtonActionsStylist();
+    method public android.support.v17.leanback.widget.GuidanceStylist.Guidance onCreateGuidance(android.os.Bundle);
+    method public android.support.v17.leanback.widget.GuidanceStylist onCreateGuidanceStylist();
+    method public void onGuidedActionClicked(android.support.v17.leanback.widget.GuidedAction);
+    method public void onGuidedActionEditCanceled(android.support.v17.leanback.widget.GuidedAction);
+    method public deprecated void onGuidedActionEdited(android.support.v17.leanback.widget.GuidedAction);
+    method public long onGuidedActionEditedAndProceed(android.support.v17.leanback.widget.GuidedAction);
+    method public void onGuidedActionFocused(android.support.v17.leanback.widget.GuidedAction);
+    method protected void onProvideFragmentTransitions();
+    method public int onProvideTheme();
+    method public boolean onSubGuidedActionClicked(android.support.v17.leanback.widget.GuidedAction);
+    method public void popBackStackToGuidedStepSupportFragment(java.lang.Class, int);
+    method public void setActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+    method public void setButtonActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+    method public void setSelectedActionPosition(int);
+    method public void setSelectedButtonActionPosition(int);
+    method public void setUiStyle(int);
+    field public static final java.lang.String EXTRA_UI_STYLE = "uiStyle";
+    field public static final int UI_STYLE_ACTIVITY_ROOT = 2; // 0x2
+    field public static final deprecated int UI_STYLE_DEFAULT = 0; // 0x0
+    field public static final int UI_STYLE_ENTRANCE = 1; // 0x1
+    field public static final int UI_STYLE_REPLACE = 0; // 0x0
+  }
+
+  public class HeadersFragment extends android.support.v17.leanback.app.BaseRowFragment {
+    ctor public HeadersFragment();
+    method public boolean isScrolling();
+    method public void setOnHeaderClickedListener(android.support.v17.leanback.app.HeadersFragment.OnHeaderClickedListener);
+    method public void setOnHeaderViewSelectedListener(android.support.v17.leanback.app.HeadersFragment.OnHeaderViewSelectedListener);
+  }
+
+  public static abstract interface HeadersFragment.OnHeaderClickedListener {
+    method public abstract void onHeaderClicked(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, android.support.v17.leanback.widget.Row);
+  }
+
+  public static abstract interface HeadersFragment.OnHeaderViewSelectedListener {
+    method public abstract void onHeaderSelected(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, android.support.v17.leanback.widget.Row);
+  }
+
+  public class HeadersSupportFragment extends android.support.v17.leanback.app.BaseRowSupportFragment {
+    ctor public HeadersSupportFragment();
+    method public boolean isScrolling();
+    method public void setOnHeaderClickedListener(android.support.v17.leanback.app.HeadersSupportFragment.OnHeaderClickedListener);
+    method public void setOnHeaderViewSelectedListener(android.support.v17.leanback.app.HeadersSupportFragment.OnHeaderViewSelectedListener);
+  }
+
+  public static abstract interface HeadersSupportFragment.OnHeaderClickedListener {
+    method public abstract void onHeaderClicked(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, android.support.v17.leanback.widget.Row);
+  }
+
+  public static abstract interface HeadersSupportFragment.OnHeaderViewSelectedListener {
+    method public abstract void onHeaderSelected(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, android.support.v17.leanback.widget.Row);
+  }
+
+  public abstract deprecated class MediaControllerGlue extends android.support.v17.leanback.app.PlaybackControlGlue {
+    ctor public MediaControllerGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[]);
+    ctor public MediaControllerGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[], int[]);
+    method public void attachToMediaController(android.support.v4.media.session.MediaControllerCompat);
+    method public void detach();
+    method public int getCurrentPosition();
+    method public int getCurrentSpeedId();
+    method public android.graphics.drawable.Drawable getMediaArt();
+    method public final android.support.v4.media.session.MediaControllerCompat getMediaController();
+    method public int getMediaDuration();
+    method public java.lang.CharSequence getMediaSubtitle();
+    method public java.lang.CharSequence getMediaTitle();
+    method public long getSupportedActions();
+    method public boolean hasValidMedia();
+    method public boolean isMediaPlaying();
+  }
+
+  public abstract class OnboardingFragment extends android.app.Fragment {
+    ctor public OnboardingFragment();
+    method protected final int getCurrentPageIndex();
+    method public final int getIconResourceId();
+    method public final int getLogoResourceId();
+    method protected abstract int getPageCount();
+    method protected abstract java.lang.CharSequence getPageDescription(int);
+    method protected abstract java.lang.CharSequence getPageTitle(int);
+    method protected abstract android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected abstract android.view.View onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateDescriptionAnimator();
+    method protected android.animation.Animator onCreateEnterAnimation();
+    method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateLogoAnimation();
+    method protected android.animation.Animator onCreateTitleAnimator();
+    method protected void onFinishFragment();
+    method protected void onPageChanged(int, int);
+    method public int onProvideTheme();
+    method public final void setIconResouceId(int);
+    method public final void setLogoResourceId(int);
+  }
+
+  public abstract class OnboardingSupportFragment extends android.support.v4.app.Fragment {
+    ctor public OnboardingSupportFragment();
+    method protected final int getCurrentPageIndex();
+    method public final int getIconResourceId();
+    method public final int getLogoResourceId();
+    method protected abstract int getPageCount();
+    method protected abstract java.lang.CharSequence getPageDescription(int);
+    method protected abstract java.lang.CharSequence getPageTitle(int);
+    method protected abstract android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected abstract android.view.View onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateDescriptionAnimator();
+    method protected android.animation.Animator onCreateEnterAnimation();
+    method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateLogoAnimation();
+    method protected android.animation.Animator onCreateTitleAnimator();
+    method protected void onFinishFragment();
+    method protected void onPageChanged(int, int);
+    method public int onProvideTheme();
+    method public final void setIconResouceId(int);
+    method public final void setLogoResourceId(int);
+  }
+
+  public abstract deprecated class PlaybackControlGlue extends android.support.v17.leanback.media.PlaybackControlGlue {
+    ctor public PlaybackControlGlue(android.content.Context, int[]);
+    ctor public PlaybackControlGlue(android.content.Context, int[], int[]);
+    ctor public PlaybackControlGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[]);
+    ctor public PlaybackControlGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[], int[]);
+    method public android.support.v17.leanback.widget.PlaybackControlsRowPresenter createControlsRowAndPresenter();
+    method protected android.support.v17.leanback.widget.SparseArrayObjectAdapter createPrimaryActionsAdapter(android.support.v17.leanback.widget.PresenterSelector);
+    method public android.support.v17.leanback.app.PlaybackOverlayFragment getFragment();
+    method public deprecated android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+    method public final void next();
+    method protected void onRowChanged(android.support.v17.leanback.widget.PlaybackControlsRow);
+    method public final void pause();
+    method protected deprecated void pausePlayback();
+    method public final void play(int);
+    method public final void previous();
+    method public deprecated void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method protected deprecated void skipToNext();
+    method protected deprecated void skipToPrevious();
+    method protected deprecated void startPlayback(int);
+  }
+
+  public static abstract deprecated interface PlaybackControlGlue.InputEventHandler {
+    method public abstract boolean handleInputEvent(android.view.InputEvent);
+  }
+
+  public abstract deprecated class PlaybackControlSupportGlue extends android.support.v17.leanback.app.PlaybackControlGlue {
+    ctor public PlaybackControlSupportGlue(android.content.Context, int[]);
+    ctor public PlaybackControlSupportGlue(android.content.Context, int[], int[]);
+    ctor public PlaybackControlSupportGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlaySupportFragment, int[]);
+    ctor public PlaybackControlSupportGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlaySupportFragment, int[], int[]);
+    field public static final int ACTION_CUSTOM_LEFT_FIRST = 1; // 0x1
+    field public static final int ACTION_CUSTOM_RIGHT_FIRST = 4096; // 0x1000
+    field public static final int ACTION_FAST_FORWARD = 128; // 0x80
+    field public static final int ACTION_PLAY_PAUSE = 64; // 0x40
+    field public static final int ACTION_REWIND = 32; // 0x20
+    field public static final int ACTION_SKIP_TO_NEXT = 256; // 0x100
+    field public static final int ACTION_SKIP_TO_PREVIOUS = 16; // 0x10
+    field public static final int PLAYBACK_SPEED_FAST_L0 = 10; // 0xa
+    field public static final int PLAYBACK_SPEED_FAST_L1 = 11; // 0xb
+    field public static final int PLAYBACK_SPEED_FAST_L2 = 12; // 0xc
+    field public static final int PLAYBACK_SPEED_FAST_L3 = 13; // 0xd
+    field public static final int PLAYBACK_SPEED_FAST_L4 = 14; // 0xe
+    field public static final int PLAYBACK_SPEED_INVALID = -1; // 0xffffffff
+    field public static final int PLAYBACK_SPEED_NORMAL = 1; // 0x1
+    field public static final int PLAYBACK_SPEED_PAUSED = 0; // 0x0
+  }
+
+  public class PlaybackFragment extends android.app.Fragment {
+    ctor public PlaybackFragment();
+    method public void fadeOut();
+    method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public int getBackgroundType();
+    method public boolean isFadingEnabled();
+    method public void notifyPlaybackRowChanged();
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setBackgroundType(int);
+    method public void setFadingEnabled(boolean);
+    method public void setHostCallback(android.support.v17.leanback.media.PlaybackGlueHost.HostCallback);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+    method public final void setOnKeyInterceptListener(android.view.View.OnKeyListener);
+    method public void setOnPlaybackItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+    method public void setPlaybackRow(android.support.v17.leanback.widget.Row);
+    method public void setPlaybackRowPresenter(android.support.v17.leanback.widget.PlaybackRowPresenter);
+    method public void setSelectedPosition(int);
+    method public void setSelectedPosition(int, boolean);
+    method public void tickle();
+    field public static final int BG_DARK = 1; // 0x1
+    field public static final int BG_LIGHT = 2; // 0x2
+    field public static final int BG_NONE = 0; // 0x0
+  }
+
+  public class PlaybackFragmentGlueHost extends android.support.v17.leanback.media.PlaybackGlueHost {
+    ctor public PlaybackFragmentGlueHost(android.support.v17.leanback.app.PlaybackFragment);
+  }
+
+  public deprecated class PlaybackOverlayFragment extends android.support.v17.leanback.app.DetailsFragment {
+    ctor public PlaybackOverlayFragment();
+    method public void fadeOut();
+    method public int getBackgroundType();
+    method public final android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler getEventHandler();
+    method public android.support.v17.leanback.app.PlaybackOverlayFragment.OnFadeCompleteListener getFadeCompleteListener();
+    method public final deprecated android.support.v17.leanback.app.PlaybackOverlayFragment.InputEventHandler getInputEventHandler();
+    method public boolean isFadingEnabled();
+    method public void setBackgroundType(int);
+    method public final void setEventHandler(android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler);
+    method public void setFadeCompleteListener(android.support.v17.leanback.app.PlaybackOverlayFragment.OnFadeCompleteListener);
+    method public void setFadingEnabled(boolean);
+    method public final deprecated void setInputEventHandler(android.support.v17.leanback.app.PlaybackOverlayFragment.InputEventHandler);
+    method public void tickle();
+    field public static final int BG_DARK = 1; // 0x1
+    field public static final int BG_LIGHT = 2; // 0x2
+    field public static final int BG_NONE = 0; // 0x0
+  }
+
+  public static abstract deprecated interface PlaybackOverlayFragment.InputEventHandler implements android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler {
+  }
+
+  public static class PlaybackOverlayFragment.OnFadeCompleteListener {
+    ctor public PlaybackOverlayFragment.OnFadeCompleteListener();
+    method public void onFadeInComplete();
+    method public void onFadeOutComplete();
+  }
+
+  public deprecated class PlaybackOverlaySupportFragment extends android.support.v17.leanback.app.DetailsSupportFragment {
+    ctor public PlaybackOverlaySupportFragment();
+    method public void fadeOut();
+    method public int getBackgroundType();
+    method public final android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler getEventHandler();
+    method public android.support.v17.leanback.app.PlaybackOverlaySupportFragment.OnFadeCompleteListener getFadeCompleteListener();
+    method public final deprecated android.support.v17.leanback.app.PlaybackOverlaySupportFragment.InputEventHandler getInputEventHandler();
+    method public boolean isFadingEnabled();
+    method public void setBackgroundType(int);
+    method public final void setEventHandler(android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler);
+    method public void setFadeCompleteListener(android.support.v17.leanback.app.PlaybackOverlaySupportFragment.OnFadeCompleteListener);
+    method public void setFadingEnabled(boolean);
+    method public final deprecated void setInputEventHandler(android.support.v17.leanback.app.PlaybackOverlaySupportFragment.InputEventHandler);
+    method public void tickle();
+    field public static final int BG_DARK = 1; // 0x1
+    field public static final int BG_LIGHT = 2; // 0x2
+    field public static final int BG_NONE = 0; // 0x0
+  }
+
+  public static abstract deprecated interface PlaybackOverlaySupportFragment.InputEventHandler implements android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler {
+  }
+
+  public static class PlaybackOverlaySupportFragment.OnFadeCompleteListener {
+    ctor public PlaybackOverlaySupportFragment.OnFadeCompleteListener();
+    method public void onFadeInComplete();
+    method public void onFadeOutComplete();
+  }
+
+  public class PlaybackSupportFragment extends android.support.v4.app.Fragment {
+    ctor public PlaybackSupportFragment();
+    method public void fadeOut();
+    method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public int getBackgroundType();
+    method public boolean isFadingEnabled();
+    method public void notifyPlaybackRowChanged();
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setBackgroundType(int);
+    method public void setFadingEnabled(boolean);
+    method public void setHostCallback(android.support.v17.leanback.media.PlaybackGlueHost.HostCallback);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+    method public final void setOnKeyInterceptListener(android.view.View.OnKeyListener);
+    method public void setOnPlaybackItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+    method public void setPlaybackRow(android.support.v17.leanback.widget.Row);
+    method public void setPlaybackRowPresenter(android.support.v17.leanback.widget.PlaybackRowPresenter);
+    method public void setSelectedPosition(int);
+    method public void setSelectedPosition(int, boolean);
+    method public void tickle();
+    field public static final int BG_DARK = 1; // 0x1
+    field public static final int BG_LIGHT = 2; // 0x2
+    field public static final int BG_NONE = 0; // 0x0
+  }
+
+  public class PlaybackSupportFragmentGlueHost extends android.support.v17.leanback.media.PlaybackGlueHost {
+    ctor public PlaybackSupportFragmentGlueHost(android.support.v17.leanback.app.PlaybackSupportFragment);
+  }
+
+  public final class ProgressBarManager {
+    ctor public ProgressBarManager();
+    method public void disableProgressBar();
+    method public void enableProgressBar();
+    method public long getInitialDelay();
+    method public void hide();
+    method public void setInitialDelay(long);
+    method public void setProgressBarView(android.view.View);
+    method public void setRootView(android.view.ViewGroup);
+    method public void show();
+  }
+
+  public class RowsFragment extends android.support.v17.leanback.app.BaseRowFragment implements android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapterProvider android.support.v17.leanback.app.BrowseFragment.MainFragmentRowsAdapterProvider {
+    ctor public RowsFragment();
+    method public deprecated void enableRowScaling(boolean);
+    method protected android.support.v17.leanback.widget.VerticalGridView findGridViewFromRoot(android.view.View);
+    method public android.support.v17.leanback.widget.RowPresenter.ViewHolder findRowViewHolderByPosition(int);
+    method public android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter getMainFragmentAdapter();
+    method public android.support.v17.leanback.app.BrowseFragment.MainFragmentRowsAdapter getMainFragmentRowsAdapter();
+    method public android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+    method public android.support.v17.leanback.widget.BaseOnItemViewSelectedListener getOnItemViewSelectedListener();
+    method public android.support.v17.leanback.widget.RowPresenter.ViewHolder getRowViewHolder(int);
+    method public boolean isScrolling();
+    method public void setEntranceTransitionState(boolean);
+    method public void setExpand(boolean);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+    method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+  }
+
+  public static class RowsFragment.MainFragmentAdapter extends android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter {
+    ctor public RowsFragment.MainFragmentAdapter(android.support.v17.leanback.app.RowsFragment);
+  }
+
+  public static class RowsFragment.MainFragmentRowsAdapter extends android.support.v17.leanback.app.BrowseFragment.MainFragmentRowsAdapter {
+    ctor public RowsFragment.MainFragmentRowsAdapter(android.support.v17.leanback.app.RowsFragment);
+  }
+
+  public class RowsSupportFragment extends android.support.v17.leanback.app.BaseRowSupportFragment implements android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapterProvider android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapterProvider {
+    ctor public RowsSupportFragment();
+    method public deprecated void enableRowScaling(boolean);
+    method protected android.support.v17.leanback.widget.VerticalGridView findGridViewFromRoot(android.view.View);
+    method public android.support.v17.leanback.widget.RowPresenter.ViewHolder findRowViewHolderByPosition(int);
+    method public android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter getMainFragmentAdapter();
+    method public android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter getMainFragmentRowsAdapter();
+    method public android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+    method public android.support.v17.leanback.widget.BaseOnItemViewSelectedListener getOnItemViewSelectedListener();
+    method public android.support.v17.leanback.widget.RowPresenter.ViewHolder getRowViewHolder(int);
+    method public boolean isScrolling();
+    method public void setEntranceTransitionState(boolean);
+    method public void setExpand(boolean);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+    method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+  }
+
+  public static class RowsSupportFragment.MainFragmentAdapter extends android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter {
+    ctor public RowsSupportFragment.MainFragmentAdapter(android.support.v17.leanback.app.RowsSupportFragment);
+  }
+
+  public static class RowsSupportFragment.MainFragmentRowsAdapter extends android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter {
+    ctor public RowsSupportFragment.MainFragmentRowsAdapter(android.support.v17.leanback.app.RowsSupportFragment);
+  }
+
+  public class SearchFragment extends android.app.Fragment {
+    ctor public SearchFragment();
+    method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String);
+    method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String, java.lang.String);
+    method public void displayCompletions(java.util.List<java.lang.String>);
+    method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
+    method public android.graphics.drawable.Drawable getBadgeDrawable();
+    method public android.content.Intent getRecognizerIntent();
+    method public java.lang.String getTitle();
+    method public static android.support.v17.leanback.app.SearchFragment newInstance(java.lang.String);
+    method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+    method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setSearchAffordanceColorsInListening(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setSearchQuery(java.lang.String, boolean);
+    method public void setSearchQuery(android.content.Intent, boolean);
+    method public void setSearchResultProvider(android.support.v17.leanback.app.SearchFragment.SearchResultProvider);
+    method public void setSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback);
+    method public void setTitle(java.lang.String);
+    method public void startRecognition();
+  }
+
+  public static abstract interface SearchFragment.SearchResultProvider {
+    method public abstract android.support.v17.leanback.widget.ObjectAdapter getResultsAdapter();
+    method public abstract boolean onQueryTextChange(java.lang.String);
+    method public abstract boolean onQueryTextSubmit(java.lang.String);
+  }
+
+  public class SearchSupportFragment extends android.support.v4.app.Fragment {
+    ctor public SearchSupportFragment();
+    method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String);
+    method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String, java.lang.String);
+    method public void displayCompletions(java.util.List<java.lang.String>);
+    method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
+    method public android.graphics.drawable.Drawable getBadgeDrawable();
+    method public android.content.Intent getRecognizerIntent();
+    method public java.lang.String getTitle();
+    method public static android.support.v17.leanback.app.SearchSupportFragment newInstance(java.lang.String);
+    method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+    method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setSearchAffordanceColorsInListening(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setSearchQuery(java.lang.String, boolean);
+    method public void setSearchQuery(android.content.Intent, boolean);
+    method public void setSearchResultProvider(android.support.v17.leanback.app.SearchSupportFragment.SearchResultProvider);
+    method public void setSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback);
+    method public void setTitle(java.lang.String);
+    method public void startRecognition();
+  }
+
+  public static abstract interface SearchSupportFragment.SearchResultProvider {
+    method public abstract android.support.v17.leanback.widget.ObjectAdapter getResultsAdapter();
+    method public abstract boolean onQueryTextChange(java.lang.String);
+    method public abstract boolean onQueryTextSubmit(java.lang.String);
+  }
+
+  public class VerticalGridFragment extends android.support.v17.leanback.app.BrandedFragment {
+    ctor public VerticalGridFragment();
+    method protected java.lang.Object createEntranceTransition();
+    method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public android.support.v17.leanback.widget.VerticalGridPresenter getGridPresenter();
+    method public android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+    method protected void runEntranceTransition(java.lang.Object);
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setGridPresenter(android.support.v17.leanback.widget.VerticalGridPresenter);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+    method public void setSelectedPosition(int);
+  }
+
+  public class VerticalGridSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
+    ctor public VerticalGridSupportFragment();
+    method protected java.lang.Object createEntranceTransition();
+    method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public android.support.v17.leanback.widget.VerticalGridPresenter getGridPresenter();
+    method public android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+    method protected void runEntranceTransition(java.lang.Object);
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setGridPresenter(android.support.v17.leanback.widget.VerticalGridPresenter);
+    method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+    method public void setSelectedPosition(int);
+  }
+
+}
+
+package android.support.v17.leanback.database {
+
+  public abstract class CursorMapper {
+    ctor public CursorMapper();
+    method protected abstract java.lang.Object bind(android.database.Cursor);
+    method protected abstract void bindColumns(android.database.Cursor);
+    method public java.lang.Object convert(android.database.Cursor);
+  }
+
+}
+
+package android.support.v17.leanback.graphics {
+
+  public final class ColorFilterCache {
+    method public static android.support.v17.leanback.graphics.ColorFilterCache getColorFilterCache(int);
+    method public android.graphics.ColorFilter getFilterForLevel(float);
+  }
+
+  public final class ColorFilterDimmer {
+    method public void applyFilterToView(android.view.View);
+    method public static android.support.v17.leanback.graphics.ColorFilterDimmer create(android.support.v17.leanback.graphics.ColorFilterCache, float, float);
+    method public static android.support.v17.leanback.graphics.ColorFilterDimmer createDefault(android.content.Context);
+    method public android.graphics.ColorFilter getColorFilter();
+    method public android.graphics.Paint getPaint();
+    method public void setActiveLevel(float);
+  }
+
+  public final class ColorOverlayDimmer {
+    method public int applyToColor(int);
+    method public static android.support.v17.leanback.graphics.ColorOverlayDimmer createColorOverlayDimmer(int, float, float);
+    method public static android.support.v17.leanback.graphics.ColorOverlayDimmer createDefault(android.content.Context);
+    method public void drawColorOverlay(android.graphics.Canvas, android.view.View, boolean);
+    method public int getAlpha();
+    method public float getAlphaFloat();
+    method public android.graphics.Paint getPaint();
+    method public boolean needsDraw();
+    method public void setActiveLevel(float);
+  }
+
+}
+
+package android.support.v17.leanback.media {
+
+  public abstract class MediaControllerGlue extends android.support.v17.leanback.media.PlaybackControlGlue {
+    ctor public MediaControllerGlue(android.content.Context, int[], int[]);
+    method public void attachToMediaController(android.support.v4.media.session.MediaControllerCompat);
+    method public void detach();
+    method public int getCurrentPosition();
+    method public int getCurrentSpeedId();
+    method public android.graphics.drawable.Drawable getMediaArt();
+    method public final android.support.v4.media.session.MediaControllerCompat getMediaController();
+    method public int getMediaDuration();
+    method public java.lang.CharSequence getMediaSubtitle();
+    method public java.lang.CharSequence getMediaTitle();
+    method public long getSupportedActions();
+    method public boolean hasValidMedia();
+    method public boolean isMediaPlaying();
+  }
+
+  public abstract class PlaybackControlGlue extends android.support.v17.leanback.media.PlaybackGlue implements android.support.v17.leanback.widget.OnActionClickedListener android.view.View.OnKeyListener {
+    ctor public PlaybackControlGlue(android.content.Context, int[]);
+    ctor public PlaybackControlGlue(android.content.Context, int[], int[]);
+    method public void enableProgressUpdating(boolean);
+    method public android.support.v17.leanback.widget.PlaybackControlsRow getControlsRow();
+    method public android.support.v17.leanback.widget.PlaybackControlsRowPresenter getControlsRowPresenter();
+    method public abstract int getCurrentPosition();
+    method public abstract int getCurrentSpeedId();
+    method public int[] getFastForwardSpeeds();
+    method public abstract android.graphics.drawable.Drawable getMediaArt();
+    method public abstract int getMediaDuration();
+    method public abstract java.lang.CharSequence getMediaSubtitle();
+    method public abstract java.lang.CharSequence getMediaTitle();
+    method public int[] getRewindSpeeds();
+    method public abstract long getSupportedActions();
+    method public int getUpdatePeriod();
+    method public abstract boolean hasValidMedia();
+    method public boolean isFadingEnabled();
+    method public abstract boolean isMediaPlaying();
+    method public void onActionClicked(android.support.v17.leanback.widget.Action);
+    method protected void onCreateControlsRowAndPresenter();
+    method protected void onCreatePrimaryActions(android.support.v17.leanback.widget.SparseArrayObjectAdapter);
+    method protected void onCreateSecondaryActions(android.support.v17.leanback.widget.ArrayObjectAdapter);
+    method public boolean onKey(android.view.View, int, android.view.KeyEvent);
+    method protected void onMetadataChanged();
+    method protected void onStateChanged();
+    method public void play(int);
+    method public final void play();
+    method public void setControlsRow(android.support.v17.leanback.widget.PlaybackControlsRow);
+    method public void setControlsRowPresenter(android.support.v17.leanback.widget.PlaybackControlsRowPresenter);
+    method public void setFadingEnabled(boolean);
+    method public void updateProgress();
+    field public static final int ACTION_CUSTOM_LEFT_FIRST = 1; // 0x1
+    field public static final int ACTION_CUSTOM_RIGHT_FIRST = 4096; // 0x1000
+    field public static final int ACTION_FAST_FORWARD = 128; // 0x80
+    field public static final int ACTION_PLAY_PAUSE = 64; // 0x40
+    field public static final int ACTION_REWIND = 32; // 0x20
+    field public static final int ACTION_SKIP_TO_NEXT = 256; // 0x100
+    field public static final int ACTION_SKIP_TO_PREVIOUS = 16; // 0x10
+    field public static final int PLAYBACK_SPEED_FAST_L0 = 10; // 0xa
+    field public static final int PLAYBACK_SPEED_FAST_L1 = 11; // 0xb
+    field public static final int PLAYBACK_SPEED_FAST_L2 = 12; // 0xc
+    field public static final int PLAYBACK_SPEED_FAST_L3 = 13; // 0xd
+    field public static final int PLAYBACK_SPEED_FAST_L4 = 14; // 0xe
+    field public static final int PLAYBACK_SPEED_INVALID = -1; // 0xffffffff
+    field public static final int PLAYBACK_SPEED_NORMAL = 1; // 0x1
+    field public static final int PLAYBACK_SPEED_PAUSED = 0; // 0x0
+  }
+
+  public abstract class PlaybackGlue {
+    ctor public PlaybackGlue(android.content.Context);
+    method public android.content.Context getContext();
+    method public android.support.v17.leanback.media.PlaybackGlueHost getHost();
+    method public boolean isReadyForPlayback();
+    method public void next();
+    method protected void onAttachedToHost(android.support.v17.leanback.media.PlaybackGlueHost);
+    method protected void onDetachedFromHost();
+    method protected void onHostPause();
+    method protected void onHostResume();
+    method protected void onHostStart();
+    method protected void onHostStop();
+    method public void pause();
+    method public void play();
+    method public void previous();
+    method public final void setHost(android.support.v17.leanback.media.PlaybackGlueHost);
+    method public void setPlayerCallback(android.support.v17.leanback.media.PlaybackGlue.PlayerCallback);
+  }
+
+  public static abstract class PlaybackGlue.PlayerCallback {
+    ctor public PlaybackGlue.PlayerCallback();
+    method public abstract void onReadyForPlayback();
+  }
+
+  public abstract class PlaybackGlueHost {
+    ctor public PlaybackGlueHost();
+    method public void fadeOut();
+    method public void notifyPlaybackRowChanged();
+    method public void setFadingEnabled(boolean);
+    method public void setHostCallback(android.support.v17.leanback.media.PlaybackGlueHost.HostCallback);
+    method public void setOnActionClickedListener(android.support.v17.leanback.widget.OnActionClickedListener);
+    method public void setOnKeyInterceptListener(android.view.View.OnKeyListener);
+    method public void setPlaybackRow(android.support.v17.leanback.widget.Row);
+    method public void setPlaybackRowPresenter(android.support.v17.leanback.widget.PlaybackRowPresenter);
+  }
+
+  public static abstract class PlaybackGlueHost.HostCallback {
+    ctor public PlaybackGlueHost.HostCallback();
+    method public void onHostPause();
+    method public void onHostResume();
+    method public void onHostStart();
+    method public void onHostStop();
+  }
+
+  public abstract interface SurfaceHolderGlueHost {
+    method public abstract void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+  }
+
+}
+
+package android.support.v17.leanback.system {
+
+  public class Settings {
+    method public boolean getBoolean(java.lang.String);
+    method public static android.support.v17.leanback.system.Settings getInstance(android.content.Context);
+    method public void setBoolean(java.lang.String, boolean);
+    field public static final java.lang.String PREFER_STATIC_SHADOWS = "PREFER_STATIC_SHADOWS";
+  }
+
+}
+
+package android.support.v17.leanback.widget {
+
+  public abstract class AbstractDetailsDescriptionPresenter extends android.support.v17.leanback.widget.Presenter {
+    ctor public AbstractDetailsDescriptionPresenter();
+    method protected abstract void onBindDescription(android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder, java.lang.Object);
+    method public final void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+    method public final android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+    method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+  }
+
+  public static class AbstractDetailsDescriptionPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+    ctor public AbstractDetailsDescriptionPresenter.ViewHolder(android.view.View);
+    method public android.widget.TextView getBody();
+    method public android.widget.TextView getSubtitle();
+    method public android.widget.TextView getTitle();
+  }
+
+  public abstract class AbstractMediaItemPresenter extends android.support.v17.leanback.widget.RowPresenter {
+    ctor public AbstractMediaItemPresenter();
+    ctor public AbstractMediaItemPresenter(int);
+    method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+    method public android.support.v17.leanback.widget.Presenter getActionPresenter();
+    method protected int getMediaPlayState(java.lang.Object);
+    method public int getThemeId();
+    method public boolean hasMediaRowSeparator();
+    method protected abstract void onBindMediaDetails(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder, java.lang.Object);
+    method public void onBindMediaPlayState(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder);
+    method protected void onBindRowActions(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder);
+    method protected void onUnbindMediaDetails(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder);
+    method public void onUnbindMediaPlayState(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder);
+    method public void setActionPresenter(android.support.v17.leanback.widget.Presenter);
+    method public void setBackgroundColor(int);
+    method public void setHasMediaRowSeparator(boolean);
+    method public void setThemeId(int);
+    field public static final int PLAY_STATE_INITIAL = 0; // 0x0
+    field public static final int PLAY_STATE_PAUSED = 1; // 0x1
+    field public static final int PLAY_STATE_PLAYING = 2; // 0x2
+  }
+
+  public static class AbstractMediaItemPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+    ctor public AbstractMediaItemPresenter.ViewHolder(android.view.View);
+    method public android.view.ViewGroup getMediaItemActionsContainer();
+    method public android.view.View getMediaItemDetailsView();
+    method public android.widget.TextView getMediaItemDurationView();
+    method public android.widget.TextView getMediaItemNameView();
+    method public android.widget.TextView getMediaItemNumberView();
+    method public android.widget.ViewFlipper getMediaItemNumberViewFlipper();
+    method public android.view.View getMediaItemPausedView();
+    method public android.view.View getMediaItemPlayingView();
+    method public android.support.v17.leanback.widget.MultiActionsProvider.MultiAction[] getMediaItemRowActions();
+    method public android.view.View getMediaItemRowSeparator();
+    method public android.view.View getSelectorView();
+    method public void notifyActionChanged(android.support.v17.leanback.widget.MultiActionsProvider.MultiAction);
+    method public void notifyDetailsChanged();
+    method public void notifyPlayStateChanged();
+    method public void onBindRowActions();
+    method public void setSelectedMediaItemNumberView(int);
+  }
+
+  public abstract class AbstractMediaListHeaderPresenter extends android.support.v17.leanback.widget.RowPresenter {
+    ctor public AbstractMediaListHeaderPresenter(android.content.Context, int);
+    ctor public AbstractMediaListHeaderPresenter();
+    method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+    method protected abstract void onBindMediaListHeaderViewHolder(android.support.v17.leanback.widget.AbstractMediaListHeaderPresenter.ViewHolder, java.lang.Object);
+    method public void setBackgroundColor(int);
+  }
+
+  public static class AbstractMediaListHeaderPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+    ctor public AbstractMediaListHeaderPresenter.ViewHolder(android.view.View);
+    method public android.widget.TextView getHeaderView();
+  }
+
+  public class Action {
+    ctor public Action(long);
+    ctor public Action(long, java.lang.CharSequence);
+    ctor public Action(long, java.lang.CharSequence, java.lang.CharSequence);
+    ctor public Action(long, java.lang.CharSequence, java.lang.CharSequence, android.graphics.drawable.Drawable);
+    method public final void addKeyCode(int);
+    method public final android.graphics.drawable.Drawable getIcon();
+    method public final long getId();
+    method public final java.lang.CharSequence getLabel1();
+    method public final java.lang.CharSequence getLabel2();
+    method public final void removeKeyCode(int);
+    method public final boolean respondsToKeyCode(int);
+    method public final void setIcon(android.graphics.drawable.Drawable);
+    method public final void setId(long);
+    method public final void setLabel1(java.lang.CharSequence);
+    method public final void setLabel2(java.lang.CharSequence);
+    field public static final long NO_ID = -1L; // 0xffffffffffffffffL
+  }
+
+  public class ArrayObjectAdapter extends android.support.v17.leanback.widget.ObjectAdapter {
+    ctor public ArrayObjectAdapter(android.support.v17.leanback.widget.PresenterSelector);
+    ctor public ArrayObjectAdapter(android.support.v17.leanback.widget.Presenter);
+    ctor public ArrayObjectAdapter();
+    method public void add(java.lang.Object);
+    method public void add(int, java.lang.Object);
+    method public void addAll(int, java.util.Collection);
+    method public void clear();
+    method public java.lang.Object get(int);
+    method public int indexOf(java.lang.Object);
+    method public void notifyArrayItemRangeChanged(int, int);
+    method public boolean remove(java.lang.Object);
+    method public int removeItems(int, int);
+    method public void replace(int, java.lang.Object);
+    method public int size();
+    method public <E> java.util.List<E> unmodifiableList();
+  }
+
+  public class BaseCardView extends android.widget.FrameLayout {
+    ctor public BaseCardView(android.content.Context);
+    ctor public BaseCardView(android.content.Context, android.util.AttributeSet);
+    ctor public BaseCardView(android.content.Context, android.util.AttributeSet, int);
+    method public int getCardType();
+    method public deprecated int getExtraVisibility();
+    method public int getInfoVisibility();
+    method public boolean isSelectedAnimationDelayed();
+    method public void setCardType(int);
+    method public deprecated void setExtraVisibility(int);
+    method public void setInfoVisibility(int);
+    method public void setSelectedAnimationDelayed(boolean);
+    field public static final int CARD_REGION_VISIBLE_ACTIVATED = 1; // 0x1
+    field public static final int CARD_REGION_VISIBLE_ALWAYS = 0; // 0x0
+    field public static final int CARD_REGION_VISIBLE_SELECTED = 2; // 0x2
+    field public static final int CARD_TYPE_INFO_OVER = 1; // 0x1
+    field public static final int CARD_TYPE_INFO_UNDER = 2; // 0x2
+    field public static final int CARD_TYPE_INFO_UNDER_WITH_EXTRA = 3; // 0x3
+    field public static final int CARD_TYPE_MAIN_ONLY = 0; // 0x0
+  }
+
+  public static class BaseCardView.LayoutParams extends android.widget.FrameLayout.LayoutParams {
+    ctor public BaseCardView.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public BaseCardView.LayoutParams(int, int);
+    ctor public BaseCardView.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public BaseCardView.LayoutParams(android.support.v17.leanback.widget.BaseCardView.LayoutParams);
+    field public static final int VIEW_TYPE_EXTRA = 2; // 0x2
+    field public static final int VIEW_TYPE_INFO = 1; // 0x1
+    field public static final int VIEW_TYPE_MAIN = 0; // 0x0
+    field public int viewType;
+  }
+
+  public abstract interface BaseOnItemViewClickedListener<T> {
+    method public abstract void onItemClicked(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object, android.support.v17.leanback.widget.RowPresenter.ViewHolder, T);
+  }
+
+  public abstract interface BaseOnItemViewSelectedListener<T> {
+    method public abstract void onItemSelected(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object, android.support.v17.leanback.widget.RowPresenter.ViewHolder, T);
+  }
+
+  public class BrowseFrameLayout extends android.widget.FrameLayout {
+    ctor public BrowseFrameLayout(android.content.Context);
+    ctor public BrowseFrameLayout(android.content.Context, android.util.AttributeSet);
+    ctor public BrowseFrameLayout(android.content.Context, android.util.AttributeSet, int);
+    method public android.support.v17.leanback.widget.BrowseFrameLayout.OnChildFocusListener getOnChildFocusListener();
+    method public android.support.v17.leanback.widget.BrowseFrameLayout.OnFocusSearchListener getOnFocusSearchListener();
+    method public void setOnChildFocusListener(android.support.v17.leanback.widget.BrowseFrameLayout.OnChildFocusListener);
+    method public void setOnDispatchKeyListener(android.view.View.OnKeyListener);
+    method public void setOnFocusSearchListener(android.support.v17.leanback.widget.BrowseFrameLayout.OnFocusSearchListener);
+  }
+
+  public static abstract interface BrowseFrameLayout.OnChildFocusListener {
+    method public abstract void onRequestChildFocus(android.view.View, android.view.View);
+    method public abstract boolean onRequestFocusInDescendants(int, android.graphics.Rect);
+  }
+
+  public static abstract interface BrowseFrameLayout.OnFocusSearchListener {
+    method public abstract android.view.View onFocusSearch(android.view.View, int);
+  }
+
+  public final class ClassPresenterSelector extends android.support.v17.leanback.widget.PresenterSelector {
+    ctor public ClassPresenterSelector();
+    method public android.support.v17.leanback.widget.ClassPresenterSelector addClassPresenter(java.lang.Class<?>, android.support.v17.leanback.widget.Presenter);
+    method public android.support.v17.leanback.widget.ClassPresenterSelector addClassPresenterSelector(java.lang.Class<?>, android.support.v17.leanback.widget.PresenterSelector);
+    method public android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+  }
+
+  public class ControlButtonPresenterSelector extends android.support.v17.leanback.widget.PresenterSelector {
+    ctor public ControlButtonPresenterSelector();
+    method public android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+    method public android.support.v17.leanback.widget.Presenter getPrimaryPresenter();
+    method public android.support.v17.leanback.widget.Presenter getSecondaryPresenter();
+  }
+
+  public class CursorObjectAdapter extends android.support.v17.leanback.widget.ObjectAdapter {
+    ctor public CursorObjectAdapter(android.support.v17.leanback.widget.PresenterSelector);
+    ctor public CursorObjectAdapter(android.support.v17.leanback.widget.Presenter);
+    ctor public CursorObjectAdapter();
+    method public void changeCursor(android.database.Cursor);
+    method public void close();
+    method public java.lang.Object get(int);
+    method public final android.database.Cursor getCursor();
+    method public final android.support.v17.leanback.database.CursorMapper getMapper();
+    method protected final void invalidateCache(int);
+    method protected final void invalidateCache(int, int);
+    method public boolean isClosed();
+    method protected void onCursorChanged();
+    method protected void onMapperChanged();
+    method public final void setMapper(android.support.v17.leanback.database.CursorMapper);
+    method public int size();
+    method public android.database.Cursor swapCursor(android.database.Cursor);
+  }
+
+  public class DetailsOverviewLogoPresenter extends android.support.v17.leanback.widget.Presenter {
+    ctor public DetailsOverviewLogoPresenter();
+    method public boolean isBoundToImage(android.support.v17.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder, android.support.v17.leanback.widget.DetailsOverviewRow);
+    method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+    method public android.view.View onCreateView(android.view.ViewGroup);
+    method public android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+    method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public void setContext(android.support.v17.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter);
+  }
+
+  public static class DetailsOverviewLogoPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+    ctor public DetailsOverviewLogoPresenter.ViewHolder(android.view.View);
+    method public android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter getParentPresenter();
+    method public android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder getParentViewHolder();
+    method public boolean isSizeFromDrawableIntrinsic();
+    method public void setSizeFromDrawableIntrinsic(boolean);
+    field protected android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter mParentPresenter;
+    field protected android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder mParentViewHolder;
+  }
+
+  public class DetailsOverviewRow extends android.support.v17.leanback.widget.Row {
+    ctor public DetailsOverviewRow(java.lang.Object);
+    method public final deprecated void addAction(android.support.v17.leanback.widget.Action);
+    method public final deprecated void addAction(int, android.support.v17.leanback.widget.Action);
+    method public android.support.v17.leanback.widget.Action getActionForKeyCode(int);
+    method public final deprecated java.util.List<android.support.v17.leanback.widget.Action> getActions();
+    method public final android.support.v17.leanback.widget.ObjectAdapter getActionsAdapter();
+    method public final android.graphics.drawable.Drawable getImageDrawable();
+    method public final java.lang.Object getItem();
+    method public boolean isImageScaleUpAllowed();
+    method public final deprecated boolean removeAction(android.support.v17.leanback.widget.Action);
+    method public final void setActionsAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public final void setImageBitmap(android.content.Context, android.graphics.Bitmap);
+    method public final void setImageDrawable(android.graphics.drawable.Drawable);
+    method public void setImageScaleUpAllowed(boolean);
+    method public final void setItem(java.lang.Object);
+  }
+
+  public static class DetailsOverviewRow.Listener {
+    ctor public DetailsOverviewRow.Listener();
+    method public void onActionsAdapterChanged(android.support.v17.leanback.widget.DetailsOverviewRow);
+    method public void onImageDrawableChanged(android.support.v17.leanback.widget.DetailsOverviewRow);
+    method public void onItemChanged(android.support.v17.leanback.widget.DetailsOverviewRow);
+  }
+
+  public deprecated class DetailsOverviewRowPresenter extends android.support.v17.leanback.widget.RowPresenter {
+    ctor public DetailsOverviewRowPresenter(android.support.v17.leanback.widget.Presenter);
+    method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+    method public int getBackgroundColor();
+    method public android.support.v17.leanback.widget.OnActionClickedListener getOnActionClickedListener();
+    method public boolean isStyleLarge();
+    method public final boolean isUsingDefaultSelectEffect();
+    method public void setBackgroundColor(int);
+    method public void setOnActionClickedListener(android.support.v17.leanback.widget.OnActionClickedListener);
+    method public final void setSharedElementEnterTransition(android.app.Activity, java.lang.String, long);
+    method public final void setSharedElementEnterTransition(android.app.Activity, java.lang.String);
+    method public void setStyleLarge(boolean);
+  }
+
+  public final class DetailsOverviewRowPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+    ctor public DetailsOverviewRowPresenter.ViewHolder(android.view.View, android.support.v17.leanback.widget.Presenter);
+    field public final android.support.v17.leanback.widget.Presenter.ViewHolder mDetailsDescriptionViewHolder;
+  }
+
+  public class DividerPresenter extends android.support.v17.leanback.widget.Presenter {
+    ctor public DividerPresenter();
+    method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+    method public android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+    method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+  }
+
+  public class DividerRow extends android.support.v17.leanback.widget.Row {
+    ctor public DividerRow();
+    method public final boolean isRenderedAsRowView();
+  }
+
+  public abstract interface FacetProvider {
+    method public abstract java.lang.Object getFacet(java.lang.Class<?>);
+  }
+
+  public abstract interface FacetProviderAdapter {
+    method public abstract android.support.v17.leanback.widget.FacetProvider getFacetProvider(int);
+  }
+
+  public abstract interface FocusHighlight {
+    field public static final int ZOOM_FACTOR_LARGE = 3; // 0x3
+    field public static final int ZOOM_FACTOR_MEDIUM = 2; // 0x2
+    field public static final int ZOOM_FACTOR_NONE = 0; // 0x0
+    field public static final int ZOOM_FACTOR_SMALL = 1; // 0x1
+    field public static final int ZOOM_FACTOR_XSMALL = 4; // 0x4
+  }
+
+  public class FocusHighlightHelper {
+    ctor public FocusHighlightHelper();
+    method public static void setupBrowseItemFocusHighlight(android.support.v17.leanback.widget.ItemBridgeAdapter, int, boolean);
+    method public static void setupHeaderItemFocusHighlight(android.support.v17.leanback.widget.VerticalGridView);
+  }
+
+  public abstract interface FragmentAnimationProvider {
+    method public abstract void onImeAppearing(java.util.List<android.animation.Animator>);
+    method public abstract void onImeDisappearing(java.util.List<android.animation.Animator>);
+  }
+
+  public class FullWidthDetailsOverviewRowPresenter extends android.support.v17.leanback.widget.RowPresenter {
+    ctor public FullWidthDetailsOverviewRowPresenter(android.support.v17.leanback.widget.Presenter);
+    ctor public FullWidthDetailsOverviewRowPresenter(android.support.v17.leanback.widget.Presenter, android.support.v17.leanback.widget.DetailsOverviewLogoPresenter);
+    method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+    method public final int getActionsBackgroundColor();
+    method public final int getAlignmentMode();
+    method public final int getBackgroundColor();
+    method public final int getInitialState();
+    method protected int getLayoutResourceId();
+    method public android.support.v17.leanback.widget.OnActionClickedListener getOnActionClickedListener();
+    method public final boolean isParticipatingEntranceTransition();
+    method public final boolean isUsingDefaultSelectEffect();
+    method public final void notifyOnBindLogo(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder);
+    method protected void onLayoutLogo(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, boolean);
+    method protected void onLayoutOverviewFrame(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, boolean);
+    method protected void onStateChanged(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int);
+    method public final void setActionsBackgroundColor(int);
+    method public final void setAlignmentMode(int);
+    method public final void setBackgroundColor(int);
+    method public final void setInitialState(int);
+    method public final void setListener(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.Listener);
+    method public void setOnActionClickedListener(android.support.v17.leanback.widget.OnActionClickedListener);
+    method public final void setParticipatingEntranceTransition(boolean);
+    method public final void setState(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int);
+    field public static final int ALIGN_MODE_MIDDLE = 1; // 0x1
+    field public static final int ALIGN_MODE_START = 0; // 0x0
+    field public static final int STATE_FULL = 1; // 0x1
+    field public static final int STATE_HALF = 0; // 0x0
+    field public static final int STATE_SMALL = 2; // 0x2
+    field protected int mInitialState;
+  }
+
+  public static abstract class FullWidthDetailsOverviewRowPresenter.Listener {
+    ctor public FullWidthDetailsOverviewRowPresenter.Listener();
+    method public void onBindLogo(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder);
+  }
+
+  public class FullWidthDetailsOverviewRowPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+    ctor public FullWidthDetailsOverviewRowPresenter.ViewHolder(android.view.View, android.support.v17.leanback.widget.Presenter, android.support.v17.leanback.widget.DetailsOverviewLogoPresenter);
+    method protected android.support.v17.leanback.widget.DetailsOverviewRow.Listener createRowListener();
+    method public final android.view.ViewGroup getActionsRow();
+    method public final android.view.ViewGroup getDetailsDescriptionFrame();
+    method public final android.support.v17.leanback.widget.Presenter.ViewHolder getDetailsDescriptionViewHolder();
+    method public final android.support.v17.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder getLogoViewHolder();
+    method public final android.view.ViewGroup getOverviewView();
+    method public final int getState();
+    field protected final android.support.v17.leanback.widget.DetailsOverviewRow.Listener mRowListener;
+  }
+
+  public class FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener extends android.support.v17.leanback.widget.DetailsOverviewRow.Listener {
+    ctor public FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener();
+  }
+
+  public class FullWidthDetailsOverviewSharedElementHelper extends android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.Listener {
+    ctor public FullWidthDetailsOverviewSharedElementHelper();
+    method public boolean getAutoStartSharedElementTransition();
+    method public void setAutoStartSharedElementTransition(boolean);
+    method public void setSharedElementEnterTransition(android.app.Activity, java.lang.String);
+    method public void setSharedElementEnterTransition(android.app.Activity, java.lang.String, long);
+    method public void startPostponedEnterTransition();
+  }
+
+  public class GuidanceStylist implements android.support.v17.leanback.widget.FragmentAnimationProvider {
+    ctor public GuidanceStylist();
+    method public android.widget.TextView getBreadcrumbView();
+    method public android.widget.TextView getDescriptionView();
+    method public android.widget.ImageView getIconView();
+    method public android.widget.TextView getTitleView();
+    method public android.view.View onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.support.v17.leanback.widget.GuidanceStylist.Guidance);
+    method public void onDestroyView();
+    method public void onImeAppearing(java.util.List<android.animation.Animator>);
+    method public void onImeDisappearing(java.util.List<android.animation.Animator>);
+    method public int onProvideLayoutId();
+  }
+
+  public static class GuidanceStylist.Guidance {
+    ctor public GuidanceStylist.Guidance(java.lang.String, java.lang.String, java.lang.String, android.graphics.drawable.Drawable);
+    method public java.lang.String getBreadcrumb();
+    method public java.lang.String getDescription();
+    method public android.graphics.drawable.Drawable getIconDrawable();
+    method public java.lang.String getTitle();
+  }
+
+  public class GuidedAction extends android.support.v17.leanback.widget.Action {
+    ctor protected GuidedAction();
+    method public int getCheckSetId();
+    method public java.lang.CharSequence getDescription();
+    method public int getDescriptionEditInputType();
+    method public int getDescriptionInputType();
+    method public java.lang.CharSequence getEditDescription();
+    method public int getEditInputType();
+    method public java.lang.CharSequence getEditTitle();
+    method public int getInputType();
+    method public android.content.Intent getIntent();
+    method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getSubActions();
+    method public java.lang.CharSequence getTitle();
+    method public boolean hasEditableActivatorView();
+    method public boolean hasMultilineDescription();
+    method public boolean hasNext();
+    method public boolean hasSubActions();
+    method public boolean hasTextEditable();
+    method public boolean infoOnly();
+    method public final boolean isAutoSaveRestoreEnabled();
+    method public boolean isChecked();
+    method public boolean isDescriptionEditable();
+    method public boolean isEditTitleUsed();
+    method public boolean isEditable();
+    method public boolean isEnabled();
+    method public boolean isFocusable();
+    method public void onRestoreInstanceState(android.os.Bundle, java.lang.String);
+    method public void onSaveInstanceState(android.os.Bundle, java.lang.String);
+    method public void setChecked(boolean);
+    method public void setDescription(java.lang.CharSequence);
+    method public void setEditDescription(java.lang.CharSequence);
+    method public void setEditTitle(java.lang.CharSequence);
+    method public void setEnabled(boolean);
+    method public void setFocusable(boolean);
+    method public void setIntent(android.content.Intent);
+    method public void setSubActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+    method public void setTitle(java.lang.CharSequence);
+    field public static final long ACTION_ID_CANCEL = -5L; // 0xfffffffffffffffbL
+    field public static final long ACTION_ID_CONTINUE = -7L; // 0xfffffffffffffff9L
+    field public static final long ACTION_ID_CURRENT = -3L; // 0xfffffffffffffffdL
+    field public static final long ACTION_ID_FINISH = -6L; // 0xfffffffffffffffaL
+    field public static final long ACTION_ID_NEXT = -2L; // 0xfffffffffffffffeL
+    field public static final long ACTION_ID_NO = -9L; // 0xfffffffffffffff7L
+    field public static final long ACTION_ID_OK = -4L; // 0xfffffffffffffffcL
+    field public static final long ACTION_ID_YES = -8L; // 0xfffffffffffffff8L
+    field public static final int CHECKBOX_CHECK_SET_ID = -1; // 0xffffffff
+    field public static final int DEFAULT_CHECK_SET_ID = 1; // 0x1
+    field public static final int NO_CHECK_SET = 0; // 0x0
+  }
+
+  public static class GuidedAction.Builder extends android.support.v17.leanback.widget.GuidedAction.BuilderBase {
+    ctor public deprecated GuidedAction.Builder();
+    ctor public GuidedAction.Builder(android.content.Context);
+    method public android.support.v17.leanback.widget.GuidedAction build();
+  }
+
+  public static abstract class GuidedAction.BuilderBase<B extends android.support.v17.leanback.widget.GuidedAction.BuilderBase> {
+    ctor public GuidedAction.BuilderBase(android.content.Context);
+    method protected final void applyValues(android.support.v17.leanback.widget.GuidedAction);
+    method public B autoSaveRestoreEnabled(boolean);
+    method public B checkSetId(int);
+    method public B checked(boolean);
+    method public B clickAction(long);
+    method public B description(java.lang.CharSequence);
+    method public B description(int);
+    method public B descriptionEditInputType(int);
+    method public B descriptionEditable(boolean);
+    method public B descriptionInputType(int);
+    method public B editDescription(java.lang.CharSequence);
+    method public B editDescription(int);
+    method public B editInputType(int);
+    method public B editTitle(java.lang.CharSequence);
+    method public B editTitle(int);
+    method public B editable(boolean);
+    method public B enabled(boolean);
+    method public B focusable(boolean);
+    method public android.content.Context getContext();
+    method public B hasEditableActivatorView(boolean);
+    method public B hasNext(boolean);
+    method public B icon(android.graphics.drawable.Drawable);
+    method public B icon(int);
+    method public deprecated B iconResourceId(int, android.content.Context);
+    method public B id(long);
+    method public B infoOnly(boolean);
+    method public B inputType(int);
+    method public B intent(android.content.Intent);
+    method public B multilineDescription(boolean);
+    method public B subActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+    method public B title(java.lang.CharSequence);
+    method public B title(int);
+  }
+
+  public class GuidedActionEditText extends android.widget.EditText implements android.support.v17.leanback.widget.ImeKeyMonitor {
+    ctor public GuidedActionEditText(android.content.Context);
+    ctor public GuidedActionEditText(android.content.Context, android.util.AttributeSet);
+    ctor public GuidedActionEditText(android.content.Context, android.util.AttributeSet, int);
+    method public void setImeKeyListener(android.support.v17.leanback.widget.ImeKeyMonitor.ImeKeyListener);
+  }
+
+  public class GuidedActionsStylist implements android.support.v17.leanback.widget.FragmentAnimationProvider {
+    ctor public GuidedActionsStylist();
+    method public void collapseAction(boolean);
+    method public void expandAction(android.support.v17.leanback.widget.GuidedAction, boolean);
+    method public android.support.v17.leanback.widget.VerticalGridView getActionsGridView();
+    method public android.support.v17.leanback.widget.GuidedAction getExpandedAction();
+    method public int getItemViewType(android.support.v17.leanback.widget.GuidedAction);
+    method public android.support.v17.leanback.widget.VerticalGridView getSubActionsGridView();
+    method public final boolean isBackKeyToCollapseActivatorView();
+    method public final boolean isBackKeyToCollapseSubActions();
+    method public boolean isButtonActions();
+    method public boolean isExpandTransitionSupported();
+    method public boolean isExpanded();
+    method public boolean isInExpandTransition();
+    method public boolean isSubActionsExpanded();
+    method public void onAnimateItemChecked(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, boolean);
+    method public void onAnimateItemFocused(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, boolean);
+    method public void onAnimateItemPressed(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, boolean);
+    method public void onAnimateItemPressedCancelled(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder);
+    method public void onBindActivatorView(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+    method public void onBindCheckMarkView(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+    method public void onBindChevronView(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+    method public void onBindViewHolder(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+    method public android.view.View onCreateView(android.view.LayoutInflater, android.view.ViewGroup);
+    method public android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+    method public android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+    method public void onDestroyView();
+    method protected deprecated void onEditingModeChange(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction, boolean);
+    method protected void onEditingModeChange(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, boolean, boolean);
+    method public void onImeAppearing(java.util.List<android.animation.Animator>);
+    method public void onImeDisappearing(java.util.List<android.animation.Animator>);
+    method public int onProvideItemLayoutId();
+    method public int onProvideItemLayoutId(int);
+    method public int onProvideLayoutId();
+    method public boolean onUpdateActivatorView(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+    method public void onUpdateExpandedViewHolder(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder);
+    method public void setAsButtonActions();
+    method public final void setBackKeyToCollapseActivatorView(boolean);
+    method public final void setBackKeyToCollapseSubActions(boolean);
+    method public deprecated void setEditingMode(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction, boolean);
+    method public deprecated void setExpandedViewHolder(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder);
+    method protected void setupImeOptions(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+    method public deprecated void startExpandedTransition(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder);
+    field public static final int VIEW_TYPE_DATE_PICKER = 1; // 0x1
+    field public static final int VIEW_TYPE_DEFAULT = 0; // 0x0
+  }
+
+  public static class GuidedActionsStylist.ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder implements android.support.v17.leanback.widget.FacetProvider {
+    ctor public GuidedActionsStylist.ViewHolder(android.view.View);
+    ctor public GuidedActionsStylist.ViewHolder(android.view.View, boolean);
+    method public android.support.v17.leanback.widget.GuidedAction getAction();
+    method public android.widget.ImageView getCheckmarkView();
+    method public android.widget.ImageView getChevronView();
+    method public android.view.View getContentView();
+    method public android.widget.TextView getDescriptionView();
+    method public android.widget.EditText getEditableDescriptionView();
+    method public android.widget.EditText getEditableTitleView();
+    method public android.view.View getEditingView();
+    method public java.lang.Object getFacet(java.lang.Class<?>);
+    method public android.widget.ImageView getIconView();
+    method public android.widget.TextView getTitleView();
+    method public boolean isInEditing();
+    method public boolean isInEditingActivatorView();
+    method public boolean isInEditingDescription();
+    method public boolean isInEditingText();
+    method public boolean isInEditingTitle();
+    method public boolean isSubAction();
+  }
+
+  public class GuidedDatePickerAction extends android.support.v17.leanback.widget.GuidedAction {
+    ctor public GuidedDatePickerAction();
+    method public long getDate();
+    method public java.lang.String getDatePickerFormat();
+    method public long getMaxDate();
+    method public long getMinDate();
+    method public void setDate(long);
+  }
+
+  public static final class GuidedDatePickerAction.Builder extends android.support.v17.leanback.widget.GuidedDatePickerAction.BuilderBase {
+    ctor public GuidedDatePickerAction.Builder(android.content.Context);
+    method public android.support.v17.leanback.widget.GuidedDatePickerAction build();
+  }
+
+  public static abstract class GuidedDatePickerAction.BuilderBase<B extends android.support.v17.leanback.widget.GuidedDatePickerAction.BuilderBase> extends android.support.v17.leanback.widget.GuidedAction.BuilderBase {
+    ctor public GuidedDatePickerAction.BuilderBase(android.content.Context);
+    method protected final void applyDatePickerValues(android.support.v17.leanback.widget.GuidedDatePickerAction);
+    method public B date(long);
+    method public B datePickerFormat(java.lang.String);
+    method public B maxDate(long);
+    method public B minDate(long);
+  }
+
+  public class HeaderItem {
+    ctor public HeaderItem(long, java.lang.String);
+    ctor public HeaderItem(java.lang.String);
+    method public java.lang.CharSequence getContentDescription();
+    method public java.lang.CharSequence getDescription();
+    method public final long getId();
+    method public final java.lang.String getName();
+    method public void setContentDescription(java.lang.CharSequence);
+    method public void setDescription(java.lang.CharSequence);
+  }
+
+  public class HorizontalGridView extends android.support.v7.widget.RecyclerView {
+    ctor public HorizontalGridView(android.content.Context);
+    ctor public HorizontalGridView(android.content.Context, android.util.AttributeSet);
+    ctor public HorizontalGridView(android.content.Context, android.util.AttributeSet, int);
+    method public final boolean getFadingLeftEdge();
+    method public final int getFadingLeftEdgeLength();
+    method public final int getFadingLeftEdgeOffset();
+    method public final boolean getFadingRightEdge();
+    method public final int getFadingRightEdgeLength();
+    method public final int getFadingRightEdgeOffset();
+    method protected void initAttributes(android.content.Context, android.util.AttributeSet);
+    method public final void setFadingLeftEdge(boolean);
+    method public final void setFadingLeftEdgeLength(int);
+    method public final void setFadingLeftEdgeOffset(int);
+    method public final void setFadingRightEdge(boolean);
+    method public final void setFadingRightEdgeLength(int);
+    method public final void setFadingRightEdgeOffset(int);
+    method public void setNumRows(int);
+    method public void setRowHeight(int);
+  }
+
+  public final class HorizontalHoverCardSwitcher extends android.support.v17.leanback.widget.PresenterSwitcher {
+    ctor public HorizontalHoverCardSwitcher();
+    method protected void insertView(android.view.View);
+    method public void select(android.support.v17.leanback.widget.HorizontalGridView, android.view.View, java.lang.Object);
+  }
+
+  public class ImageCardView extends android.support.v17.leanback.widget.BaseCardView {
+    ctor public deprecated ImageCardView(android.content.Context, int);
+    ctor public ImageCardView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ImageCardView(android.content.Context);
+    ctor public ImageCardView(android.content.Context, android.util.AttributeSet);
+    method public android.graphics.drawable.Drawable getBadgeImage();
+    method public java.lang.CharSequence getContentText();
+    method public android.graphics.drawable.Drawable getInfoAreaBackground();
+    method public android.graphics.drawable.Drawable getMainImage();
+    method public final android.widget.ImageView getMainImageView();
+    method public java.lang.CharSequence getTitleText();
+    method public void setBadgeImage(android.graphics.drawable.Drawable);
+    method public void setContentText(java.lang.CharSequence);
+    method public void setInfoAreaBackground(android.graphics.drawable.Drawable);
+    method public void setInfoAreaBackgroundColor(int);
+    method public void setMainImage(android.graphics.drawable.Drawable);
+    method public void setMainImage(android.graphics.drawable.Drawable, boolean);
+    method public void setMainImageAdjustViewBounds(boolean);
+    method public void setMainImageDimensions(int, int);
+    method public void setMainImageScaleType(android.widget.ImageView.ScaleType);
+    method public void setTitleText(java.lang.CharSequence);
+    field public static final int CARD_TYPE_FLAG_CONTENT = 2; // 0x2
+    field public static final int CARD_TYPE_FLAG_ICON_LEFT = 8; // 0x8
+    field public static final int CARD_TYPE_FLAG_ICON_RIGHT = 4; // 0x4
+    field public static final int CARD_TYPE_FLAG_IMAGE_ONLY = 0; // 0x0
+    field public static final int CARD_TYPE_FLAG_TITLE = 1; // 0x1
+  }
+
+  public abstract interface ImeKeyMonitor {
+    method public abstract void setImeKeyListener(android.support.v17.leanback.widget.ImeKeyMonitor.ImeKeyListener);
+  }
+
+  public static abstract interface ImeKeyMonitor.ImeKeyListener {
+    method public abstract boolean onKeyPreIme(android.widget.EditText, int, android.view.KeyEvent);
+  }
+
+  public final class ItemAlignmentFacet {
+    ctor public ItemAlignmentFacet();
+    method public android.support.v17.leanback.widget.ItemAlignmentFacet.ItemAlignmentDef[] getAlignmentDefs();
+    method public boolean isMultiAlignment();
+    method public void setAlignmentDefs(android.support.v17.leanback.widget.ItemAlignmentFacet.ItemAlignmentDef[]);
+    field public static final float ITEM_ALIGN_OFFSET_PERCENT_DISABLED = -1.0f;
+  }
+
+  public static class ItemAlignmentFacet.ItemAlignmentDef {
+    ctor public ItemAlignmentFacet.ItemAlignmentDef();
+    method public final int getItemAlignmentFocusViewId();
+    method public final int getItemAlignmentOffset();
+    method public final float getItemAlignmentOffsetPercent();
+    method public final int getItemAlignmentViewId();
+    method public boolean isAlignedToTextViewBaseLine();
+    method public final boolean isItemAlignmentOffsetWithPadding();
+    method public final void setAlignedToTextViewBaseline(boolean);
+    method public final void setItemAlignmentFocusViewId(int);
+    method public final void setItemAlignmentOffset(int);
+    method public final void setItemAlignmentOffsetPercent(float);
+    method public final void setItemAlignmentOffsetWithPadding(boolean);
+    method public final void setItemAlignmentViewId(int);
+  }
+
+  public class ItemBridgeAdapter extends android.support.v7.widget.RecyclerView.Adapter implements android.support.v17.leanback.widget.FacetProviderAdapter {
+    ctor public ItemBridgeAdapter(android.support.v17.leanback.widget.ObjectAdapter, android.support.v17.leanback.widget.PresenterSelector);
+    ctor public ItemBridgeAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    ctor public ItemBridgeAdapter();
+    method public void clear();
+    method public android.support.v17.leanback.widget.FacetProvider getFacetProvider(int);
+    method public int getItemCount();
+    method public java.util.ArrayList<android.support.v17.leanback.widget.Presenter> getPresenterMapper();
+    method public android.support.v17.leanback.widget.ItemBridgeAdapter.Wrapper getWrapper();
+    method protected void onAddPresenter(android.support.v17.leanback.widget.Presenter, int);
+    method protected void onAttachedToWindow(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+    method protected void onBind(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+    method public final void onBindViewHolder(android.support.v7.widget.RecyclerView.ViewHolder, int);
+    method protected void onCreate(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+    method public final android.support.v7.widget.RecyclerView.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+    method protected void onDetachedFromWindow(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+    method protected void onUnbind(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+    method public final void onViewAttachedToWindow(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void onViewDetachedFromWindow(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void onViewRecycled(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setAdapterListener(android.support.v17.leanback.widget.ItemBridgeAdapter.AdapterListener);
+    method public void setPresenterMapper(java.util.ArrayList<android.support.v17.leanback.widget.Presenter>);
+    method public void setWrapper(android.support.v17.leanback.widget.ItemBridgeAdapter.Wrapper);
+  }
+
+  public static class ItemBridgeAdapter.AdapterListener {
+    ctor public ItemBridgeAdapter.AdapterListener();
+    method public void onAddPresenter(android.support.v17.leanback.widget.Presenter, int);
+    method public void onAttachedToWindow(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+    method public void onBind(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+    method public void onCreate(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+    method public void onDetachedFromWindow(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+    method public void onUnbind(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+  }
+
+  public class ItemBridgeAdapter.ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder implements android.support.v17.leanback.widget.FacetProvider {
+    method public final java.lang.Object getExtraObject();
+    method public java.lang.Object getFacet(java.lang.Class<?>);
+    method public final java.lang.Object getItem();
+    method public final android.support.v17.leanback.widget.Presenter getPresenter();
+    method public final android.support.v17.leanback.widget.Presenter.ViewHolder getViewHolder();
+    method public void setExtraObject(java.lang.Object);
+  }
+
+  public static abstract class ItemBridgeAdapter.Wrapper {
+    ctor public ItemBridgeAdapter.Wrapper();
+    method public abstract android.view.View createWrapper(android.view.View);
+    method public abstract void wrap(android.view.View, android.view.View);
+  }
+
+  public class ItemBridgeAdapterShadowOverlayWrapper extends android.support.v17.leanback.widget.ItemBridgeAdapter.Wrapper {
+    ctor public ItemBridgeAdapterShadowOverlayWrapper(android.support.v17.leanback.widget.ShadowOverlayHelper);
+    method public android.view.View createWrapper(android.view.View);
+    method public void wrap(android.view.View, android.view.View);
+  }
+
+  public class ListRow extends android.support.v17.leanback.widget.Row {
+    ctor public ListRow(android.support.v17.leanback.widget.HeaderItem, android.support.v17.leanback.widget.ObjectAdapter);
+    ctor public ListRow(long, android.support.v17.leanback.widget.HeaderItem, android.support.v17.leanback.widget.ObjectAdapter);
+    ctor public ListRow(android.support.v17.leanback.widget.ObjectAdapter);
+    method public final android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+    method public java.lang.CharSequence getContentDescription();
+    method public void setContentDescription(java.lang.CharSequence);
+  }
+
+  public final class ListRowHoverCardView extends android.widget.LinearLayout {
+    ctor public ListRowHoverCardView(android.content.Context);
+    ctor public ListRowHoverCardView(android.content.Context, android.util.AttributeSet);
+    ctor public ListRowHoverCardView(android.content.Context, android.util.AttributeSet, int);
+    method public final java.lang.CharSequence getDescription();
+    method public final java.lang.CharSequence getTitle();
+    method public final void setDescription(java.lang.CharSequence);
+    method public final void setTitle(java.lang.CharSequence);
+  }
+
+  public class ListRowPresenter extends android.support.v17.leanback.widget.RowPresenter {
+    ctor public ListRowPresenter();
+    ctor public ListRowPresenter(int);
+    ctor public ListRowPresenter(int, boolean);
+    method public final boolean areChildRoundedCornersEnabled();
+    method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+    method protected android.support.v17.leanback.widget.ShadowOverlayHelper.Options createShadowOverlayOptions();
+    method public final void enableChildRoundedCorners(boolean);
+    method public int getExpandedRowHeight();
+    method public final int getFocusZoomFactor();
+    method public final android.support.v17.leanback.widget.PresenterSelector getHoverCardPresenterSelector();
+    method public int getRecycledPoolSize(android.support.v17.leanback.widget.Presenter);
+    method public int getRowHeight();
+    method public final boolean getShadowEnabled();
+    method public final deprecated int getZoomFactor();
+    method public final boolean isFocusDimmerUsed();
+    method public final boolean isKeepChildForeground();
+    method public boolean isUsingDefaultListSelectEffect();
+    method public final boolean isUsingDefaultSelectEffect();
+    method public boolean isUsingDefaultShadow();
+    method public boolean isUsingZOrder(android.content.Context);
+    method public void setExpandedRowHeight(int);
+    method public final void setHoverCardPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+    method public final void setKeepChildForeground(boolean);
+    method public void setNumRows(int);
+    method public void setRecycledPoolSize(android.support.v17.leanback.widget.Presenter, int);
+    method public void setRowHeight(int);
+    method public final void setShadowEnabled(boolean);
+  }
+
+  public static class ListRowPresenter.SelectItemViewHolderTask extends android.support.v17.leanback.widget.Presenter.ViewHolderTask {
+    ctor public ListRowPresenter.SelectItemViewHolderTask(int);
+    method public int getItemPosition();
+    method public android.support.v17.leanback.widget.Presenter.ViewHolderTask getItemTask();
+    method public boolean isSmoothScroll();
+    method public void setItemPosition(int);
+    method public void setItemTask(android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+    method public void setSmoothScroll(boolean);
+  }
+
+  public static class ListRowPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+    ctor public ListRowPresenter.ViewHolder(android.view.View, android.support.v17.leanback.widget.HorizontalGridView, android.support.v17.leanback.widget.ListRowPresenter);
+    method public final android.support.v17.leanback.widget.ItemBridgeAdapter getBridgeAdapter();
+    method public final android.support.v17.leanback.widget.HorizontalGridView getGridView();
+    method public android.support.v17.leanback.widget.Presenter.ViewHolder getItemViewHolder(int);
+    method public final android.support.v17.leanback.widget.ListRowPresenter getListRowPresenter();
+    method public int getSelectedPosition();
+  }
+
+  public final class ListRowView extends android.widget.LinearLayout {
+    ctor public ListRowView(android.content.Context);
+    ctor public ListRowView(android.content.Context, android.util.AttributeSet);
+    ctor public ListRowView(android.content.Context, android.util.AttributeSet, int);
+    method public android.support.v17.leanback.widget.HorizontalGridView getGridView();
+  }
+
+  public abstract interface MultiActionsProvider {
+    method public abstract android.support.v17.leanback.widget.MultiActionsProvider.MultiAction[] getActions();
+  }
+
+  public static class MultiActionsProvider.MultiAction {
+    ctor public MultiActionsProvider.MultiAction(long);
+    method public android.graphics.drawable.Drawable getCurrentDrawable();
+    method public android.graphics.drawable.Drawable[] getDrawables();
+    method public long getId();
+    method public int getIndex();
+    method public void incrementIndex();
+    method public void setDrawables(android.graphics.drawable.Drawable[]);
+    method public void setIndex(int);
+  }
+
+  public abstract class ObjectAdapter {
+    ctor public ObjectAdapter(android.support.v17.leanback.widget.PresenterSelector);
+    ctor public ObjectAdapter(android.support.v17.leanback.widget.Presenter);
+    ctor public ObjectAdapter();
+    method public abstract java.lang.Object get(int);
+    method public long getId(int);
+    method public final android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+    method public final android.support.v17.leanback.widget.PresenterSelector getPresenterSelector();
+    method public final boolean hasStableIds();
+    method public boolean isImmediateNotifySupported();
+    method protected final void notifyChanged();
+    method public final void notifyItemRangeChanged(int, int);
+    method protected final void notifyItemRangeInserted(int, int);
+    method protected final void notifyItemRangeRemoved(int, int);
+    method protected void onHasStableIdsChanged();
+    method protected void onPresenterSelectorChanged();
+    method public final void registerObserver(android.support.v17.leanback.widget.ObjectAdapter.DataObserver);
+    method public final void setHasStableIds(boolean);
+    method public final void setPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+    method public abstract int size();
+    method public final void unregisterAllObservers();
+    method public final void unregisterObserver(android.support.v17.leanback.widget.ObjectAdapter.DataObserver);
+    field public static final int NO_ID = -1; // 0xffffffff
+  }
+
+  public static abstract class ObjectAdapter.DataObserver {
+    ctor public ObjectAdapter.DataObserver();
+    method public void onChanged();
+    method public void onItemRangeChanged(int, int);
+    method public void onItemRangeInserted(int, int);
+    method public void onItemRangeRemoved(int, int);
+  }
+
+  public abstract interface OnActionClickedListener {
+    method public abstract void onActionClicked(android.support.v17.leanback.widget.Action);
+  }
+
+  public abstract interface OnChildLaidOutListener {
+    method public abstract void onChildLaidOut(android.view.ViewGroup, android.view.View, int, long);
+  }
+
+  public abstract deprecated interface OnChildSelectedListener {
+    method public abstract void onChildSelected(android.view.ViewGroup, android.view.View, int, long);
+  }
+
+  public abstract class OnChildViewHolderSelectedListener {
+    ctor public OnChildViewHolderSelectedListener();
+    method public void onChildViewHolderSelected(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, int, int);
+    method public void onChildViewHolderSelectedAndPositioned(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, int, int);
+  }
+
+  public abstract interface OnItemViewClickedListener implements android.support.v17.leanback.widget.BaseOnItemViewClickedListener {
+  }
+
+  public abstract interface OnItemViewSelectedListener implements android.support.v17.leanback.widget.BaseOnItemViewSelectedListener {
+  }
+
+  public class PageRow extends android.support.v17.leanback.widget.Row {
+    ctor public PageRow(android.support.v17.leanback.widget.HeaderItem);
+    method public final boolean isRenderedAsRowView();
+  }
+
+  public class PlaybackControlsRow extends android.support.v17.leanback.widget.Row {
+    ctor public PlaybackControlsRow(java.lang.Object);
+    ctor public PlaybackControlsRow();
+    method public android.support.v17.leanback.widget.Action getActionForKeyCode(int);
+    method public android.support.v17.leanback.widget.Action getActionForKeyCode(android.support.v17.leanback.widget.ObjectAdapter, int);
+    method public int getBufferedProgress();
+    method public long getBufferedProgressLong();
+    method public int getCurrentTime();
+    method public long getCurrentTimeLong();
+    method public final android.graphics.drawable.Drawable getImageDrawable();
+    method public final java.lang.Object getItem();
+    method public final android.support.v17.leanback.widget.ObjectAdapter getPrimaryActionsAdapter();
+    method public final android.support.v17.leanback.widget.ObjectAdapter getSecondaryActionsAdapter();
+    method public int getTotalTime();
+    method public long getTotalTimeLong();
+    method public void setBufferedProgress(int);
+    method public void setBufferedProgressLong(long);
+    method public void setCurrentTime(int);
+    method public void setCurrentTimeLong(long);
+    method public final void setImageBitmap(android.content.Context, android.graphics.Bitmap);
+    method public final void setImageDrawable(android.graphics.drawable.Drawable);
+    method public final void setPrimaryActionsAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public final void setSecondaryActionsAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+    method public void setTotalTime(int);
+    method public void setTotalTimeLong(long);
+  }
+
+  public static class PlaybackControlsRow.ClosedCaptioningAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+    ctor public PlaybackControlsRow.ClosedCaptioningAction(android.content.Context);
+    ctor public PlaybackControlsRow.ClosedCaptioningAction(android.content.Context, int);
+    field public static int OFF;
+    field public static int ON;
+  }
+
+  public static class PlaybackControlsRow.FastForwardAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+    ctor public PlaybackControlsRow.FastForwardAction(android.content.Context);
+    ctor public PlaybackControlsRow.FastForwardAction(android.content.Context, int);
+  }
+
+  public static class PlaybackControlsRow.HighQualityAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+    ctor public PlaybackControlsRow.HighQualityAction(android.content.Context);
+    ctor public PlaybackControlsRow.HighQualityAction(android.content.Context, int);
+    field public static int OFF;
+    field public static int ON;
+  }
+
+  public static class PlaybackControlsRow.MoreActions extends android.support.v17.leanback.widget.Action {
+    ctor public PlaybackControlsRow.MoreActions(android.content.Context);
+  }
+
+  public static abstract class PlaybackControlsRow.MultiAction extends android.support.v17.leanback.widget.Action {
+    ctor public PlaybackControlsRow.MultiAction(int);
+    method public int getActionCount();
+    method public android.graphics.drawable.Drawable getDrawable(int);
+    method public int getIndex();
+    method public java.lang.String getLabel(int);
+    method public java.lang.String getSecondaryLabel(int);
+    method public void nextIndex();
+    method public void setDrawables(android.graphics.drawable.Drawable[]);
+    method public void setIndex(int);
+    method public void setLabels(java.lang.String[]);
+    method public void setSecondaryLabels(java.lang.String[]);
+  }
+
+  public static class PlaybackControlsRow.PictureInPictureAction extends android.support.v17.leanback.widget.Action {
+    ctor public PlaybackControlsRow.PictureInPictureAction(android.content.Context);
+  }
+
+  public static class PlaybackControlsRow.PlayPauseAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+    ctor public PlaybackControlsRow.PlayPauseAction(android.content.Context);
+    field public static int PAUSE;
+    field public static int PLAY;
+  }
+
+  public static class PlaybackControlsRow.RepeatAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+    ctor public PlaybackControlsRow.RepeatAction(android.content.Context);
+    ctor public PlaybackControlsRow.RepeatAction(android.content.Context, int);
+    ctor public PlaybackControlsRow.RepeatAction(android.content.Context, int, int);
+    field public static int ALL;
+    field public static int NONE;
+    field public static int ONE;
+  }
+
+  public static class PlaybackControlsRow.RewindAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+    ctor public PlaybackControlsRow.RewindAction(android.content.Context);
+    ctor public PlaybackControlsRow.RewindAction(android.content.Context, int);
+  }
+
+  public static class PlaybackControlsRow.ShuffleAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+    ctor public PlaybackControlsRow.ShuffleAction(android.content.Context);
+    ctor public PlaybackControlsRow.ShuffleAction(android.content.Context, int);
+    field public static int OFF;
+    field public static int ON;
+  }
+
+  public static class PlaybackControlsRow.SkipNextAction extends android.support.v17.leanback.widget.Action {
+    ctor public PlaybackControlsRow.SkipNextAction(android.content.Context);
+  }
+
+  public static class PlaybackControlsRow.SkipPreviousAction extends android.support.v17.leanback.widget.Action {
+    ctor public PlaybackControlsRow.SkipPreviousAction(android.content.Context);
+  }
+
+  public static abstract class PlaybackControlsRow.ThumbsAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+    ctor public PlaybackControlsRow.ThumbsAction(int, android.content.Context, int, int);
+    field public static int OUTLINE;
+    field public static int SOLID;
+  }
+
+  public static class PlaybackControlsRow.ThumbsDownAction extends android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsAction {
+    ctor public PlaybackControlsRow.ThumbsDownAction(android.content.Context);
+  }
+
+  public static class PlaybackControlsRow.ThumbsUpAction extends android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsAction {
+    ctor public PlaybackControlsRow.ThumbsUpAction(android.content.Context);
+  }
+
+  public class PlaybackControlsRowPresenter extends android.support.v17.leanback.widget.PlaybackRowPresenter {
+    ctor public PlaybackControlsRowPresenter(android.support.v17.leanback.widget.Presenter);
+    ctor public PlaybackControlsRowPresenter();
+    method public boolean areSecondaryActionsHidden();
+    method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+    method public int getBackgroundColor();
+    method public android.support.v17.leanback.widget.OnActionClickedListener getOnActionClickedListener();
+    method public int getProgressColor();
+    method public void setBackgroundColor(int);
+    method public void setOnActionClickedListener(android.support.v17.leanback.widget.OnActionClickedListener);
+    method public void setProgressColor(int);
+    method public void setSecondaryActionsHidden(boolean);
+    method public void showBottomSpace(android.support.v17.leanback.widget.PlaybackControlsRowPresenter.ViewHolder, boolean);
+    method public void showPrimaryActions(android.support.v17.leanback.widget.PlaybackControlsRowPresenter.ViewHolder);
+  }
+
+  public class PlaybackControlsRowPresenter.ViewHolder extends android.support.v17.leanback.widget.PlaybackRowPresenter.ViewHolder {
+    field public final android.support.v17.leanback.widget.Presenter.ViewHolder mDescriptionViewHolder;
+  }
+
+  public abstract class PlaybackRowPresenter extends android.support.v17.leanback.widget.RowPresenter {
+    ctor public PlaybackRowPresenter();
+    method public void onReappear(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+  }
+
+  public static class PlaybackRowPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+    ctor public PlaybackRowPresenter.ViewHolder(android.view.View);
+  }
+
+  public abstract class Presenter implements android.support.v17.leanback.widget.FacetProvider {
+    ctor public Presenter();
+    method protected static void cancelAnimationsRecursive(android.view.View);
+    method public final java.lang.Object getFacet(java.lang.Class<?>);
+    method public abstract void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+    method public abstract android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+    method public abstract void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public void onViewAttachedToWindow(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public void onViewDetachedFromWindow(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public final void setFacet(java.lang.Class<?>, java.lang.Object);
+    method public void setOnClickListener(android.support.v17.leanback.widget.Presenter.ViewHolder, android.view.View.OnClickListener);
+  }
+
+  public static class Presenter.ViewHolder implements android.support.v17.leanback.widget.FacetProvider {
+    ctor public Presenter.ViewHolder(android.view.View);
+    method public final java.lang.Object getFacet(java.lang.Class<?>);
+    method public final void setFacet(java.lang.Class<?>, java.lang.Object);
+    field public final android.view.View view;
+  }
+
+  public static abstract class Presenter.ViewHolderTask {
+    ctor public Presenter.ViewHolderTask();
+    method public void run(android.support.v17.leanback.widget.Presenter.ViewHolder);
+  }
+
+  public abstract class PresenterSelector {
+    ctor public PresenterSelector();
+    method public abstract android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+    method public android.support.v17.leanback.widget.Presenter[] getPresenters();
+  }
+
+  public abstract class PresenterSwitcher {
+    ctor public PresenterSwitcher();
+    method public void clear();
+    method public final android.view.ViewGroup getParentViewGroup();
+    method public void init(android.view.ViewGroup, android.support.v17.leanback.widget.PresenterSelector);
+    method protected abstract void insertView(android.view.View);
+    method protected void onViewSelected(android.view.View);
+    method public void select(java.lang.Object);
+    method protected void showView(android.view.View, boolean);
+    method public void unselect();
+  }
+
+  public class Row {
+    ctor public Row(long, android.support.v17.leanback.widget.HeaderItem);
+    ctor public Row(android.support.v17.leanback.widget.HeaderItem);
+    ctor public Row();
+    method public final android.support.v17.leanback.widget.HeaderItem getHeaderItem();
+    method public final long getId();
+    method public boolean isRenderedAsRowView();
+    method public final void setHeaderItem(android.support.v17.leanback.widget.HeaderItem);
+    method public final void setId(long);
+  }
+
+  public class RowHeaderPresenter extends android.support.v17.leanback.widget.Presenter {
+    ctor public RowHeaderPresenter();
+    method protected static float getFontDescent(android.widget.TextView, android.graphics.Paint);
+    method public int getSpaceUnderBaseline(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder);
+    method public boolean isNullItemVisibilityGone();
+    method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+    method public android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+    method protected void onSelectLevelChanged(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder);
+    method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public void setNullItemVisibilityGone(boolean);
+    method public final void setSelectLevel(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, float);
+  }
+
+  public static class RowHeaderPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+    ctor public RowHeaderPresenter.ViewHolder(android.view.View);
+    method public final float getSelectLevel();
+  }
+
+  public final class RowHeaderView extends android.widget.TextView {
+    ctor public RowHeaderView(android.content.Context);
+    ctor public RowHeaderView(android.content.Context, android.util.AttributeSet);
+    ctor public RowHeaderView(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public abstract class RowPresenter extends android.support.v17.leanback.widget.Presenter {
+    ctor public RowPresenter();
+    method protected abstract android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+    method protected void dispatchItemSelectedListener(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+    method public void freeze(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+    method public final android.support.v17.leanback.widget.RowHeaderPresenter getHeaderPresenter();
+    method public final android.support.v17.leanback.widget.RowPresenter.ViewHolder getRowViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public final boolean getSelectEffectEnabled();
+    method public final float getSelectLevel(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public final int getSyncActivatePolicy();
+    method protected void initializeRowViewHolder(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+    method protected boolean isClippingChildren();
+    method public boolean isUsingDefaultSelectEffect();
+    method protected void onBindRowViewHolder(android.support.v17.leanback.widget.RowPresenter.ViewHolder, java.lang.Object);
+    method public final void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+    method public final android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+    method protected void onRowViewAttachedToWindow(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+    method protected void onRowViewDetachedFromWindow(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+    method protected void onRowViewExpanded(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+    method protected void onRowViewSelected(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+    method protected void onSelectLevelChanged(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+    method protected void onUnbindRowViewHolder(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+    method public final void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public final void onViewAttachedToWindow(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public final void onViewDetachedFromWindow(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public void setEntranceTransitionState(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+    method public final void setHeaderPresenter(android.support.v17.leanback.widget.RowHeaderPresenter);
+    method public final void setRowViewExpanded(android.support.v17.leanback.widget.Presenter.ViewHolder, boolean);
+    method public final void setRowViewSelected(android.support.v17.leanback.widget.Presenter.ViewHolder, boolean);
+    method public final void setSelectEffectEnabled(boolean);
+    method public final void setSelectLevel(android.support.v17.leanback.widget.Presenter.ViewHolder, float);
+    method public final void setSyncActivatePolicy(int);
+    field public static final int SYNC_ACTIVATED_CUSTOM = 0; // 0x0
+    field public static final int SYNC_ACTIVATED_TO_EXPANDED = 1; // 0x1
+    field public static final int SYNC_ACTIVATED_TO_EXPANDED_AND_SELECTED = 3; // 0x3
+    field public static final int SYNC_ACTIVATED_TO_SELECTED = 2; // 0x2
+  }
+
+  public static class RowPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+    ctor public RowPresenter.ViewHolder(android.view.View);
+    method public final android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder getHeaderViewHolder();
+    method public final android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+    method public final android.support.v17.leanback.widget.BaseOnItemViewSelectedListener getOnItemViewSelectedListener();
+    method public android.view.View.OnKeyListener getOnKeyListener();
+    method public final android.support.v17.leanback.widget.Row getRow();
+    method public final java.lang.Object getRowObject();
+    method public final float getSelectLevel();
+    method public java.lang.Object getSelectedItem();
+    method public android.support.v17.leanback.widget.Presenter.ViewHolder getSelectedItemViewHolder();
+    method public final boolean isExpanded();
+    method public final boolean isSelected();
+    method public final void setActivated(boolean);
+    method public final void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+    method public final void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+    method public void setOnKeyListener(android.view.View.OnKeyListener);
+    method public final void syncActivatedStatus(android.view.View);
+    field protected final android.support.v17.leanback.graphics.ColorOverlayDimmer mColorDimmer;
+  }
+
+  public class SearchBar extends android.widget.RelativeLayout {
+    ctor public SearchBar(android.content.Context);
+    ctor public SearchBar(android.content.Context, android.util.AttributeSet);
+    ctor public SearchBar(android.content.Context, android.util.AttributeSet, int);
+    method public void displayCompletions(java.util.List<java.lang.String>);
+    method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
+    method public android.graphics.drawable.Drawable getBadgeDrawable();
+    method public java.lang.CharSequence getHint();
+    method public java.lang.String getTitle();
+    method public boolean isRecognizing();
+    method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+    method public void setPermissionListener(android.support.v17.leanback.widget.SearchBar.SearchBarPermissionListener);
+    method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setSearchAffordanceColorsInListening(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setSearchBarListener(android.support.v17.leanback.widget.SearchBar.SearchBarListener);
+    method public void setSearchQuery(java.lang.String);
+    method public void setSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback);
+    method public void setSpeechRecognizer(android.speech.SpeechRecognizer);
+    method public void setTitle(java.lang.String);
+    method public void startRecognition();
+    method public void stopRecognition();
+  }
+
+  public static abstract interface SearchBar.SearchBarListener {
+    method public abstract void onKeyboardDismiss(java.lang.String);
+    method public abstract void onSearchQueryChange(java.lang.String);
+    method public abstract void onSearchQuerySubmit(java.lang.String);
+  }
+
+  public static abstract interface SearchBar.SearchBarPermissionListener {
+    method public abstract void requestAudioPermission();
+  }
+
+  public class SearchEditText extends android.support.v17.leanback.widget.StreamingTextView {
+    ctor public SearchEditText(android.content.Context);
+    ctor public SearchEditText(android.content.Context, android.util.AttributeSet);
+    ctor public SearchEditText(android.content.Context, android.util.AttributeSet, int);
+    method public void setOnKeyboardDismissListener(android.support.v17.leanback.widget.SearchEditText.OnKeyboardDismissListener);
+  }
+
+  public static abstract interface SearchEditText.OnKeyboardDismissListener {
+    method public abstract void onKeyboardDismiss();
+  }
+
+  public class SearchOrbView extends android.widget.FrameLayout implements android.view.View.OnClickListener {
+    ctor public SearchOrbView(android.content.Context);
+    ctor public SearchOrbView(android.content.Context, android.util.AttributeSet);
+    ctor public SearchOrbView(android.content.Context, android.util.AttributeSet, int);
+    method public void enableOrbColorAnimation(boolean);
+    method public int getOrbColor();
+    method public android.support.v17.leanback.widget.SearchOrbView.Colors getOrbColors();
+    method public android.graphics.drawable.Drawable getOrbIcon();
+    method public void onClick(android.view.View);
+    method public void setOnOrbClickedListener(android.view.View.OnClickListener);
+    method public void setOrbColor(int);
+    method public deprecated void setOrbColor(int, int);
+    method public void setOrbColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setOrbIcon(android.graphics.drawable.Drawable);
+  }
+
+  public static class SearchOrbView.Colors {
+    ctor public SearchOrbView.Colors(int);
+    ctor public SearchOrbView.Colors(int, int);
+    ctor public SearchOrbView.Colors(int, int, int);
+    method public static int getBrightColor(int);
+    field public int brightColor;
+    field public int color;
+    field public int iconColor;
+  }
+
+  public class SectionRow extends android.support.v17.leanback.widget.Row {
+    ctor public SectionRow(android.support.v17.leanback.widget.HeaderItem);
+    ctor public SectionRow(long, java.lang.String);
+    ctor public SectionRow(java.lang.String);
+    method public final boolean isRenderedAsRowView();
+  }
+
+  public class ShadowOverlayContainer extends android.widget.FrameLayout {
+    ctor public ShadowOverlayContainer(android.content.Context);
+    ctor public ShadowOverlayContainer(android.content.Context, android.util.AttributeSet);
+    ctor public ShadowOverlayContainer(android.content.Context, android.util.AttributeSet, int);
+    method public int getShadowType();
+    method public android.view.View getWrappedView();
+    method public deprecated void initialize(boolean, boolean);
+    method public deprecated void initialize(boolean, boolean, boolean);
+    method public static void prepareParentForShadow(android.view.ViewGroup);
+    method public void setOverlayColor(int);
+    method public void setShadowFocusLevel(float);
+    method public static boolean supportsDynamicShadow();
+    method public static boolean supportsShadow();
+    method public void useDynamicShadow();
+    method public void useDynamicShadow(float, float);
+    method public void useStaticShadow();
+    method public void wrap(android.view.View);
+    field public static final int SHADOW_DYNAMIC = 3; // 0x3
+    field public static final int SHADOW_NONE = 1; // 0x1
+    field public static final int SHADOW_STATIC = 2; // 0x2
+  }
+
+  public final class ShadowOverlayHelper {
+    method public android.support.v17.leanback.widget.ShadowOverlayContainer createShadowOverlayContainer(android.content.Context);
+    method public int getShadowType();
+    method public boolean needsOverlay();
+    method public boolean needsRoundedCorner();
+    method public boolean needsWrapper();
+    method public void onViewCreated(android.view.View);
+    method public void prepareParentForShadow(android.view.ViewGroup);
+    method public static void setNoneWrapperOverlayColor(android.view.View, int);
+    method public static void setNoneWrapperShadowFocusLevel(android.view.View, float);
+    method public void setOverlayColor(android.view.View, int);
+    method public void setShadowFocusLevel(android.view.View, float);
+    method public static boolean supportsDynamicShadow();
+    method public static boolean supportsForeground();
+    method public static boolean supportsRoundedCorner();
+    method public static boolean supportsShadow();
+    field public static final int SHADOW_DYNAMIC = 3; // 0x3
+    field public static final int SHADOW_NONE = 1; // 0x1
+    field public static final int SHADOW_STATIC = 2; // 0x2
+  }
+
+  public static final class ShadowOverlayHelper.Builder {
+    ctor public ShadowOverlayHelper.Builder();
+    method public android.support.v17.leanback.widget.ShadowOverlayHelper build(android.content.Context);
+    method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder keepForegroundDrawable(boolean);
+    method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder needsOverlay(boolean);
+    method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder needsRoundedCorner(boolean);
+    method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder needsShadow(boolean);
+    method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder options(android.support.v17.leanback.widget.ShadowOverlayHelper.Options);
+    method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder preferZOrder(boolean);
+  }
+
+  public static final class ShadowOverlayHelper.Options {
+    ctor public ShadowOverlayHelper.Options();
+    method public android.support.v17.leanback.widget.ShadowOverlayHelper.Options dynamicShadowZ(float, float);
+    method public final float getDynamicShadowFocusedZ();
+    method public final float getDynamicShadowUnfocusedZ();
+    method public final int getRoundedCornerRadius();
+    method public android.support.v17.leanback.widget.ShadowOverlayHelper.Options roundedCornerRadius(int);
+    field public static final android.support.v17.leanback.widget.ShadowOverlayHelper.Options DEFAULT;
+  }
+
+  public final class SinglePresenterSelector extends android.support.v17.leanback.widget.PresenterSelector {
+    ctor public SinglePresenterSelector(android.support.v17.leanback.widget.Presenter);
+    method public android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+  }
+
+  public class SparseArrayObjectAdapter extends android.support.v17.leanback.widget.ObjectAdapter {
+    ctor public SparseArrayObjectAdapter(android.support.v17.leanback.widget.PresenterSelector);
+    ctor public SparseArrayObjectAdapter(android.support.v17.leanback.widget.Presenter);
+    ctor public SparseArrayObjectAdapter();
+    method public void clear(int);
+    method public void clear();
+    method public java.lang.Object get(int);
+    method public int indexOf(java.lang.Object);
+    method public int indexOf(int);
+    method public java.lang.Object lookup(int);
+    method public void notifyArrayItemRangeChanged(int, int);
+    method public void set(int, java.lang.Object);
+    method public int size();
+  }
+
+  public class SpeechOrbView extends android.support.v17.leanback.widget.SearchOrbView {
+    ctor public SpeechOrbView(android.content.Context);
+    ctor public SpeechOrbView(android.content.Context, android.util.AttributeSet);
+    ctor public SpeechOrbView(android.content.Context, android.util.AttributeSet, int);
+    method public void setListeningOrbColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setNotListeningOrbColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setSoundLevel(int);
+    method public void showListening();
+    method public void showNotListening();
+  }
+
+  public abstract interface SpeechRecognitionCallback {
+    method public abstract void recognizeSpeech();
+  }
+
+   class StreamingTextView extends android.widget.EditText {
+    ctor public StreamingTextView(android.content.Context, android.util.AttributeSet);
+    ctor public StreamingTextView(android.content.Context, android.util.AttributeSet, int);
+    method public static boolean isLayoutRtl(android.view.View);
+    method public void reset();
+    method public void setFinalRecognizedText(java.lang.CharSequence);
+    method public void updateRecognizedText(java.lang.String, java.lang.String);
+    method public void updateRecognizedText(java.lang.String, java.util.List<java.lang.Float>);
+  }
+
+  public class TitleHelper {
+    ctor public TitleHelper(android.view.ViewGroup, android.view.View);
+    method public android.support.v17.leanback.widget.BrowseFrameLayout.OnFocusSearchListener getOnFocusSearchListener();
+    method public android.view.ViewGroup getSceneRoot();
+    method public android.view.View getTitleView();
+    method public void showTitle(boolean);
+  }
+
+  public class TitleView extends android.widget.FrameLayout implements android.support.v17.leanback.widget.TitleViewAdapter.Provider {
+    ctor public TitleView(android.content.Context);
+    ctor public TitleView(android.content.Context, android.util.AttributeSet);
+    ctor public TitleView(android.content.Context, android.util.AttributeSet, int);
+    method public void enableAnimation(boolean);
+    method public android.graphics.drawable.Drawable getBadgeDrawable();
+    method public android.support.v17.leanback.widget.SearchOrbView.Colors getSearchAffordanceColors();
+    method public android.view.View getSearchAffordanceView();
+    method public java.lang.CharSequence getTitle();
+    method public android.support.v17.leanback.widget.TitleViewAdapter getTitleViewAdapter();
+    method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+    method public void setOnSearchClickedListener(android.view.View.OnClickListener);
+    method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setTitle(java.lang.CharSequence);
+    method public void updateComponentsVisibility(int);
+  }
+
+  public abstract class TitleViewAdapter {
+    ctor public TitleViewAdapter();
+    method public android.graphics.drawable.Drawable getBadgeDrawable();
+    method public android.support.v17.leanback.widget.SearchOrbView.Colors getSearchAffordanceColors();
+    method public abstract android.view.View getSearchAffordanceView();
+    method public java.lang.CharSequence getTitle();
+    method public void setAnimationEnabled(boolean);
+    method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+    method public void setOnSearchClickedListener(android.view.View.OnClickListener);
+    method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+    method public void setTitle(java.lang.CharSequence);
+    method public void updateComponentsVisibility(int);
+    field public static final int BRANDING_VIEW_VISIBLE = 2; // 0x2
+    field public static final int FULL_VIEW_VISIBLE = 6; // 0x6
+    field public static final int SEARCH_VIEW_VISIBLE = 4; // 0x4
+  }
+
+  public static abstract interface TitleViewAdapter.Provider {
+    method public abstract android.support.v17.leanback.widget.TitleViewAdapter getTitleViewAdapter();
+  }
+
+  public class VerticalGridPresenter extends android.support.v17.leanback.widget.Presenter {
+    ctor public VerticalGridPresenter();
+    ctor public VerticalGridPresenter(int);
+    ctor public VerticalGridPresenter(int, boolean);
+    method public final boolean areChildRoundedCornersEnabled();
+    method protected android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder createGridViewHolder(android.view.ViewGroup);
+    method protected android.support.v17.leanback.widget.ShadowOverlayHelper.Options createShadowOverlayOptions();
+    method public final void enableChildRoundedCorners(boolean);
+    method public final int getFocusZoomFactor();
+    method public final boolean getKeepChildForeground();
+    method public int getNumberOfColumns();
+    method public final android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+    method public final android.support.v17.leanback.widget.OnItemViewSelectedListener getOnItemViewSelectedListener();
+    method public final boolean getShadowEnabled();
+    method protected void initializeGridViewHolder(android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder);
+    method public final boolean isFocusDimmerUsed();
+    method public boolean isUsingDefaultShadow();
+    method public boolean isUsingZOrder(android.content.Context);
+    method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+    method public final android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+    method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public void setEntranceTransitionState(android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder, boolean);
+    method public final void setKeepChildForeground(boolean);
+    method public void setNumberOfColumns(int);
+    method public final void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+    method public final void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+    method public final void setShadowEnabled(boolean);
+  }
+
+  public static class VerticalGridPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+    ctor public VerticalGridPresenter.ViewHolder(android.support.v17.leanback.widget.VerticalGridView);
+    method public android.support.v17.leanback.widget.VerticalGridView getGridView();
+  }
+
+  public class VerticalGridView extends android.support.v7.widget.RecyclerView {
+    ctor public VerticalGridView(android.content.Context);
+    ctor public VerticalGridView(android.content.Context, android.util.AttributeSet);
+    ctor public VerticalGridView(android.content.Context, android.util.AttributeSet, int);
+    method protected void initAttributes(android.content.Context, android.util.AttributeSet);
+    method public void setColumnWidth(int);
+    method public void setNumColumns(int);
+  }
+
+  public abstract interface ViewHolderTask {
+    method public abstract void run(android.support.v7.widget.RecyclerView.ViewHolder);
+  }
+
+}
+
+package android.support.v17.leanback.widget.picker {
+
+  public class Picker extends android.widget.FrameLayout {
+    ctor public Picker(android.content.Context, android.util.AttributeSet, int);
+    method public void addOnValueChangedListener(android.support.v17.leanback.widget.picker.Picker.PickerValueListener);
+    method public float getActivatedVisibleItemCount();
+    method public android.support.v17.leanback.widget.picker.PickerColumn getColumnAt(int);
+    method public int getColumnsCount();
+    method protected int getPickerItemHeightPixels();
+    method public final int getPickerItemLayoutId();
+    method public final int getPickerItemTextViewId();
+    method public int getSelectedColumn();
+    method public final java.lang.CharSequence getSeparator();
+    method public float getVisibleItemCount();
+    method public void onColumnValueChanged(int, int);
+    method public void removeOnValueChangedListener(android.support.v17.leanback.widget.picker.Picker.PickerValueListener);
+    method public void setActivatedVisibleItemCount(float);
+    method public void setColumnAt(int, android.support.v17.leanback.widget.picker.PickerColumn);
+    method public void setColumnValue(int, int, boolean);
+    method public void setColumns(java.util.List<android.support.v17.leanback.widget.picker.PickerColumn>);
+    method public final void setPickerItemTextViewId(int);
+    method public void setSelectedColumn(int);
+    method public final void setSeparator(java.lang.CharSequence);
+    method public void setVisibleItemCount(float);
+  }
+
+  public static abstract interface Picker.PickerValueListener {
+    method public abstract void onValueChanged(android.support.v17.leanback.widget.picker.Picker, int);
+  }
+
+  public class PickerColumn {
+    ctor public PickerColumn();
+    method public int getCount();
+    method public int getCurrentValue();
+    method public java.lang.CharSequence getLabelFor(int);
+    method public java.lang.String getLabelFormat();
+    method public int getMaxValue();
+    method public int getMinValue();
+    method public java.lang.CharSequence[] getStaticLabels();
+    method public void setCurrentValue(int);
+    method public void setLabelFormat(java.lang.String);
+    method public void setMaxValue(int);
+    method public void setMinValue(int);
+    method public void setStaticLabels(java.lang.CharSequence[]);
+  }
+
+}
+
+package android.support.v17.preference {
+
+  public abstract class BaseLeanbackPreferenceFragment extends android.support.v14.preference.PreferenceFragment {
+    ctor public BaseLeanbackPreferenceFragment();
+  }
+
+  public class LeanbackListPreferenceDialogFragment extends android.support.v17.preference.LeanbackPreferenceDialogFragment {
+    ctor public LeanbackListPreferenceDialogFragment();
+    method public static android.support.v17.preference.LeanbackListPreferenceDialogFragment newInstanceMulti(java.lang.String);
+    method public static android.support.v17.preference.LeanbackListPreferenceDialogFragment newInstanceSingle(java.lang.String);
+    method public android.support.v7.widget.RecyclerView.Adapter onCreateAdapter();
+  }
+
+  public class LeanbackListPreferenceDialogFragment.AdapterMulti extends android.support.v7.widget.RecyclerView.Adapter implements android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
+    ctor public LeanbackListPreferenceDialogFragment.AdapterMulti(java.lang.CharSequence[], java.lang.CharSequence[], java.util.Set<java.lang.String>);
+    method public int getItemCount();
+    method public void onBindViewHolder(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder, int);
+    method public android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+    method public void onItemClick(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder);
+  }
+
+  public class LeanbackListPreferenceDialogFragment.AdapterSingle extends android.support.v7.widget.RecyclerView.Adapter implements android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
+    ctor public LeanbackListPreferenceDialogFragment.AdapterSingle(java.lang.CharSequence[], java.lang.CharSequence[], java.lang.CharSequence);
+    method public int getItemCount();
+    method public void onBindViewHolder(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder, int);
+    method public android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+    method public void onItemClick(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder);
+  }
+
+  public static class LeanbackListPreferenceDialogFragment.ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder implements android.view.View.OnClickListener {
+    ctor public LeanbackListPreferenceDialogFragment.ViewHolder(android.view.View, android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener);
+    method public android.view.ViewGroup getContainer();
+    method public android.widget.TextView getTitleView();
+    method public android.widget.Checkable getWidgetView();
+    method public void onClick(android.view.View);
+  }
+
+  public static abstract interface LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
+    method public abstract void onItemClick(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder);
+  }
+
+  public class LeanbackPreferenceDialogFragment extends android.app.Fragment {
+    ctor public LeanbackPreferenceDialogFragment();
+    method public android.support.v7.preference.DialogPreference getPreference();
+    field public static final java.lang.String ARG_KEY = "key";
+  }
+
+  public abstract class LeanbackPreferenceFragment extends android.support.v17.preference.BaseLeanbackPreferenceFragment {
+    ctor public LeanbackPreferenceFragment();
+    method public void setTitle(java.lang.CharSequence);
+  }
+
+  public abstract class LeanbackSettingsFragment extends android.app.Fragment implements android.support.v14.preference.PreferenceFragment.OnPreferenceDisplayDialogCallback android.support.v14.preference.PreferenceFragment.OnPreferenceStartFragmentCallback android.support.v14.preference.PreferenceFragment.OnPreferenceStartScreenCallback {
+    ctor public LeanbackSettingsFragment();
+    method public boolean onPreferenceDisplayDialog(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
+    method public abstract void onPreferenceStartInitialScreen();
+    method public void startImmersiveFragment(android.app.Fragment);
+    method public void startPreferenceFragment(android.app.Fragment);
+  }
+
+}
+
+package android.support.v4.accessibilityservice {
+
+  public final class AccessibilityServiceInfoCompat {
+    method public static java.lang.String capabilityToString(int);
+    method public static java.lang.String feedbackTypeToString(int);
+    method public static java.lang.String flagToString(int);
+    method public static boolean getCanRetrieveWindowContent(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static int getCapabilities(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static deprecated java.lang.String getDescription(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static java.lang.String getId(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static android.content.pm.ResolveInfo getResolveInfo(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static java.lang.String getSettingsActivityName(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static java.lang.String loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager);
+    field public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 8; // 0x8
+    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+    field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
+    field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
+    field public static final int DEFAULT = 1; // 0x1
+    field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
+    field public static final int FEEDBACK_BRAILLE = 32; // 0x20
+    field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+    field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+    field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
+    field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
+  }
+
+}
+
+package android.support.v4.app {
+
+  public deprecated class ActionBarDrawerToggle implements android.support.v4.widget.DrawerLayout.DrawerListener {
+    ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, int, int, int);
+    ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, boolean, int, int, int);
+    method public boolean isDrawerIndicatorEnabled();
+    method public void onConfigurationChanged(android.content.res.Configuration);
+    method public void onDrawerClosed(android.view.View);
+    method public void onDrawerOpened(android.view.View);
+    method public void onDrawerSlide(android.view.View, float);
+    method public void onDrawerStateChanged(int);
+    method public boolean onOptionsItemSelected(android.view.MenuItem);
+    method public void setDrawerIndicatorEnabled(boolean);
+    method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
+    method public void setHomeAsUpIndicator(int);
+    method public void syncState();
+  }
+
+  public static abstract interface ActionBarDrawerToggle.Delegate {
+    method public abstract android.graphics.drawable.Drawable getThemeUpIndicator();
+    method public abstract void setActionBarDescription(int);
+    method public abstract void setActionBarUpIndicator(android.graphics.drawable.Drawable, int);
+  }
+
+  public static abstract interface ActionBarDrawerToggle.DelegateProvider {
+    method public abstract android.support.v4.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+  }
+
+  public class ActivityCompat extends android.support.v4.content.ContextCompat {
+    ctor protected ActivityCompat();
+    method public static void finishAffinity(android.app.Activity);
+    method public static void finishAfterTransition(android.app.Activity);
+    method public static android.net.Uri getReferrer(android.app.Activity);
+    method public static boolean invalidateOptionsMenu(android.app.Activity);
+    method public static void postponeEnterTransition(android.app.Activity);
+    method public static void requestPermissions(android.app.Activity, java.lang.String[], int);
+    method public static void setEnterSharedElementCallback(android.app.Activity, android.support.v4.app.SharedElementCallback);
+    method public static void setExitSharedElementCallback(android.app.Activity, android.support.v4.app.SharedElementCallback);
+    method public static boolean shouldShowRequestPermissionRationale(android.app.Activity, java.lang.String);
+    method public static void startActivityForResult(android.app.Activity, android.content.Intent, int, android.os.Bundle);
+    method public static void startIntentSenderForResult(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public static void startPostponedEnterTransition(android.app.Activity);
+  }
+
+  public static abstract interface ActivityCompat.OnRequestPermissionsResultCallback {
+    method public abstract void onRequestPermissionsResult(int, java.lang.String[], int[]);
+  }
+
+  public final class ActivityManagerCompat {
+    method public static boolean isLowRamDevice(android.app.ActivityManager);
+  }
+
+  public class ActivityOptionsCompat {
+    ctor protected ActivityOptionsCompat();
+    method public android.graphics.Rect getLaunchBounds();
+    method public static android.support.v4.app.ActivityOptionsCompat makeBasic();
+    method public static android.support.v4.app.ActivityOptionsCompat makeClipRevealAnimation(android.view.View, int, int, int, int);
+    method public static android.support.v4.app.ActivityOptionsCompat makeCustomAnimation(android.content.Context, int, int);
+    method public static android.support.v4.app.ActivityOptionsCompat makeScaleUpAnimation(android.view.View, int, int, int, int);
+    method public static android.support.v4.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.view.View, java.lang.String);
+    method public static android.support.v4.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.support.v4.util.Pair<android.view.View, java.lang.String>...);
+    method public static android.support.v4.app.ActivityOptionsCompat makeTaskLaunchBehind();
+    method public static android.support.v4.app.ActivityOptionsCompat makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
+    method public void requestUsageTimeReport(android.app.PendingIntent);
+    method public android.support.v4.app.ActivityOptionsCompat setLaunchBounds(android.graphics.Rect);
+    method public android.os.Bundle toBundle();
+    method public void update(android.support.v4.app.ActivityOptionsCompat);
+    field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+    field public static final java.lang.String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
+  }
+
+  public class AppLaunchChecker {
+    ctor public AppLaunchChecker();
+    method public static boolean hasStartedFromLauncher(android.content.Context);
+    method public static void onActivityCreate(android.app.Activity);
+  }
+
+  public final class AppOpsManagerCompat {
+    method public static int noteOp(android.content.Context, java.lang.String, int, java.lang.String);
+    method public static int noteProxyOp(android.content.Context, java.lang.String, java.lang.String);
+    method public static java.lang.String permissionToOp(java.lang.String);
+    field public static final int MODE_ALLOWED = 0; // 0x0
+    field public static final int MODE_DEFAULT = 3; // 0x3
+    field public static final int MODE_IGNORED = 1; // 0x1
+  }
+
+  public final class BundleCompat {
+    method public static android.os.IBinder getBinder(android.os.Bundle, java.lang.String);
+    method public static void putBinder(android.os.Bundle, java.lang.String, android.os.IBinder);
+  }
+
+  public class DialogFragment extends android.support.v4.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
+    ctor public DialogFragment();
+    method public void dismiss();
+    method public void dismissAllowingStateLoss();
+    method public android.app.Dialog getDialog();
+    method public boolean getShowsDialog();
+    method public int getTheme();
+    method public boolean isCancelable();
+    method public void onCancel(android.content.DialogInterface);
+    method public android.app.Dialog onCreateDialog(android.os.Bundle);
+    method public void onDismiss(android.content.DialogInterface);
+    method public void setCancelable(boolean);
+    method public void setShowsDialog(boolean);
+    method public void setStyle(int, int);
+    method public void show(android.support.v4.app.FragmentManager, java.lang.String);
+    method public int show(android.support.v4.app.FragmentTransaction, java.lang.String);
+    field public static final int STYLE_NORMAL = 0; // 0x0
+    field public static final int STYLE_NO_FRAME = 2; // 0x2
+    field public static final int STYLE_NO_INPUT = 3; // 0x3
+    field public static final int STYLE_NO_TITLE = 1; // 0x1
+  }
+
+  public class Fragment implements android.content.ComponentCallbacks android.view.View.OnCreateContextMenuListener {
+    ctor public Fragment();
+    method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public final boolean equals(java.lang.Object);
+    method public final android.support.v4.app.FragmentActivity getActivity();
+    method public boolean getAllowEnterTransitionOverlap();
+    method public boolean getAllowReturnTransitionOverlap();
+    method public final android.os.Bundle getArguments();
+    method public final android.support.v4.app.FragmentManager getChildFragmentManager();
+    method public android.content.Context getContext();
+    method public java.lang.Object getEnterTransition();
+    method public java.lang.Object getExitTransition();
+    method public final android.support.v4.app.FragmentManager getFragmentManager();
+    method public final java.lang.Object getHost();
+    method public final int getId();
+    method public android.support.v4.app.LoaderManager getLoaderManager();
+    method public final android.support.v4.app.Fragment getParentFragment();
+    method public java.lang.Object getReenterTransition();
+    method public final android.content.res.Resources getResources();
+    method public final boolean getRetainInstance();
+    method public java.lang.Object getReturnTransition();
+    method public java.lang.Object getSharedElementEnterTransition();
+    method public java.lang.Object getSharedElementReturnTransition();
+    method public final java.lang.String getString(int);
+    method public final java.lang.String getString(int, java.lang.Object...);
+    method public final java.lang.String getTag();
+    method public final android.support.v4.app.Fragment getTargetFragment();
+    method public final int getTargetRequestCode();
+    method public final java.lang.CharSequence getText(int);
+    method public boolean getUserVisibleHint();
+    method public android.view.View getView();
+    method public final int hashCode();
+    method public static android.support.v4.app.Fragment instantiate(android.content.Context, java.lang.String);
+    method public static android.support.v4.app.Fragment instantiate(android.content.Context, java.lang.String, android.os.Bundle);
+    method public final boolean isAdded();
+    method public final boolean isDetached();
+    method public final boolean isHidden();
+    method public final boolean isInLayout();
+    method public final boolean isRemoving();
+    method public final boolean isResumed();
+    method public final boolean isVisible();
+    method public void onActivityCreated(android.os.Bundle);
+    method public void onActivityResult(int, int, android.content.Intent);
+    method public void onAttach(android.content.Context);
+    method public deprecated void onAttach(android.app.Activity);
+    method public void onAttachFragment(android.support.v4.app.Fragment);
+    method public void onConfigurationChanged(android.content.res.Configuration);
+    method public boolean onContextItemSelected(android.view.MenuItem);
+    method public void onCreate(android.os.Bundle);
+    method public android.view.animation.Animation onCreateAnimation(int, boolean, int);
+    method public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo);
+    method public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+    method public android.view.View onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method public void onDestroy();
+    method public void onDestroyOptionsMenu();
+    method public void onDestroyView();
+    method public void onDetach();
+    method public void onHiddenChanged(boolean);
+    method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
+    method public deprecated void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle);
+    method public void onLowMemory();
+    method public void onMultiWindowModeChanged(boolean);
+    method public boolean onOptionsItemSelected(android.view.MenuItem);
+    method public void onOptionsMenuClosed(android.view.Menu);
+    method public void onPause();
+    method public void onPictureInPictureModeChanged(boolean);
+    method public void onPrepareOptionsMenu(android.view.Menu);
+    method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
+    method public void onResume();
+    method public void onSaveInstanceState(android.os.Bundle);
+    method public void onStart();
+    method public void onStop();
+    method public void onViewCreated(android.view.View, android.os.Bundle);
+    method public void onViewStateRestored(android.os.Bundle);
+    method public void postponeEnterTransition();
+    method public void registerForContextMenu(android.view.View);
+    method public final void requestPermissions(java.lang.String[], int);
+    method public void setAllowEnterTransitionOverlap(boolean);
+    method public void setAllowReturnTransitionOverlap(boolean);
+    method public void setArguments(android.os.Bundle);
+    method public void setEnterSharedElementCallback(android.support.v4.app.SharedElementCallback);
+    method public void setEnterTransition(java.lang.Object);
+    method public void setExitSharedElementCallback(android.support.v4.app.SharedElementCallback);
+    method public void setExitTransition(java.lang.Object);
+    method public void setHasOptionsMenu(boolean);
+    method public void setInitialSavedState(android.support.v4.app.Fragment.SavedState);
+    method public void setMenuVisibility(boolean);
+    method public void setReenterTransition(java.lang.Object);
+    method public void setRetainInstance(boolean);
+    method public void setReturnTransition(java.lang.Object);
+    method public void setSharedElementEnterTransition(java.lang.Object);
+    method public void setSharedElementReturnTransition(java.lang.Object);
+    method public void setTargetFragment(android.support.v4.app.Fragment, int);
+    method public void setUserVisibleHint(boolean);
+    method public boolean shouldShowRequestPermissionRationale(java.lang.String);
+    method public void startActivity(android.content.Intent);
+    method public void startActivity(android.content.Intent, android.os.Bundle);
+    method public void startActivityForResult(android.content.Intent, int);
+    method public void startActivityForResult(android.content.Intent, int, android.os.Bundle);
+    method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void startPostponedEnterTransition();
+    method public void unregisterForContextMenu(android.view.View);
+  }
+
+  public static class Fragment.InstantiationException extends java.lang.RuntimeException {
+    ctor public Fragment.InstantiationException(java.lang.String, java.lang.Exception);
+  }
+
+  public static class Fragment.SavedState implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.app.Fragment.SavedState> CREATOR;
+  }
+
+  public class FragmentActivity extends android.app.Activity implements android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback {
+    ctor public FragmentActivity();
+    method public java.lang.Object getLastCustomNonConfigurationInstance();
+    method public android.support.v4.app.FragmentManager getSupportFragmentManager();
+    method public android.support.v4.app.LoaderManager getSupportLoaderManager();
+    method public void onAttachFragment(android.support.v4.app.Fragment);
+    method protected void onResumeFragments();
+    method public java.lang.Object onRetainCustomNonConfigurationInstance();
+    method public final java.lang.Object onRetainNonConfigurationInstance();
+    method public void setEnterSharedElementCallback(android.support.v4.app.SharedElementCallback);
+    method public void setExitSharedElementCallback(android.support.v4.app.SharedElementCallback);
+    method public void startActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int);
+    method public void startActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int, android.os.Bundle);
+    method public void startIntentSenderFromFragment(android.support.v4.app.Fragment, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void supportFinishAfterTransition();
+    method public void supportInvalidateOptionsMenu();
+    method public void supportPostponeEnterTransition();
+    method public void supportStartPostponedEnterTransition();
+    method public final void validateRequestPermissionsRequestCode(int);
+  }
+
+  public abstract class FragmentContainer {
+    ctor public FragmentContainer();
+    method public abstract android.view.View onFindViewById(int);
+    method public abstract boolean onHasView();
+  }
+
+  public class FragmentController {
+    method public void attachHost(android.support.v4.app.Fragment);
+    method public static final android.support.v4.app.FragmentController createController(android.support.v4.app.FragmentHostCallback<?>);
+    method public void dispatchActivityCreated();
+    method public void dispatchConfigurationChanged(android.content.res.Configuration);
+    method public boolean dispatchContextItemSelected(android.view.MenuItem);
+    method public void dispatchCreate();
+    method public boolean dispatchCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+    method public void dispatchDestroy();
+    method public void dispatchDestroyView();
+    method public void dispatchLowMemory();
+    method public void dispatchMultiWindowModeChanged(boolean);
+    method public boolean dispatchOptionsItemSelected(android.view.MenuItem);
+    method public void dispatchOptionsMenuClosed(android.view.Menu);
+    method public void dispatchPause();
+    method public void dispatchPictureInPictureModeChanged(boolean);
+    method public boolean dispatchPrepareOptionsMenu(android.view.Menu);
+    method public void dispatchReallyStop();
+    method public void dispatchResume();
+    method public void dispatchStart();
+    method public void dispatchStop();
+    method public void doLoaderDestroy();
+    method public void doLoaderRetain();
+    method public void doLoaderStart();
+    method public void doLoaderStop(boolean);
+    method public void dumpLoaders(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public boolean execPendingActions();
+    method public android.support.v4.app.Fragment findFragmentByWho(java.lang.String);
+    method public java.util.List<android.support.v4.app.Fragment> getActiveFragments(java.util.List<android.support.v4.app.Fragment>);
+    method public int getActiveFragmentsCount();
+    method public android.support.v4.app.FragmentManager getSupportFragmentManager();
+    method public android.support.v4.app.LoaderManager getSupportLoaderManager();
+    method public void noteStateNotSaved();
+    method public android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+    method public void reportLoaderStart();
+    method public deprecated void restoreAllState(android.os.Parcelable, java.util.List<android.support.v4.app.Fragment>);
+    method public void restoreAllState(android.os.Parcelable, android.support.v4.app.FragmentManagerNonConfig);
+    method public void restoreLoaderNonConfig(android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager>);
+    method public android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager> retainLoaderNonConfig();
+    method public android.support.v4.app.FragmentManagerNonConfig retainNestedNonConfig();
+    method public deprecated java.util.List<android.support.v4.app.Fragment> retainNonConfig();
+    method public android.os.Parcelable saveAllState();
+  }
+
+  public abstract class FragmentHostCallback<E> extends android.support.v4.app.FragmentContainer {
+    ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
+    method public void onDump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public android.view.View onFindViewById(int);
+    method public abstract E onGetHost();
+    method public android.view.LayoutInflater onGetLayoutInflater();
+    method public int onGetWindowAnimations();
+    method public boolean onHasView();
+    method public boolean onHasWindowAnimations();
+    method public void onRequestPermissionsFromFragment(android.support.v4.app.Fragment, java.lang.String[], int);
+    method public boolean onShouldSaveFragmentState(android.support.v4.app.Fragment);
+    method public boolean onShouldShowRequestPermissionRationale(java.lang.String);
+    method public void onStartActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int);
+    method public void onStartActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int, android.os.Bundle);
+    method public void onStartIntentSenderFromFragment(android.support.v4.app.Fragment, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void onSupportInvalidateOptionsMenu();
+  }
+
+  public abstract class FragmentManager {
+    ctor public FragmentManager();
+    method public abstract void addOnBackStackChangedListener(android.support.v4.app.FragmentManager.OnBackStackChangedListener);
+    method public abstract android.support.v4.app.FragmentTransaction beginTransaction();
+    method public abstract void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public static void enableDebugLogging(boolean);
+    method public abstract boolean executePendingTransactions();
+    method public abstract android.support.v4.app.Fragment findFragmentById(int);
+    method public abstract android.support.v4.app.Fragment findFragmentByTag(java.lang.String);
+    method public abstract android.support.v4.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
+    method public abstract int getBackStackEntryCount();
+    method public abstract android.support.v4.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+    method public abstract boolean isDestroyed();
+    method public abstract void popBackStack();
+    method public abstract void popBackStack(java.lang.String, int);
+    method public abstract void popBackStack(int, int);
+    method public abstract boolean popBackStackImmediate();
+    method public abstract boolean popBackStackImmediate(java.lang.String, int);
+    method public abstract boolean popBackStackImmediate(int, int);
+    method public abstract void putFragment(android.os.Bundle, java.lang.String, android.support.v4.app.Fragment);
+    method public abstract void registerFragmentLifecycleCallbacks(android.support.v4.app.FragmentManager.FragmentLifecycleCallbacks, boolean);
+    method public abstract void removeOnBackStackChangedListener(android.support.v4.app.FragmentManager.OnBackStackChangedListener);
+    method public abstract android.support.v4.app.Fragment.SavedState saveFragmentInstanceState(android.support.v4.app.Fragment);
+    method public abstract void unregisterFragmentLifecycleCallbacks(android.support.v4.app.FragmentManager.FragmentLifecycleCallbacks);
+    field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
+  }
+
+  public static abstract interface FragmentManager.BackStackEntry {
+    method public abstract java.lang.CharSequence getBreadCrumbShortTitle();
+    method public abstract int getBreadCrumbShortTitleRes();
+    method public abstract java.lang.CharSequence getBreadCrumbTitle();
+    method public abstract int getBreadCrumbTitleRes();
+    method public abstract int getId();
+    method public abstract java.lang.String getName();
+  }
+
+  public static abstract class FragmentManager.FragmentLifecycleCallbacks {
+    ctor public FragmentManager.FragmentLifecycleCallbacks();
+    method public void onFragmentActivityCreated(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.os.Bundle);
+    method public void onFragmentAttached(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.content.Context);
+    method public void onFragmentCreated(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.os.Bundle);
+    method public void onFragmentDestroyed(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+    method public void onFragmentDetached(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+    method public void onFragmentPaused(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+    method public void onFragmentPreAttached(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.content.Context);
+    method public void onFragmentResumed(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+    method public void onFragmentSaveInstanceState(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.os.Bundle);
+    method public void onFragmentStarted(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+    method public void onFragmentStopped(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+    method public void onFragmentViewCreated(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.view.View, android.os.Bundle);
+    method public void onFragmentViewDestroyed(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+  }
+
+  public static abstract interface FragmentManager.OnBackStackChangedListener {
+    method public abstract void onBackStackChanged();
+  }
+
+  public class FragmentManagerNonConfig {
+  }
+
+  public abstract class FragmentPagerAdapter extends android.support.v4.view.PagerAdapter {
+    ctor public FragmentPagerAdapter(android.support.v4.app.FragmentManager);
+    method public abstract android.support.v4.app.Fragment getItem(int);
+    method public long getItemId(int);
+    method public boolean isViewFromObject(android.view.View, java.lang.Object);
+  }
+
+  public abstract class FragmentStatePagerAdapter extends android.support.v4.view.PagerAdapter {
+    ctor public FragmentStatePagerAdapter(android.support.v4.app.FragmentManager);
+    method public abstract android.support.v4.app.Fragment getItem(int);
+    method public boolean isViewFromObject(android.view.View, java.lang.Object);
+  }
+
+  public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
+    ctor public FragmentTabHost(android.content.Context);
+    ctor public FragmentTabHost(android.content.Context, android.util.AttributeSet);
+    method public void addTab(android.widget.TabHost.TabSpec, java.lang.Class<?>, android.os.Bundle);
+    method public void onTabChanged(java.lang.String);
+    method public void setup(android.content.Context, android.support.v4.app.FragmentManager);
+    method public void setup(android.content.Context, android.support.v4.app.FragmentManager, int);
+  }
+
+  public abstract class FragmentTransaction {
+    ctor public FragmentTransaction();
+    method public abstract android.support.v4.app.FragmentTransaction add(android.support.v4.app.Fragment, java.lang.String);
+    method public abstract android.support.v4.app.FragmentTransaction add(int, android.support.v4.app.Fragment);
+    method public abstract android.support.v4.app.FragmentTransaction add(int, android.support.v4.app.Fragment, java.lang.String);
+    method public abstract android.support.v4.app.FragmentTransaction addSharedElement(android.view.View, java.lang.String);
+    method public abstract android.support.v4.app.FragmentTransaction addToBackStack(java.lang.String);
+    method public abstract android.support.v4.app.FragmentTransaction attach(android.support.v4.app.Fragment);
+    method public abstract int commit();
+    method public abstract int commitAllowingStateLoss();
+    method public abstract void commitNow();
+    method public abstract void commitNowAllowingStateLoss();
+    method public abstract android.support.v4.app.FragmentTransaction detach(android.support.v4.app.Fragment);
+    method public abstract android.support.v4.app.FragmentTransaction disallowAddToBackStack();
+    method public abstract android.support.v4.app.FragmentTransaction hide(android.support.v4.app.Fragment);
+    method public abstract boolean isAddToBackStackAllowed();
+    method public abstract boolean isEmpty();
+    method public abstract android.support.v4.app.FragmentTransaction remove(android.support.v4.app.Fragment);
+    method public abstract android.support.v4.app.FragmentTransaction replace(int, android.support.v4.app.Fragment);
+    method public abstract android.support.v4.app.FragmentTransaction replace(int, android.support.v4.app.Fragment, java.lang.String);
+    method public abstract android.support.v4.app.FragmentTransaction setAllowOptimization(boolean);
+    method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbShortTitle(int);
+    method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbShortTitle(java.lang.CharSequence);
+    method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbTitle(int);
+    method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
+    method public abstract android.support.v4.app.FragmentTransaction setCustomAnimations(int, int);
+    method public abstract android.support.v4.app.FragmentTransaction setCustomAnimations(int, int, int, int);
+    method public abstract android.support.v4.app.FragmentTransaction setTransition(int);
+    method public abstract android.support.v4.app.FragmentTransaction setTransitionStyle(int);
+    method public abstract android.support.v4.app.FragmentTransaction show(android.support.v4.app.Fragment);
+    field public static final int TRANSIT_ENTER_MASK = 4096; // 0x1000
+    field public static final int TRANSIT_EXIT_MASK = 8192; // 0x2000
+    field public static final int TRANSIT_FRAGMENT_CLOSE = 8194; // 0x2002
+    field public static final int TRANSIT_FRAGMENT_FADE = 4099; // 0x1003
+    field public static final int TRANSIT_FRAGMENT_OPEN = 4097; // 0x1001
+    field public static final int TRANSIT_NONE = 0; // 0x0
+    field public static final int TRANSIT_UNSET = -1; // 0xffffffff
+  }
+
+  public class ListFragment extends android.support.v4.app.Fragment {
+    ctor public ListFragment();
+    method public android.widget.ListAdapter getListAdapter();
+    method public android.widget.ListView getListView();
+    method public long getSelectedItemId();
+    method public int getSelectedItemPosition();
+    method public void onListItemClick(android.widget.ListView, android.view.View, int, long);
+    method public void setEmptyText(java.lang.CharSequence);
+    method public void setListAdapter(android.widget.ListAdapter);
+    method public void setListShown(boolean);
+    method public void setListShownNoAnimation(boolean);
+    method public void setSelection(int);
+  }
+
+  public abstract class LoaderManager {
+    ctor public LoaderManager();
+    method public abstract void destroyLoader(int);
+    method public abstract void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public static void enableDebugLogging(boolean);
+    method public abstract <D> android.support.v4.content.Loader<D> getLoader(int);
+    method public boolean hasRunningLoaders();
+    method public abstract <D> android.support.v4.content.Loader<D> initLoader(int, android.os.Bundle, android.support.v4.app.LoaderManager.LoaderCallbacks<D>);
+    method public abstract <D> android.support.v4.content.Loader<D> restartLoader(int, android.os.Bundle, android.support.v4.app.LoaderManager.LoaderCallbacks<D>);
+  }
+
+  public static abstract interface LoaderManager.LoaderCallbacks<D> {
+    method public abstract android.support.v4.content.Loader<D> onCreateLoader(int, android.os.Bundle);
+    method public abstract void onLoadFinished(android.support.v4.content.Loader<D>, D);
+    method public abstract void onLoaderReset(android.support.v4.content.Loader<D>);
+  }
+
+  public final class NavUtils {
+    method public static android.content.Intent getParentActivityIntent(android.app.Activity);
+    method public static android.content.Intent getParentActivityIntent(android.content.Context, java.lang.Class<?>) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static android.content.Intent getParentActivityIntent(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static java.lang.String getParentActivityName(android.app.Activity);
+    method public static java.lang.String getParentActivityName(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static void navigateUpFromSameTask(android.app.Activity);
+    method public static void navigateUpTo(android.app.Activity, android.content.Intent);
+    method public static boolean shouldUpRecreateTask(android.app.Activity, android.content.Intent);
+    field public static final java.lang.String PARENT_ACTIVITY = "android.support.PARENT_ACTIVITY";
+  }
+
+  public class NotificationCompat {
+    ctor public NotificationCompat();
+    method public static android.support.v4.app.NotificationCompat.Action getAction(android.app.Notification, int);
+    method public static int getActionCount(android.app.Notification);
+    method public static java.lang.String getCategory(android.app.Notification);
+    method public static android.os.Bundle getExtras(android.app.Notification);
+    method public static java.lang.String getGroup(android.app.Notification);
+    method public static boolean getLocalOnly(android.app.Notification);
+    method public static java.lang.String getSortKey(android.app.Notification);
+    method public static boolean isGroupSummary(android.app.Notification);
+    field public static final java.lang.String CATEGORY_ALARM = "alarm";
+    field public static final java.lang.String CATEGORY_CALL = "call";
+    field public static final java.lang.String CATEGORY_EMAIL = "email";
+    field public static final java.lang.String CATEGORY_ERROR = "err";
+    field public static final java.lang.String CATEGORY_EVENT = "event";
+    field public static final java.lang.String CATEGORY_MESSAGE = "msg";
+    field public static final java.lang.String CATEGORY_PROGRESS = "progress";
+    field public static final java.lang.String CATEGORY_PROMO = "promo";
+    field public static final java.lang.String CATEGORY_RECOMMENDATION = "recommendation";
+    field public static final java.lang.String CATEGORY_REMINDER = "reminder";
+    field public static final java.lang.String CATEGORY_SERVICE = "service";
+    field public static final java.lang.String CATEGORY_SOCIAL = "social";
+    field public static final java.lang.String CATEGORY_STATUS = "status";
+    field public static final java.lang.String CATEGORY_SYSTEM = "sys";
+    field public static final java.lang.String CATEGORY_TRANSPORT = "transport";
+    field public static final int COLOR_DEFAULT = 0; // 0x0
+    field public static final int DEFAULT_ALL = -1; // 0xffffffff
+    field public static final int DEFAULT_LIGHTS = 4; // 0x4
+    field public static final int DEFAULT_SOUND = 1; // 0x1
+    field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
+    field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
+    field public static final java.lang.String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+    field public static final java.lang.String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
+    field public static final java.lang.String EXTRA_INFO_TEXT = "android.infoText";
+    field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
+    field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+    field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
+    field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
+    field public static final java.lang.String EXTRA_PEOPLE = "android.people";
+    field public static final java.lang.String EXTRA_PICTURE = "android.picture";
+    field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
+    field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
+    field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
+    field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+    field public static final java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
+    field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
+    field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
+    field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
+    field public static final java.lang.String EXTRA_SUB_TEXT = "android.subText";
+    field public static final java.lang.String EXTRA_SUMMARY_TEXT = "android.summaryText";
+    field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
+    field public static final java.lang.String EXTRA_TEXT = "android.text";
+    field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+    field public static final java.lang.String EXTRA_TITLE = "android.title";
+    field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
+    field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
+    field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
+    field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
+    field public static final deprecated int FLAG_HIGH_PRIORITY = 128; // 0x80
+    field public static final int FLAG_INSISTENT = 4; // 0x4
+    field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
+    field public static final int FLAG_NO_CLEAR = 32; // 0x20
+    field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
+    field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
+    field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final int PRIORITY_DEFAULT = 0; // 0x0
+    field public static final int PRIORITY_HIGH = 1; // 0x1
+    field public static final int PRIORITY_LOW = -1; // 0xffffffff
+    field public static final int PRIORITY_MAX = 2; // 0x2
+    field public static final int PRIORITY_MIN = -2; // 0xfffffffe
+    field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+    field public static final int VISIBILITY_PRIVATE = 0; // 0x0
+    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
+    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
+  }
+
+  public static class NotificationCompat.Action {
+    ctor public NotificationCompat.Action(int, java.lang.CharSequence, android.app.PendingIntent);
+    method public android.app.PendingIntent getActionIntent();
+    method public boolean getAllowGeneratedReplies();
+    method public android.os.Bundle getExtras();
+    method public int getIcon();
+    method public android.support.v4.app.RemoteInput[] getRemoteInputs();
+    method public java.lang.CharSequence getTitle();
+    field public android.app.PendingIntent actionIntent;
+    field public int icon;
+    field public java.lang.CharSequence title;
+  }
+
+  public static final class NotificationCompat.Action.Builder {
+    ctor public NotificationCompat.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent);
+    ctor public NotificationCompat.Action.Builder(android.support.v4.app.NotificationCompat.Action);
+    method public android.support.v4.app.NotificationCompat.Action.Builder addExtras(android.os.Bundle);
+    method public android.support.v4.app.NotificationCompat.Action.Builder addRemoteInput(android.support.v4.app.RemoteInput);
+    method public android.support.v4.app.NotificationCompat.Action build();
+    method public android.support.v4.app.NotificationCompat.Action.Builder extend(android.support.v4.app.NotificationCompat.Action.Extender);
+    method public android.os.Bundle getExtras();
+    method public android.support.v4.app.NotificationCompat.Action.Builder setAllowGeneratedReplies(boolean);
+  }
+
+  public static abstract interface NotificationCompat.Action.Extender {
+    method public abstract android.support.v4.app.NotificationCompat.Action.Builder extend(android.support.v4.app.NotificationCompat.Action.Builder);
+  }
+
+  public static final class NotificationCompat.Action.WearableExtender implements android.support.v4.app.NotificationCompat.Action.Extender {
+    ctor public NotificationCompat.Action.WearableExtender();
+    ctor public NotificationCompat.Action.WearableExtender(android.support.v4.app.NotificationCompat.Action);
+    method public android.support.v4.app.NotificationCompat.Action.WearableExtender clone();
+    method public android.support.v4.app.NotificationCompat.Action.Builder extend(android.support.v4.app.NotificationCompat.Action.Builder);
+    method public java.lang.CharSequence getCancelLabel();
+    method public java.lang.CharSequence getConfirmLabel();
+    method public boolean getHintDisplayActionInline();
+    method public boolean getHintLaunchesActivity();
+    method public java.lang.CharSequence getInProgressLabel();
+    method public boolean isAvailableOffline();
+    method public android.support.v4.app.NotificationCompat.Action.WearableExtender setAvailableOffline(boolean);
+    method public android.support.v4.app.NotificationCompat.Action.WearableExtender setCancelLabel(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.Action.WearableExtender setConfirmLabel(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.Action.WearableExtender setHintDisplayActionInline(boolean);
+    method public android.support.v4.app.NotificationCompat.Action.WearableExtender setHintLaunchesActivity(boolean);
+    method public android.support.v4.app.NotificationCompat.Action.WearableExtender setInProgressLabel(java.lang.CharSequence);
+  }
+
+  public static class NotificationCompat.BigPictureStyle extends android.support.v4.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigPictureStyle();
+    ctor public NotificationCompat.BigPictureStyle(android.support.v4.app.NotificationCompat.Builder);
+    method public android.support.v4.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
+    method public android.support.v4.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.Bitmap);
+    method public android.support.v4.app.NotificationCompat.BigPictureStyle setBigContentTitle(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.BigPictureStyle setSummaryText(java.lang.CharSequence);
+  }
+
+  public static class NotificationCompat.BigTextStyle extends android.support.v4.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigTextStyle();
+    ctor public NotificationCompat.BigTextStyle(android.support.v4.app.NotificationCompat.Builder);
+    method public android.support.v4.app.NotificationCompat.BigTextStyle bigText(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.BigTextStyle setBigContentTitle(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.BigTextStyle setSummaryText(java.lang.CharSequence);
+  }
+
+  public static class NotificationCompat.Builder {
+    ctor public NotificationCompat.Builder(android.content.Context);
+    method public android.support.v4.app.NotificationCompat.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent);
+    method public android.support.v4.app.NotificationCompat.Builder addAction(android.support.v4.app.NotificationCompat.Action);
+    method public android.support.v4.app.NotificationCompat.Builder addExtras(android.os.Bundle);
+    method public android.support.v4.app.NotificationCompat.Builder addPerson(java.lang.String);
+    method public android.app.Notification build();
+    method public android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Extender);
+    method public android.os.Bundle getExtras();
+    method public deprecated android.app.Notification getNotification();
+    method protected static java.lang.CharSequence limitCharSequenceLength(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.Builder setAutoCancel(boolean);
+    method public android.support.v4.app.NotificationCompat.Builder setCategory(java.lang.String);
+    method public android.support.v4.app.NotificationCompat.Builder setColor(int);
+    method public android.support.v4.app.NotificationCompat.Builder setContent(android.widget.RemoteViews);
+    method public android.support.v4.app.NotificationCompat.Builder setContentInfo(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.Builder setContentIntent(android.app.PendingIntent);
+    method public android.support.v4.app.NotificationCompat.Builder setContentText(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.Builder setContentTitle(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.Builder setCustomBigContentView(android.widget.RemoteViews);
+    method public android.support.v4.app.NotificationCompat.Builder setCustomContentView(android.widget.RemoteViews);
+    method public android.support.v4.app.NotificationCompat.Builder setCustomHeadsUpContentView(android.widget.RemoteViews);
+    method public android.support.v4.app.NotificationCompat.Builder setDefaults(int);
+    method public android.support.v4.app.NotificationCompat.Builder setDeleteIntent(android.app.PendingIntent);
+    method public android.support.v4.app.NotificationCompat.Builder setExtras(android.os.Bundle);
+    method public android.support.v4.app.NotificationCompat.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
+    method public android.support.v4.app.NotificationCompat.Builder setGroup(java.lang.String);
+    method public android.support.v4.app.NotificationCompat.Builder setGroupSummary(boolean);
+    method public android.support.v4.app.NotificationCompat.Builder setLargeIcon(android.graphics.Bitmap);
+    method public android.support.v4.app.NotificationCompat.Builder setLights(int, int, int);
+    method public android.support.v4.app.NotificationCompat.Builder setLocalOnly(boolean);
+    method public android.support.v4.app.NotificationCompat.Builder setNumber(int);
+    method public android.support.v4.app.NotificationCompat.Builder setOngoing(boolean);
+    method public android.support.v4.app.NotificationCompat.Builder setOnlyAlertOnce(boolean);
+    method public android.support.v4.app.NotificationCompat.Builder setPriority(int);
+    method public android.support.v4.app.NotificationCompat.Builder setProgress(int, int, boolean);
+    method public android.support.v4.app.NotificationCompat.Builder setPublicVersion(android.app.Notification);
+    method public android.support.v4.app.NotificationCompat.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+    method public android.support.v4.app.NotificationCompat.Builder setShowWhen(boolean);
+    method public android.support.v4.app.NotificationCompat.Builder setSmallIcon(int);
+    method public android.support.v4.app.NotificationCompat.Builder setSmallIcon(int, int);
+    method public android.support.v4.app.NotificationCompat.Builder setSortKey(java.lang.String);
+    method public android.support.v4.app.NotificationCompat.Builder setSound(android.net.Uri);
+    method public android.support.v4.app.NotificationCompat.Builder setSound(android.net.Uri, int);
+    method public android.support.v4.app.NotificationCompat.Builder setStyle(android.support.v4.app.NotificationCompat.Style);
+    method public android.support.v4.app.NotificationCompat.Builder setSubText(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.Builder setTicker(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
+    method public android.support.v4.app.NotificationCompat.Builder setUsesChronometer(boolean);
+    method public android.support.v4.app.NotificationCompat.Builder setVibrate(long[]);
+    method public android.support.v4.app.NotificationCompat.Builder setVisibility(int);
+    method public android.support.v4.app.NotificationCompat.Builder setWhen(long);
+    field public java.util.ArrayList<java.lang.String> mPeople;
+  }
+
+  public static final class NotificationCompat.CarExtender implements android.support.v4.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.CarExtender();
+    ctor public NotificationCompat.CarExtender(android.app.Notification);
+    method public android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Builder);
+    method public int getColor();
+    method public android.graphics.Bitmap getLargeIcon();
+    method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation getUnreadConversation();
+    method public android.support.v4.app.NotificationCompat.CarExtender setColor(int);
+    method public android.support.v4.app.NotificationCompat.CarExtender setLargeIcon(android.graphics.Bitmap);
+    method public android.support.v4.app.NotificationCompat.CarExtender setUnreadConversation(android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation);
+  }
+
+  public static class NotificationCompat.CarExtender.UnreadConversation {
+    method public long getLatestTimestamp();
+    method public java.lang.String[] getMessages();
+    method public java.lang.String getParticipant();
+    method public java.lang.String[] getParticipants();
+    method public android.app.PendingIntent getReadPendingIntent();
+    method public android.support.v4.app.RemoteInput getRemoteInput();
+    method public android.app.PendingIntent getReplyPendingIntent();
+  }
+
+  public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
+    ctor public NotificationCompat.CarExtender.UnreadConversation.Builder(java.lang.String);
+    method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder addMessage(java.lang.String);
+    method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation build();
+    method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder setLatestTimestamp(long);
+    method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReadPendingIntent(android.app.PendingIntent);
+    method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReplyAction(android.app.PendingIntent, android.support.v4.app.RemoteInput);
+  }
+
+  public static abstract interface NotificationCompat.Extender {
+    method public abstract android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Builder);
+  }
+
+  public static class NotificationCompat.InboxStyle extends android.support.v4.app.NotificationCompat.Style {
+    ctor public NotificationCompat.InboxStyle();
+    ctor public NotificationCompat.InboxStyle(android.support.v4.app.NotificationCompat.Builder);
+    method public android.support.v4.app.NotificationCompat.InboxStyle addLine(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.InboxStyle setBigContentTitle(java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.InboxStyle setSummaryText(java.lang.CharSequence);
+  }
+
+  public static class NotificationCompat.MessagingStyle extends android.support.v4.app.NotificationCompat.Style {
+    ctor public NotificationCompat.MessagingStyle(java.lang.CharSequence);
+    method public void addCompatExtras(android.os.Bundle);
+    method public android.support.v4.app.NotificationCompat.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
+    method public android.support.v4.app.NotificationCompat.MessagingStyle addMessage(android.support.v4.app.NotificationCompat.MessagingStyle.Message);
+    method public static android.support.v4.app.NotificationCompat.MessagingStyle extractMessagingStyleFromNotification(android.app.Notification);
+    method public java.lang.CharSequence getConversationTitle();
+    method public java.util.List<android.support.v4.app.NotificationCompat.MessagingStyle.Message> getMessages();
+    method public java.lang.CharSequence getUserDisplayName();
+    method public android.support.v4.app.NotificationCompat.MessagingStyle setConversationTitle(java.lang.CharSequence);
+    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+  }
+
+  public static final class NotificationCompat.MessagingStyle.Message {
+    ctor public NotificationCompat.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
+    method public java.lang.String getDataMimeType();
+    method public android.net.Uri getDataUri();
+    method public java.lang.CharSequence getSender();
+    method public java.lang.CharSequence getText();
+    method public long getTimestamp();
+    method public android.support.v4.app.NotificationCompat.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
+  }
+
+  public static abstract class NotificationCompat.Style {
+    ctor public NotificationCompat.Style();
+    method public android.app.Notification build();
+    method public void setBuilder(android.support.v4.app.NotificationCompat.Builder);
+  }
+
+  public static final class NotificationCompat.WearableExtender implements android.support.v4.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.WearableExtender();
+    ctor public NotificationCompat.WearableExtender(android.app.Notification);
+    method public android.support.v4.app.NotificationCompat.WearableExtender addAction(android.support.v4.app.NotificationCompat.Action);
+    method public android.support.v4.app.NotificationCompat.WearableExtender addActions(java.util.List<android.support.v4.app.NotificationCompat.Action>);
+    method public android.support.v4.app.NotificationCompat.WearableExtender addPage(android.app.Notification);
+    method public android.support.v4.app.NotificationCompat.WearableExtender addPages(java.util.List<android.app.Notification>);
+    method public android.support.v4.app.NotificationCompat.WearableExtender clearActions();
+    method public android.support.v4.app.NotificationCompat.WearableExtender clearPages();
+    method public android.support.v4.app.NotificationCompat.WearableExtender clone();
+    method public android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Builder);
+    method public java.util.List<android.support.v4.app.NotificationCompat.Action> getActions();
+    method public android.graphics.Bitmap getBackground();
+    method public java.lang.String getBridgeTag();
+    method public int getContentAction();
+    method public int getContentIcon();
+    method public int getContentIconGravity();
+    method public boolean getContentIntentAvailableOffline();
+    method public int getCustomContentHeight();
+    method public int getCustomSizePreset();
+    method public java.lang.String getDismissalId();
+    method public android.app.PendingIntent getDisplayIntent();
+    method public int getGravity();
+    method public boolean getHintAmbientBigPicture();
+    method public boolean getHintAvoidBackgroundClipping();
+    method public boolean getHintContentIntentLaunchesActivity();
+    method public boolean getHintHideIcon();
+    method public int getHintScreenTimeout();
+    method public boolean getHintShowBackgroundOnly();
+    method public java.util.List<android.app.Notification> getPages();
+    method public boolean getStartScrollBottom();
+    method public android.support.v4.app.NotificationCompat.WearableExtender setBackground(android.graphics.Bitmap);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setBridgeTag(java.lang.String);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setContentAction(int);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setContentIcon(int);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setContentIconGravity(int);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setContentIntentAvailableOffline(boolean);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setCustomContentHeight(int);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setCustomSizePreset(int);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setDismissalId(java.lang.String);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setDisplayIntent(android.app.PendingIntent);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setGravity(int);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setHintAmbientBigPicture(boolean);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setHintAvoidBackgroundClipping(boolean);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setHintContentIntentLaunchesActivity(boolean);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setHintHideIcon(boolean);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setHintScreenTimeout(int);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setHintShowBackgroundOnly(boolean);
+    method public android.support.v4.app.NotificationCompat.WearableExtender setStartScrollBottom(boolean);
+    field public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
+    field public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
+    field public static final int SIZE_DEFAULT = 0; // 0x0
+    field public static final int SIZE_FULL_SCREEN = 5; // 0x5
+    field public static final int SIZE_LARGE = 4; // 0x4
+    field public static final int SIZE_MEDIUM = 3; // 0x3
+    field public static final int SIZE_SMALL = 2; // 0x2
+    field public static final int SIZE_XSMALL = 1; // 0x1
+    field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
+  }
+
+  public final class NotificationCompatExtras {
+    field public static final java.lang.String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
+    field public static final java.lang.String EXTRA_GROUP_KEY = "android.support.groupKey";
+    field public static final java.lang.String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
+    field public static final java.lang.String EXTRA_LOCAL_ONLY = "android.support.localOnly";
+    field public static final java.lang.String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
+    field public static final java.lang.String EXTRA_SORT_KEY = "android.support.sortKey";
+  }
+
+  public abstract class NotificationCompatSideChannelService extends android.app.Service {
+    ctor public NotificationCompatSideChannelService();
+    method public abstract void cancel(java.lang.String, int, java.lang.String);
+    method public abstract void cancelAll(java.lang.String);
+    method public abstract void notify(java.lang.String, int, java.lang.String, android.app.Notification);
+    method public android.os.IBinder onBind(android.content.Intent);
+  }
+
+  public final class NotificationManagerCompat {
+    method public boolean areNotificationsEnabled();
+    method public void cancel(int);
+    method public void cancel(java.lang.String, int);
+    method public void cancelAll();
+    method public static android.support.v4.app.NotificationManagerCompat from(android.content.Context);
+    method public static java.util.Set<java.lang.String> getEnabledListenerPackages(android.content.Context);
+    method public int getImportance();
+    method public void notify(int, android.app.Notification);
+    method public void notify(java.lang.String, int, android.app.Notification);
+    field public static final java.lang.String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
+    field public static final java.lang.String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
+    field public static final int IMPORTANCE_DEFAULT = 3; // 0x3
+    field public static final int IMPORTANCE_HIGH = 4; // 0x4
+    field public static final int IMPORTANCE_LOW = 2; // 0x2
+    field public static final int IMPORTANCE_MAX = 5; // 0x5
+    field public static final int IMPORTANCE_MIN = 1; // 0x1
+    field public static final int IMPORTANCE_NONE = 0; // 0x0
+    field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
+  }
+
+  public final class RemoteInput extends android.support.v4.app.RemoteInputCompatBase.RemoteInput {
+    method public static void addResultsToIntent(android.support.v4.app.RemoteInput[], android.content.Intent, android.os.Bundle);
+    method public boolean getAllowFreeFormInput();
+    method public java.lang.CharSequence[] getChoices();
+    method public android.os.Bundle getExtras();
+    method public java.lang.CharSequence getLabel();
+    method public java.lang.String getResultKey();
+    method public static android.os.Bundle getResultsFromIntent(android.content.Intent);
+    field public static final java.lang.String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+    field public static final java.lang.String RESULTS_CLIP_LABEL = "android.remoteinput.results";
+  }
+
+  public static final class RemoteInput.Builder {
+    ctor public RemoteInput.Builder(java.lang.String);
+    method public android.support.v4.app.RemoteInput.Builder addExtras(android.os.Bundle);
+    method public android.support.v4.app.RemoteInput build();
+    method public android.os.Bundle getExtras();
+    method public android.support.v4.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
+    method public android.support.v4.app.RemoteInput.Builder setChoices(java.lang.CharSequence[]);
+    method public android.support.v4.app.RemoteInput.Builder setLabel(java.lang.CharSequence);
+  }
+
+   class RemoteInputCompatBase {
+  }
+
+  public static abstract class RemoteInputCompatBase.RemoteInput {
+    ctor public RemoteInputCompatBase.RemoteInput();
+    method protected abstract boolean getAllowFreeFormInput();
+    method protected abstract java.lang.CharSequence[] getChoices();
+    method protected abstract android.os.Bundle getExtras();
+    method protected abstract java.lang.CharSequence getLabel();
+    method protected abstract java.lang.String getResultKey();
+  }
+
+  public final class ServiceCompat {
+    method public static void stopForeground(android.app.Service, int);
+    field public static final int START_STICKY = 1; // 0x1
+    field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
+    field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
+  }
+
+  public final class ShareCompat {
+    method public static void configureMenuItem(android.view.MenuItem, android.support.v4.app.ShareCompat.IntentBuilder);
+    method public static void configureMenuItem(android.view.Menu, int, android.support.v4.app.ShareCompat.IntentBuilder);
+    method public static android.content.ComponentName getCallingActivity(android.app.Activity);
+    method public static java.lang.String getCallingPackage(android.app.Activity);
+    field public static final java.lang.String EXTRA_CALLING_ACTIVITY = "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
+    field public static final java.lang.String EXTRA_CALLING_PACKAGE = "android.support.v4.app.EXTRA_CALLING_PACKAGE";
+  }
+
+  public static class ShareCompat.IntentBuilder {
+    method public android.support.v4.app.ShareCompat.IntentBuilder addEmailBcc(java.lang.String);
+    method public android.support.v4.app.ShareCompat.IntentBuilder addEmailBcc(java.lang.String[]);
+    method public android.support.v4.app.ShareCompat.IntentBuilder addEmailCc(java.lang.String);
+    method public android.support.v4.app.ShareCompat.IntentBuilder addEmailCc(java.lang.String[]);
+    method public android.support.v4.app.ShareCompat.IntentBuilder addEmailTo(java.lang.String);
+    method public android.support.v4.app.ShareCompat.IntentBuilder addEmailTo(java.lang.String[]);
+    method public android.support.v4.app.ShareCompat.IntentBuilder addStream(android.net.Uri);
+    method public android.content.Intent createChooserIntent();
+    method public static android.support.v4.app.ShareCompat.IntentBuilder from(android.app.Activity);
+    method public android.content.Intent getIntent();
+    method public android.support.v4.app.ShareCompat.IntentBuilder setChooserTitle(java.lang.CharSequence);
+    method public android.support.v4.app.ShareCompat.IntentBuilder setChooserTitle(int);
+    method public android.support.v4.app.ShareCompat.IntentBuilder setEmailBcc(java.lang.String[]);
+    method public android.support.v4.app.ShareCompat.IntentBuilder setEmailCc(java.lang.String[]);
+    method public android.support.v4.app.ShareCompat.IntentBuilder setEmailTo(java.lang.String[]);
+    method public android.support.v4.app.ShareCompat.IntentBuilder setHtmlText(java.lang.String);
+    method public android.support.v4.app.ShareCompat.IntentBuilder setStream(android.net.Uri);
+    method public android.support.v4.app.ShareCompat.IntentBuilder setSubject(java.lang.String);
+    method public android.support.v4.app.ShareCompat.IntentBuilder setText(java.lang.CharSequence);
+    method public android.support.v4.app.ShareCompat.IntentBuilder setType(java.lang.String);
+    method public void startChooser();
+  }
+
+  public static class ShareCompat.IntentReader {
+    method public static android.support.v4.app.ShareCompat.IntentReader from(android.app.Activity);
+    method public android.content.ComponentName getCallingActivity();
+    method public android.graphics.drawable.Drawable getCallingActivityIcon();
+    method public android.graphics.drawable.Drawable getCallingApplicationIcon();
+    method public java.lang.CharSequence getCallingApplicationLabel();
+    method public java.lang.String getCallingPackage();
+    method public java.lang.String[] getEmailBcc();
+    method public java.lang.String[] getEmailCc();
+    method public java.lang.String[] getEmailTo();
+    method public java.lang.String getHtmlText();
+    method public android.net.Uri getStream();
+    method public android.net.Uri getStream(int);
+    method public int getStreamCount();
+    method public java.lang.String getSubject();
+    method public java.lang.CharSequence getText();
+    method public java.lang.String getType();
+    method public boolean isMultipleShare();
+    method public boolean isShareIntent();
+    method public boolean isSingleShare();
+  }
+
+  public abstract class SharedElementCallback {
+    ctor public SharedElementCallback();
+    method public android.os.Parcelable onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF);
+    method public android.view.View onCreateSnapshotView(android.content.Context, android.os.Parcelable);
+    method public void onMapSharedElements(java.util.List<java.lang.String>, java.util.Map<java.lang.String, android.view.View>);
+    method public void onRejectSharedElements(java.util.List<android.view.View>);
+    method public void onSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
+    method public void onSharedElementStart(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
+    method public void onSharedElementsArrived(java.util.List<java.lang.String>, java.util.List<android.view.View>, android.support.v4.app.SharedElementCallback.OnSharedElementsReadyListener);
+  }
+
+  public static abstract interface SharedElementCallback.OnSharedElementsReadyListener {
+    method public abstract void onSharedElementsReady();
+  }
+
+  public final class TaskStackBuilder implements java.lang.Iterable {
+    method public android.support.v4.app.TaskStackBuilder addNextIntent(android.content.Intent);
+    method public android.support.v4.app.TaskStackBuilder addNextIntentWithParentStack(android.content.Intent);
+    method public android.support.v4.app.TaskStackBuilder addParentStack(android.app.Activity);
+    method public android.support.v4.app.TaskStackBuilder addParentStack(java.lang.Class<?>);
+    method public android.support.v4.app.TaskStackBuilder addParentStack(android.content.ComponentName);
+    method public static android.support.v4.app.TaskStackBuilder create(android.content.Context);
+    method public android.content.Intent editIntentAt(int);
+    method public static deprecated android.support.v4.app.TaskStackBuilder from(android.content.Context);
+    method public deprecated android.content.Intent getIntent(int);
+    method public int getIntentCount();
+    method public android.content.Intent[] getIntents();
+    method public android.app.PendingIntent getPendingIntent(int, int);
+    method public android.app.PendingIntent getPendingIntent(int, int, android.os.Bundle);
+    method public deprecated java.util.Iterator<android.content.Intent> iterator();
+    method public void startActivities();
+    method public void startActivities(android.os.Bundle);
+  }
+
+  public static abstract interface TaskStackBuilder.SupportParentable {
+    method public abstract android.content.Intent getSupportParentActivityIntent();
+  }
+
+}
+
+package android.support.v4.content {
+
+  public abstract class AsyncTaskLoader<D> extends android.support.v4.content.Loader {
+    ctor public AsyncTaskLoader(android.content.Context);
+    method public void cancelLoadInBackground();
+    method public boolean isLoadInBackgroundCanceled();
+    method public abstract D loadInBackground();
+    method public void onCanceled(D);
+    method protected D onLoadInBackground();
+    method public void setUpdateThrottle(long);
+  }
+
+  public final class ContentResolverCompat {
+    method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.support.v4.os.CancellationSignal);
+  }
+
+  public class ContextCompat {
+    ctor protected ContextCompat();
+    method public static int checkSelfPermission(android.content.Context, java.lang.String);
+    method public static android.content.Context createDeviceProtectedStorageContext(android.content.Context);
+    method public static java.io.File getCodeCacheDir(android.content.Context);
+    method public static final int getColor(android.content.Context, int);
+    method public static final android.content.res.ColorStateList getColorStateList(android.content.Context, int);
+    method public static java.io.File getDataDir(android.content.Context);
+    method public static final android.graphics.drawable.Drawable getDrawable(android.content.Context, int);
+    method public static java.io.File[] getExternalCacheDirs(android.content.Context);
+    method public static java.io.File[] getExternalFilesDirs(android.content.Context, java.lang.String);
+    method public static final java.io.File getNoBackupFilesDir(android.content.Context);
+    method public static java.io.File[] getObbDirs(android.content.Context);
+    method public static boolean isDeviceProtectedStorage(android.content.Context);
+    method public static boolean startActivities(android.content.Context, android.content.Intent[]);
+    method public static boolean startActivities(android.content.Context, android.content.Intent[], android.os.Bundle);
+    method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle);
+  }
+
+  public class CursorLoader extends android.support.v4.content.AsyncTaskLoader {
+    ctor public CursorLoader(android.content.Context);
+    ctor public CursorLoader(android.content.Context, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+    method public void deliverResult(android.database.Cursor);
+    method public java.lang.String[] getProjection();
+    method public java.lang.String getSelection();
+    method public java.lang.String[] getSelectionArgs();
+    method public java.lang.String getSortOrder();
+    method public android.net.Uri getUri();
+    method public android.database.Cursor loadInBackground();
+    method public void onCanceled(android.database.Cursor);
+    method public void setProjection(java.lang.String[]);
+    method public void setSelection(java.lang.String);
+    method public void setSelectionArgs(java.lang.String[]);
+    method public void setSortOrder(java.lang.String);
+    method public void setUri(android.net.Uri);
+  }
+
+  public class FileProvider extends android.content.ContentProvider {
+    ctor public FileProvider();
+    method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
+    method public java.lang.String getType(android.net.Uri);
+    method public static android.net.Uri getUriForFile(android.content.Context, java.lang.String, java.io.File);
+    method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
+    method public boolean onCreate();
+    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+    method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
+  }
+
+  public final class IntentCompat {
+    method public static android.content.Intent makeMainActivity(android.content.ComponentName);
+    method public static android.content.Intent makeMainSelectorActivity(java.lang.String, java.lang.String);
+    method public static android.content.Intent makeRestartActivityTask(android.content.ComponentName);
+    field public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE";
+    field public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE";
+    field public static final java.lang.String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
+    field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
+    field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
+    field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+    field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
+    field public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; // 0x4000
+  }
+
+  public class Loader<D> {
+    ctor public Loader(android.content.Context);
+    method public void abandon();
+    method public boolean cancelLoad();
+    method public void commitContentChanged();
+    method public java.lang.String dataToString(D);
+    method public void deliverCancellation();
+    method public void deliverResult(D);
+    method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public void forceLoad();
+    method public android.content.Context getContext();
+    method public int getId();
+    method public boolean isAbandoned();
+    method public boolean isReset();
+    method public boolean isStarted();
+    method protected void onAbandon();
+    method protected boolean onCancelLoad();
+    method public void onContentChanged();
+    method protected void onForceLoad();
+    method protected void onReset();
+    method protected void onStartLoading();
+    method protected void onStopLoading();
+    method public void registerListener(int, android.support.v4.content.Loader.OnLoadCompleteListener<D>);
+    method public void registerOnLoadCanceledListener(android.support.v4.content.Loader.OnLoadCanceledListener<D>);
+    method public void reset();
+    method public void rollbackContentChanged();
+    method public final void startLoading();
+    method public void stopLoading();
+    method public boolean takeContentChanged();
+    method public void unregisterListener(android.support.v4.content.Loader.OnLoadCompleteListener<D>);
+    method public void unregisterOnLoadCanceledListener(android.support.v4.content.Loader.OnLoadCanceledListener<D>);
+  }
+
+  public final class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
+    ctor public Loader.ForceLoadContentObserver();
+  }
+
+  public static abstract interface Loader.OnLoadCanceledListener<D> {
+    method public abstract void onLoadCanceled(android.support.v4.content.Loader<D>);
+  }
+
+  public static abstract interface Loader.OnLoadCompleteListener<D> {
+    method public abstract void onLoadComplete(android.support.v4.content.Loader<D>, D);
+  }
+
+  public final class LocalBroadcastManager {
+    method public static android.support.v4.content.LocalBroadcastManager getInstance(android.content.Context);
+    method public void registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter);
+    method public boolean sendBroadcast(android.content.Intent);
+    method public void sendBroadcastSync(android.content.Intent);
+    method public void unregisterReceiver(android.content.BroadcastReceiver);
+  }
+
+  public final class ParallelExecutorCompat {
+    method public static java.util.concurrent.Executor getParallelExecutor();
+  }
+
+  public final class PermissionChecker {
+    method public static int checkCallingOrSelfPermission(android.content.Context, java.lang.String);
+    method public static int checkCallingPermission(android.content.Context, java.lang.String, java.lang.String);
+    method public static int checkPermission(android.content.Context, java.lang.String, int, int, java.lang.String);
+    method public static int checkSelfPermission(android.content.Context, java.lang.String);
+    field public static final int PERMISSION_DENIED = -1; // 0xffffffff
+    field public static final int PERMISSION_DENIED_APP_OP = -2; // 0xfffffffe
+    field public static final int PERMISSION_GRANTED = 0; // 0x0
+  }
+
+  public static abstract class PermissionChecker.PermissionResult implements java.lang.annotation.Annotation {
+  }
+
+  public final class SharedPreferencesCompat {
+  }
+
+  public static final class SharedPreferencesCompat.EditorCompat {
+    method public void apply(android.content.SharedPreferences.Editor);
+    method public static android.support.v4.content.SharedPreferencesCompat.EditorCompat getInstance();
+  }
+
+  public abstract class WakefulBroadcastReceiver extends android.content.BroadcastReceiver {
+    ctor public WakefulBroadcastReceiver();
+    method public static boolean completeWakefulIntent(android.content.Intent);
+    method public static android.content.ComponentName startWakefulService(android.content.Context, android.content.Intent);
+  }
+
+}
+
+package android.support.v4.content.pm {
+
+  public final class ActivityInfoCompat {
+    field public static final int CONFIG_UI_MODE = 512; // 0x200
+  }
+
+}
+
+package android.support.v4.content.res {
+
+  public final class ConfigurationHelper {
+    method public static int getDensityDpi(android.content.res.Resources);
+    method public static int getScreenHeightDp(android.content.res.Resources);
+    method public static int getScreenWidthDp(android.content.res.Resources);
+    method public static int getSmallestScreenWidthDp(android.content.res.Resources);
+  }
+
+  public final class ResourcesCompat {
+    method public static int getColor(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+    method public static android.content.res.ColorStateList getColorStateList(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable getDrawable(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable getDrawableForDensity(android.content.res.Resources, int, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+  }
+
+}
+
+package android.support.v4.database {
+
+  public final class DatabaseUtilsCompat {
+    method public static java.lang.String[] appendSelectionArgs(java.lang.String[], java.lang.String[]);
+    method public static java.lang.String concatenateWhere(java.lang.String, java.lang.String);
+  }
+
+}
+
+package android.support.v4.graphics {
+
+  public final class BitmapCompat {
+    method public static int getAllocationByteCount(android.graphics.Bitmap);
+    method public static boolean hasMipMap(android.graphics.Bitmap);
+    method public static void setHasMipMap(android.graphics.Bitmap, boolean);
+  }
+
+  public final class ColorUtils {
+    method public static int HSLToColor(float[]);
+    method public static int LABToColor(double, double, double);
+    method public static void LABToXYZ(double, double, double, double[]);
+    method public static void RGBToHSL(int, int, int, float[]);
+    method public static void RGBToLAB(int, int, int, double[]);
+    method public static void RGBToXYZ(int, int, int, double[]);
+    method public static int XYZToColor(double, double, double);
+    method public static void XYZToLAB(double, double, double, double[]);
+    method public static int blendARGB(int, int, float);
+    method public static void blendHSL(float[], float[], float, float[]);
+    method public static void blendLAB(double[], double[], double, double[]);
+    method public static double calculateContrast(int, int);
+    method public static double calculateLuminance(int);
+    method public static int calculateMinimumAlpha(int, int, float);
+    method public static void colorToHSL(int, float[]);
+    method public static void colorToLAB(int, double[]);
+    method public static void colorToXYZ(int, double[]);
+    method public static int compositeColors(int, int);
+    method public static double distanceEuclidean(double[], double[]);
+    method public static int setAlphaComponent(int, int);
+  }
+
+}
+
+package android.support.v4.graphics.drawable {
+
+  public final class DrawableCompat {
+    method public static void applyTheme(android.graphics.drawable.Drawable, android.content.res.Resources.Theme);
+    method public static boolean canApplyTheme(android.graphics.drawable.Drawable);
+    method public static void clearColorFilter(android.graphics.drawable.Drawable);
+    method public static int getAlpha(android.graphics.drawable.Drawable);
+    method public static android.graphics.ColorFilter getColorFilter(android.graphics.drawable.Drawable);
+    method public static int getLayoutDirection(android.graphics.drawable.Drawable);
+    method public static void inflate(android.graphics.drawable.Drawable, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static boolean isAutoMirrored(android.graphics.drawable.Drawable);
+    method public static void jumpToCurrentState(android.graphics.drawable.Drawable);
+    method public static void setAutoMirrored(android.graphics.drawable.Drawable, boolean);
+    method public static void setHotspot(android.graphics.drawable.Drawable, float, float);
+    method public static void setHotspotBounds(android.graphics.drawable.Drawable, int, int, int, int);
+    method public static boolean setLayoutDirection(android.graphics.drawable.Drawable, int);
+    method public static void setTint(android.graphics.drawable.Drawable, int);
+    method public static void setTintList(android.graphics.drawable.Drawable, android.content.res.ColorStateList);
+    method public static void setTintMode(android.graphics.drawable.Drawable, android.graphics.PorterDuff.Mode);
+    method public static <T extends android.graphics.drawable.Drawable> T unwrap(android.graphics.drawable.Drawable);
+    method public static android.graphics.drawable.Drawable wrap(android.graphics.drawable.Drawable);
+  }
+
+  public abstract class RoundedBitmapDrawable extends android.graphics.drawable.Drawable {
+    method public void draw(android.graphics.Canvas);
+    method public final android.graphics.Bitmap getBitmap();
+    method public float getCornerRadius();
+    method public int getGravity();
+    method public int getOpacity();
+    method public final android.graphics.Paint getPaint();
+    method public boolean hasAntiAlias();
+    method public boolean hasMipMap();
+    method public boolean isCircular();
+    method public void setAlpha(int);
+    method public void setAntiAlias(boolean);
+    method public void setCircular(boolean);
+    method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setCornerRadius(float);
+    method public void setGravity(int);
+    method public void setMipMap(boolean);
+    method public void setTargetDensity(android.graphics.Canvas);
+    method public void setTargetDensity(android.util.DisplayMetrics);
+    method public void setTargetDensity(int);
+  }
+
+  public final class RoundedBitmapDrawableFactory {
+    method public static android.support.v4.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, android.graphics.Bitmap);
+    method public static android.support.v4.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.lang.String);
+    method public static android.support.v4.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.io.InputStream);
+  }
+
+}
+
+package android.support.v4.hardware.display {
+
+  public abstract class DisplayManagerCompat {
+    method public abstract android.view.Display getDisplay(int);
+    method public abstract android.view.Display[] getDisplays();
+    method public abstract android.view.Display[] getDisplays(java.lang.String);
+    method public static android.support.v4.hardware.display.DisplayManagerCompat getInstance(android.content.Context);
+    field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+  }
+
+}
+
+package android.support.v4.hardware.fingerprint {
+
+  public final class FingerprintManagerCompat {
+    method public void authenticate(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject, int, android.support.v4.os.CancellationSignal, android.support.v4.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, android.os.Handler);
+    method public static android.support.v4.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
+    method public boolean hasEnrolledFingerprints();
+    method public boolean isHardwareDetected();
+  }
+
+  public static abstract class FingerprintManagerCompat.AuthenticationCallback {
+    ctor public FingerprintManagerCompat.AuthenticationCallback();
+    method public void onAuthenticationError(int, java.lang.CharSequence);
+    method public void onAuthenticationFailed();
+    method public void onAuthenticationHelp(int, java.lang.CharSequence);
+    method public void onAuthenticationSucceeded(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult);
+  }
+
+  public static final class FingerprintManagerCompat.AuthenticationResult {
+    ctor public FingerprintManagerCompat.AuthenticationResult(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject);
+    method public android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject getCryptoObject();
+  }
+
+  public static class FingerprintManagerCompat.CryptoObject {
+    ctor public FingerprintManagerCompat.CryptoObject(java.security.Signature);
+    ctor public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
+    ctor public FingerprintManagerCompat.CryptoObject(javax.crypto.Mac);
+    method public javax.crypto.Cipher getCipher();
+    method public javax.crypto.Mac getMac();
+    method public java.security.Signature getSignature();
+  }
+
+}
+
+package android.support.v4.math {
+
+  public class MathUtils {
+    ctor public MathUtils();
+    method public static float clamp(float, int, int);
+    method public static double clamp(double, double, double);
+    method public static int clamp(int, int, int);
+  }
+
+}
+
+package android.support.v4.media {
+
+  public final class MediaBrowserCompat {
+    ctor public MediaBrowserCompat(android.content.Context, android.content.ComponentName, android.support.v4.media.MediaBrowserCompat.ConnectionCallback, android.os.Bundle);
+    method public void connect();
+    method public void disconnect();
+    method public android.os.Bundle getExtras();
+    method public void getItem(java.lang.String, android.support.v4.media.MediaBrowserCompat.ItemCallback);
+    method public java.lang.String getRoot();
+    method public android.content.ComponentName getServiceComponent();
+    method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+    method public boolean isConnected();
+    method public void subscribe(java.lang.String, android.support.v4.media.MediaBrowserCompat.SubscriptionCallback);
+    method public void subscribe(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserCompat.SubscriptionCallback);
+    method public void unsubscribe(java.lang.String);
+    method public void unsubscribe(java.lang.String, android.support.v4.media.MediaBrowserCompat.SubscriptionCallback);
+    field public static final java.lang.String EXTRA_PAGE = "android.media.browse.extra.PAGE";
+    field public static final java.lang.String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
+  }
+
+  public static class MediaBrowserCompat.ConnectionCallback {
+    ctor public MediaBrowserCompat.ConnectionCallback();
+    method public void onConnected();
+    method public void onConnectionFailed();
+    method public void onConnectionSuspended();
+  }
+
+  public static abstract class MediaBrowserCompat.ItemCallback {
+    ctor public MediaBrowserCompat.ItemCallback();
+    method public void onError(java.lang.String);
+    method public void onItemLoaded(android.support.v4.media.MediaBrowserCompat.MediaItem);
+  }
+
+  public static class MediaBrowserCompat.MediaItem implements android.os.Parcelable {
+    ctor public MediaBrowserCompat.MediaItem(android.support.v4.media.MediaDescriptionCompat, int);
+    method public int describeContents();
+    method public static android.support.v4.media.MediaBrowserCompat.MediaItem fromMediaItem(java.lang.Object);
+    method public static java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem> fromMediaItemList(java.util.List<?>);
+    method public android.support.v4.media.MediaDescriptionCompat getDescription();
+    method public int getFlags();
+    method public java.lang.String getMediaId();
+    method public boolean isBrowsable();
+    method public boolean isPlayable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.media.MediaBrowserCompat.MediaItem> CREATOR;
+    field public static final int FLAG_BROWSABLE = 1; // 0x1
+    field public static final int FLAG_PLAYABLE = 2; // 0x2
+  }
+
+  public static abstract class MediaBrowserCompat.SubscriptionCallback {
+    ctor public MediaBrowserCompat.SubscriptionCallback();
+    method public void onChildrenLoaded(java.lang.String, java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>);
+    method public void onChildrenLoaded(java.lang.String, java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>, android.os.Bundle);
+    method public void onError(java.lang.String);
+    method public void onError(java.lang.String, android.os.Bundle);
+  }
+
+  public abstract class MediaBrowserServiceCompat extends android.app.Service {
+    ctor public MediaBrowserServiceCompat();
+    method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public final android.os.Bundle getBrowserRootHints();
+    method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+    method public void notifyChildrenChanged(java.lang.String);
+    method public void notifyChildrenChanged(java.lang.String, android.os.Bundle);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract android.support.v4.media.MediaBrowserServiceCompat.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
+    method public abstract void onLoadChildren(java.lang.String, android.support.v4.media.MediaBrowserServiceCompat.Result<java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>>);
+    method public void onLoadChildren(java.lang.String, android.support.v4.media.MediaBrowserServiceCompat.Result<java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>>, android.os.Bundle);
+    method public void onLoadItem(java.lang.String, android.support.v4.media.MediaBrowserServiceCompat.Result<android.support.v4.media.MediaBrowserCompat.MediaItem>);
+    method public void setSessionToken(android.support.v4.media.session.MediaSessionCompat.Token);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
+  }
+
+  public static final class MediaBrowserServiceCompat.BrowserRoot {
+    ctor public MediaBrowserServiceCompat.BrowserRoot(java.lang.String, android.os.Bundle);
+    method public android.os.Bundle getExtras();
+    method public java.lang.String getRootId();
+    field public static final java.lang.String EXTRA_OFFLINE = "android.service.media.extra.OFFLINE";
+    field public static final java.lang.String EXTRA_RECENT = "android.service.media.extra.RECENT";
+    field public static final java.lang.String EXTRA_SUGGESTED = "android.service.media.extra.SUGGESTED";
+    field public static final java.lang.String EXTRA_SUGGESTION_KEYWORDS = "android.service.media.extra.SUGGESTION_KEYWORDS";
+  }
+
+  public static class MediaBrowserServiceCompat.Result<T> {
+    method public void detach();
+    method public void sendResult(T);
+  }
+
+  public final class MediaDescriptionCompat implements android.os.Parcelable {
+    method public int describeContents();
+    method public static android.support.v4.media.MediaDescriptionCompat fromMediaDescription(java.lang.Object);
+    method public java.lang.CharSequence getDescription();
+    method public android.os.Bundle getExtras();
+    method public android.graphics.Bitmap getIconBitmap();
+    method public android.net.Uri getIconUri();
+    method public java.lang.Object getMediaDescription();
+    method public java.lang.String getMediaId();
+    method public android.net.Uri getMediaUri();
+    method public java.lang.CharSequence getSubtitle();
+    method public java.lang.CharSequence getTitle();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final long BT_FOLDER_TYPE_ALBUMS = 2L; // 0x2L
+    field public static final long BT_FOLDER_TYPE_ARTISTS = 3L; // 0x3L
+    field public static final long BT_FOLDER_TYPE_GENRES = 4L; // 0x4L
+    field public static final long BT_FOLDER_TYPE_MIXED = 0L; // 0x0L
+    field public static final long BT_FOLDER_TYPE_PLAYLISTS = 5L; // 0x5L
+    field public static final long BT_FOLDER_TYPE_TITLES = 1L; // 0x1L
+    field public static final long BT_FOLDER_TYPE_YEARS = 6L; // 0x6L
+    field public static final android.os.Parcelable.Creator<android.support.v4.media.MediaDescriptionCompat> CREATOR;
+    field public static final java.lang.String EXTRA_BT_FOLDER_TYPE = "android.media.extra.BT_FOLDER_TYPE";
+  }
+
+  public static final class MediaDescriptionCompat.Builder {
+    ctor public MediaDescriptionCompat.Builder();
+    method public android.support.v4.media.MediaDescriptionCompat build();
+    method public android.support.v4.media.MediaDescriptionCompat.Builder setDescription(java.lang.CharSequence);
+    method public android.support.v4.media.MediaDescriptionCompat.Builder setExtras(android.os.Bundle);
+    method public android.support.v4.media.MediaDescriptionCompat.Builder setIconBitmap(android.graphics.Bitmap);
+    method public android.support.v4.media.MediaDescriptionCompat.Builder setIconUri(android.net.Uri);
+    method public android.support.v4.media.MediaDescriptionCompat.Builder setMediaId(java.lang.String);
+    method public android.support.v4.media.MediaDescriptionCompat.Builder setMediaUri(android.net.Uri);
+    method public android.support.v4.media.MediaDescriptionCompat.Builder setSubtitle(java.lang.CharSequence);
+    method public android.support.v4.media.MediaDescriptionCompat.Builder setTitle(java.lang.CharSequence);
+  }
+
+  public final class MediaMetadataCompat implements android.os.Parcelable {
+    method public boolean containsKey(java.lang.String);
+    method public int describeContents();
+    method public static android.support.v4.media.MediaMetadataCompat fromMediaMetadata(java.lang.Object);
+    method public android.graphics.Bitmap getBitmap(java.lang.String);
+    method public android.os.Bundle getBundle();
+    method public android.support.v4.media.MediaDescriptionCompat getDescription();
+    method public long getLong(java.lang.String);
+    method public java.lang.Object getMediaMetadata();
+    method public android.support.v4.media.RatingCompat getRating(java.lang.String);
+    method public java.lang.String getString(java.lang.String);
+    method public java.lang.CharSequence getText(java.lang.String);
+    method public java.util.Set<java.lang.String> keySet();
+    method public int size();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.media.MediaMetadataCompat> CREATOR;
+    field public static final java.lang.String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+    field public static final java.lang.String METADATA_KEY_ART = "android.media.metadata.ART";
+    field public static final java.lang.String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+    field public static final java.lang.String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+    field public static final java.lang.String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+    field public static final java.lang.String METADATA_KEY_BT_FOLDER_TYPE = "android.media.metadata.BT_FOLDER_TYPE";
+    field public static final java.lang.String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION";
+    field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+    field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE";
+    field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_DESCRIPTION = "android.media.metadata.DISPLAY_DESCRIPTION";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_ICON = "android.media.metadata.DISPLAY_ICON";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_ICON_URI = "android.media.metadata.DISPLAY_ICON_URI";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_SUBTITLE = "android.media.metadata.DISPLAY_SUBTITLE";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
+    field public static final java.lang.String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+    field public static final java.lang.String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+    field public static final java.lang.String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID";
+    field public static final java.lang.String METADATA_KEY_MEDIA_URI = "android.media.metadata.MEDIA_URI";
+    field public static final java.lang.String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+    field public static final java.lang.String METADATA_KEY_RATING = "android.media.metadata.RATING";
+    field public static final java.lang.String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+    field public static final java.lang.String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+    field public static final java.lang.String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+    field public static final java.lang.String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+    field public static final java.lang.String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+  }
+
+  public static final class MediaMetadataCompat.Builder {
+    ctor public MediaMetadataCompat.Builder();
+    ctor public MediaMetadataCompat.Builder(android.support.v4.media.MediaMetadataCompat);
+    method public android.support.v4.media.MediaMetadataCompat build();
+    method public android.support.v4.media.MediaMetadataCompat.Builder putBitmap(java.lang.String, android.graphics.Bitmap);
+    method public android.support.v4.media.MediaMetadataCompat.Builder putLong(java.lang.String, long);
+    method public android.support.v4.media.MediaMetadataCompat.Builder putRating(java.lang.String, android.support.v4.media.RatingCompat);
+    method public android.support.v4.media.MediaMetadataCompat.Builder putString(java.lang.String, java.lang.String);
+    method public android.support.v4.media.MediaMetadataCompat.Builder putText(java.lang.String, java.lang.CharSequence);
+  }
+
+  public final class RatingCompat implements android.os.Parcelable {
+    method public int describeContents();
+    method public static android.support.v4.media.RatingCompat fromRating(java.lang.Object);
+    method public float getPercentRating();
+    method public java.lang.Object getRating();
+    method public int getRatingStyle();
+    method public float getStarRating();
+    method public boolean hasHeart();
+    method public boolean isRated();
+    method public boolean isThumbUp();
+    method public static android.support.v4.media.RatingCompat newHeartRating(boolean);
+    method public static android.support.v4.media.RatingCompat newPercentageRating(float);
+    method public static android.support.v4.media.RatingCompat newStarRating(int, float);
+    method public static android.support.v4.media.RatingCompat newThumbRating(boolean);
+    method public static android.support.v4.media.RatingCompat newUnratedRating(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.media.RatingCompat> CREATOR;
+    field public static final int RATING_3_STARS = 3; // 0x3
+    field public static final int RATING_4_STARS = 4; // 0x4
+    field public static final int RATING_5_STARS = 5; // 0x5
+    field public static final int RATING_HEART = 1; // 0x1
+    field public static final int RATING_NONE = 0; // 0x0
+    field public static final int RATING_PERCENTAGE = 6; // 0x6
+    field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
+  }
+
+  public abstract class TransportController {
+    ctor public TransportController();
+    method public abstract int getBufferPercentage();
+    method public abstract long getCurrentPosition();
+    method public abstract long getDuration();
+    method public abstract int getTransportControlFlags();
+    method public abstract boolean isPlaying();
+    method public abstract void pausePlaying();
+    method public abstract void registerStateListener(android.support.v4.media.TransportStateListener);
+    method public abstract void seekTo(long);
+    method public abstract void startPlaying();
+    method public abstract void stopPlaying();
+    method public abstract void unregisterStateListener(android.support.v4.media.TransportStateListener);
+  }
+
+  public class TransportMediator extends android.support.v4.media.TransportController {
+    ctor public TransportMediator(android.app.Activity, android.support.v4.media.TransportPerformer);
+    ctor public TransportMediator(android.view.View, android.support.v4.media.TransportPerformer);
+    method public void destroy();
+    method public boolean dispatchKeyEvent(android.view.KeyEvent);
+    method public int getBufferPercentage();
+    method public long getCurrentPosition();
+    method public long getDuration();
+    method public java.lang.Object getRemoteControlClient();
+    method public int getTransportControlFlags();
+    method public boolean isPlaying();
+    method public void pausePlaying();
+    method public void refreshState();
+    method public void registerStateListener(android.support.v4.media.TransportStateListener);
+    method public void seekTo(long);
+    method public void startPlaying();
+    method public void stopPlaying();
+    method public void unregisterStateListener(android.support.v4.media.TransportStateListener);
+    field public static final int FLAG_KEY_MEDIA_FAST_FORWARD = 64; // 0x40
+    field public static final int FLAG_KEY_MEDIA_NEXT = 128; // 0x80
+    field public static final int FLAG_KEY_MEDIA_PAUSE = 16; // 0x10
+    field public static final int FLAG_KEY_MEDIA_PLAY = 4; // 0x4
+    field public static final int FLAG_KEY_MEDIA_PLAY_PAUSE = 8; // 0x8
+    field public static final int FLAG_KEY_MEDIA_PREVIOUS = 1; // 0x1
+    field public static final int FLAG_KEY_MEDIA_REWIND = 2; // 0x2
+    field public static final int FLAG_KEY_MEDIA_STOP = 32; // 0x20
+    field public static final int KEYCODE_MEDIA_PAUSE = 127; // 0x7f
+    field public static final int KEYCODE_MEDIA_PLAY = 126; // 0x7e
+    field public static final int KEYCODE_MEDIA_RECORD = 130; // 0x82
+  }
+
+  public abstract class TransportPerformer {
+    ctor public TransportPerformer();
+    method public void onAudioFocusChange(int);
+    method public int onGetBufferPercentage();
+    method public abstract long onGetCurrentPosition();
+    method public abstract long onGetDuration();
+    method public int onGetTransportControlFlags();
+    method public abstract boolean onIsPlaying();
+    method public boolean onMediaButtonDown(int, android.view.KeyEvent);
+    method public boolean onMediaButtonUp(int, android.view.KeyEvent);
+    method public abstract void onPause();
+    method public abstract void onSeekTo(long);
+    method public abstract void onStart();
+    method public abstract void onStop();
+  }
+
+  public class TransportStateListener {
+    ctor public TransportStateListener();
+    method public void onPlayingChanged(android.support.v4.media.TransportController);
+    method public void onTransportControlsChanged(android.support.v4.media.TransportController);
+  }
+
+  public abstract class VolumeProviderCompat {
+    ctor public VolumeProviderCompat(int, int, int);
+    method public final int getCurrentVolume();
+    method public final int getMaxVolume();
+    method public final int getVolumeControl();
+    method public java.lang.Object getVolumeProvider();
+    method public void onAdjustVolume(int);
+    method public void onSetVolumeTo(int);
+    method public void setCallback(android.support.v4.media.VolumeProviderCompat.Callback);
+    method public final void setCurrentVolume(int);
+    field public static final int VOLUME_CONTROL_ABSOLUTE = 2; // 0x2
+    field public static final int VOLUME_CONTROL_FIXED = 0; // 0x0
+    field public static final int VOLUME_CONTROL_RELATIVE = 1; // 0x1
+  }
+
+  public static abstract class VolumeProviderCompat.Callback {
+    ctor public VolumeProviderCompat.Callback();
+    method public abstract void onVolumeChanged(android.support.v4.media.VolumeProviderCompat);
+  }
+
+}
+
+package android.support.v4.media.session {
+
+  public class MediaButtonReceiver extends android.content.BroadcastReceiver {
+    ctor public MediaButtonReceiver();
+    method public static android.app.PendingIntent buildMediaButtonPendingIntent(android.content.Context, long);
+    method public static android.app.PendingIntent buildMediaButtonPendingIntent(android.content.Context, android.content.ComponentName, long);
+    method public static android.view.KeyEvent handleIntent(android.support.v4.media.session.MediaSessionCompat, android.content.Intent);
+    method public void onReceive(android.content.Context, android.content.Intent);
+  }
+
+  public final class MediaControllerCompat {
+    ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat);
+    ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat.Token) throws android.os.RemoteException;
+    method public void adjustVolume(int, int);
+    method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
+    method public android.os.Bundle getExtras();
+    method public long getFlags();
+    method public static android.support.v4.media.session.MediaControllerCompat getMediaController(android.app.Activity);
+    method public java.lang.Object getMediaController();
+    method public android.support.v4.media.MediaMetadataCompat getMetadata();
+    method public java.lang.String getPackageName();
+    method public android.support.v4.media.session.MediaControllerCompat.PlaybackInfo getPlaybackInfo();
+    method public android.support.v4.media.session.PlaybackStateCompat getPlaybackState();
+    method public java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem> getQueue();
+    method public java.lang.CharSequence getQueueTitle();
+    method public int getRatingType();
+    method public int getRepeatMode();
+    method public android.app.PendingIntent getSessionActivity();
+    method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+    method public android.support.v4.media.session.MediaControllerCompat.TransportControls getTransportControls();
+    method public boolean isShuffleModeEnabled();
+    method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback);
+    method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback, android.os.Handler);
+    method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public static void setMediaController(android.app.Activity, android.support.v4.media.session.MediaControllerCompat);
+    method public void setVolumeTo(int, int);
+    method public void unregisterCallback(android.support.v4.media.session.MediaControllerCompat.Callback);
+  }
+
+  public static abstract class MediaControllerCompat.Callback implements android.os.IBinder.DeathRecipient {
+    ctor public MediaControllerCompat.Callback();
+    method public void binderDied();
+    method public void onAudioInfoChanged(android.support.v4.media.session.MediaControllerCompat.PlaybackInfo);
+    method public void onExtrasChanged(android.os.Bundle);
+    method public void onMetadataChanged(android.support.v4.media.MediaMetadataCompat);
+    method public void onPlaybackStateChanged(android.support.v4.media.session.PlaybackStateCompat);
+    method public void onQueueChanged(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>);
+    method public void onQueueTitleChanged(java.lang.CharSequence);
+    method public void onRepeatModeChanged(int);
+    method public void onSessionDestroyed();
+    method public void onSessionEvent(java.lang.String, android.os.Bundle);
+    method public void onShuffleModeChanged(boolean);
+  }
+
+  public static final class MediaControllerCompat.PlaybackInfo {
+    method public int getAudioStream();
+    method public int getCurrentVolume();
+    method public int getMaxVolume();
+    method public int getPlaybackType();
+    method public int getVolumeControl();
+    field public static final int PLAYBACK_TYPE_LOCAL = 1; // 0x1
+    field public static final int PLAYBACK_TYPE_REMOTE = 2; // 0x2
+  }
+
+  public static abstract class MediaControllerCompat.TransportControls {
+    method public abstract void fastForward();
+    method public abstract void pause();
+    method public abstract void play();
+    method public abstract void playFromMediaId(java.lang.String, android.os.Bundle);
+    method public abstract void playFromSearch(java.lang.String, android.os.Bundle);
+    method public abstract void playFromUri(android.net.Uri, android.os.Bundle);
+    method public abstract void prepare();
+    method public abstract void prepareFromMediaId(java.lang.String, android.os.Bundle);
+    method public abstract void prepareFromSearch(java.lang.String, android.os.Bundle);
+    method public abstract void prepareFromUri(android.net.Uri, android.os.Bundle);
+    method public abstract void rewind();
+    method public abstract void seekTo(long);
+    method public abstract void sendCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction, android.os.Bundle);
+    method public abstract void sendCustomAction(java.lang.String, android.os.Bundle);
+    method public abstract void setRating(android.support.v4.media.RatingCompat);
+    method public abstract void setRepeatMode(int);
+    method public abstract void setShuffleModeEnabled(boolean);
+    method public abstract void skipToNext();
+    method public abstract void skipToPrevious();
+    method public abstract void skipToQueueItem(long);
+    method public abstract void stop();
+  }
+
+  public class MediaSessionCompat {
+    ctor public MediaSessionCompat(android.content.Context, java.lang.String);
+    ctor public MediaSessionCompat(android.content.Context, java.lang.String, android.content.ComponentName, android.app.PendingIntent);
+    method public void addOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener);
+    method public static android.support.v4.media.session.MediaSessionCompat fromMediaSession(android.content.Context, java.lang.Object);
+    method public android.support.v4.media.session.MediaControllerCompat getController();
+    method public java.lang.Object getMediaSession();
+    method public java.lang.Object getRemoteControlClient();
+    method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+    method public boolean isActive();
+    method public static deprecated android.support.v4.media.session.MediaSessionCompat obtain(android.content.Context, java.lang.Object);
+    method public void release();
+    method public void removeOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener);
+    method public void sendSessionEvent(java.lang.String, android.os.Bundle);
+    method public void setActive(boolean);
+    method public void setCallback(android.support.v4.media.session.MediaSessionCompat.Callback);
+    method public void setCallback(android.support.v4.media.session.MediaSessionCompat.Callback, android.os.Handler);
+    method public void setExtras(android.os.Bundle);
+    method public void setFlags(int);
+    method public void setMediaButtonReceiver(android.app.PendingIntent);
+    method public void setMetadata(android.support.v4.media.MediaMetadataCompat);
+    method public void setPlaybackState(android.support.v4.media.session.PlaybackStateCompat);
+    method public void setPlaybackToLocal(int);
+    method public void setPlaybackToRemote(android.support.v4.media.VolumeProviderCompat);
+    method public void setQueue(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>);
+    method public void setQueueTitle(java.lang.CharSequence);
+    method public void setRatingType(int);
+    method public void setRepeatMode(int);
+    method public void setSessionActivity(android.app.PendingIntent);
+    method public void setShuffleModeEnabled(boolean);
+    field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+    field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
+  }
+
+  public static abstract class MediaSessionCompat.Callback {
+    ctor public MediaSessionCompat.Callback();
+    method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public void onCustomAction(java.lang.String, android.os.Bundle);
+    method public void onFastForward();
+    method public boolean onMediaButtonEvent(android.content.Intent);
+    method public void onPause();
+    method public void onPlay();
+    method public void onPlayFromMediaId(java.lang.String, android.os.Bundle);
+    method public void onPlayFromSearch(java.lang.String, android.os.Bundle);
+    method public void onPlayFromUri(android.net.Uri, android.os.Bundle);
+    method public void onPrepare();
+    method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
+    method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
+    method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
+    method public void onRewind();
+    method public void onSeekTo(long);
+    method public void onSetRating(android.support.v4.media.RatingCompat);
+    method public void onSetRepeatMode(int);
+    method public void onSetShuffleModeEnabled(boolean);
+    method public void onSkipToNext();
+    method public void onSkipToPrevious();
+    method public void onSkipToQueueItem(long);
+    method public void onStop();
+  }
+
+  public static abstract interface MediaSessionCompat.OnActiveChangeListener {
+    method public abstract void onActiveChanged();
+  }
+
+  public static final class MediaSessionCompat.QueueItem implements android.os.Parcelable {
+    ctor public MediaSessionCompat.QueueItem(android.support.v4.media.MediaDescriptionCompat, long);
+    method public int describeContents();
+    method public static android.support.v4.media.session.MediaSessionCompat.QueueItem fromQueueItem(java.lang.Object);
+    method public static java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem> fromQueueItemList(java.util.List<?>);
+    method public android.support.v4.media.MediaDescriptionCompat getDescription();
+    method public long getQueueId();
+    method public java.lang.Object getQueueItem();
+    method public static deprecated android.support.v4.media.session.MediaSessionCompat.QueueItem obtain(java.lang.Object);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.media.session.MediaSessionCompat.QueueItem> CREATOR;
+    field public static final int UNKNOWN_ID = -1; // 0xffffffff
+  }
+
+  public static final class MediaSessionCompat.Token implements android.os.Parcelable {
+    method public int describeContents();
+    method public static android.support.v4.media.session.MediaSessionCompat.Token fromToken(java.lang.Object);
+    method public java.lang.Object getToken();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.media.session.MediaSessionCompat.Token> CREATOR;
+  }
+
+  public class ParcelableVolumeInfo implements android.os.Parcelable {
+    ctor public ParcelableVolumeInfo(int, int, int, int, int);
+    ctor public ParcelableVolumeInfo(android.os.Parcel);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.media.session.ParcelableVolumeInfo> CREATOR;
+    field public int audioStream;
+    field public int controlType;
+    field public int currentVolume;
+    field public int maxVolume;
+    field public int volumeType;
+  }
+
+  public final class PlaybackStateCompat implements android.os.Parcelable {
+    method public int describeContents();
+    method public static android.support.v4.media.session.PlaybackStateCompat fromPlaybackState(java.lang.Object);
+    method public long getActions();
+    method public long getActiveQueueItemId();
+    method public long getBufferedPosition();
+    method public java.util.List<android.support.v4.media.session.PlaybackStateCompat.CustomAction> getCustomActions();
+    method public java.lang.CharSequence getErrorMessage();
+    method public android.os.Bundle getExtras();
+    method public long getLastPositionUpdateTime();
+    method public float getPlaybackSpeed();
+    method public java.lang.Object getPlaybackState();
+    method public long getPosition();
+    method public int getState();
+    method public static int toKeyCode(long);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final long ACTION_FAST_FORWARD = 64L; // 0x40L
+    field public static final long ACTION_PAUSE = 2L; // 0x2L
+    field public static final long ACTION_PLAY = 4L; // 0x4L
+    field public static final long ACTION_PLAY_FROM_MEDIA_ID = 1024L; // 0x400L
+    field public static final long ACTION_PLAY_FROM_SEARCH = 2048L; // 0x800L
+    field public static final long ACTION_PLAY_FROM_URI = 8192L; // 0x2000L
+    field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L
+    field public static final long ACTION_PREPARE = 16384L; // 0x4000L
+    field public static final long ACTION_PREPARE_FROM_MEDIA_ID = 32768L; // 0x8000L
+    field public static final long ACTION_PREPARE_FROM_SEARCH = 65536L; // 0x10000L
+    field public static final long ACTION_PREPARE_FROM_URI = 131072L; // 0x20000L
+    field public static final long ACTION_REWIND = 8L; // 0x8L
+    field public static final long ACTION_SEEK_TO = 256L; // 0x100L
+    field public static final long ACTION_SET_RATING = 128L; // 0x80L
+    field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
+    field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
+    field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
+    field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
+    field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
+    field public static final long ACTION_STOP = 1L; // 0x1L
+    field public static final android.os.Parcelable.Creator<android.support.v4.media.session.PlaybackStateCompat> CREATOR;
+    field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
+    field public static final int REPEAT_MODE_ALL = 2; // 0x2
+    field public static final int REPEAT_MODE_NONE = 0; // 0x0
+    field public static final int REPEAT_MODE_ONE = 1; // 0x1
+    field public static final int STATE_BUFFERING = 6; // 0x6
+    field public static final int STATE_CONNECTING = 8; // 0x8
+    field public static final int STATE_ERROR = 7; // 0x7
+    field public static final int STATE_FAST_FORWARDING = 4; // 0x4
+    field public static final int STATE_NONE = 0; // 0x0
+    field public static final int STATE_PAUSED = 2; // 0x2
+    field public static final int STATE_PLAYING = 3; // 0x3
+    field public static final int STATE_REWINDING = 5; // 0x5
+    field public static final int STATE_SKIPPING_TO_NEXT = 10; // 0xa
+    field public static final int STATE_SKIPPING_TO_PREVIOUS = 9; // 0x9
+    field public static final int STATE_SKIPPING_TO_QUEUE_ITEM = 11; // 0xb
+    field public static final int STATE_STOPPED = 1; // 0x1
+  }
+
+  public static final class PlaybackStateCompat.Builder {
+    ctor public PlaybackStateCompat.Builder();
+    ctor public PlaybackStateCompat.Builder(android.support.v4.media.session.PlaybackStateCompat);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder addCustomAction(java.lang.String, java.lang.String, int);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder addCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction);
+    method public android.support.v4.media.session.PlaybackStateCompat build();
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder setActions(long);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder setActiveQueueItemId(long);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder setBufferedPosition(long);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder setErrorMessage(java.lang.CharSequence);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder setExtras(android.os.Bundle);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder setState(int, long, float);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder setState(int, long, float, long);
+  }
+
+  public static final class PlaybackStateCompat.CustomAction implements android.os.Parcelable {
+    method public int describeContents();
+    method public static android.support.v4.media.session.PlaybackStateCompat.CustomAction fromCustomAction(java.lang.Object);
+    method public java.lang.String getAction();
+    method public java.lang.Object getCustomAction();
+    method public android.os.Bundle getExtras();
+    method public int getIcon();
+    method public java.lang.CharSequence getName();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.media.session.PlaybackStateCompat.CustomAction> CREATOR;
+  }
+
+  public static final class PlaybackStateCompat.CustomAction.Builder {
+    ctor public PlaybackStateCompat.CustomAction.Builder(java.lang.String, java.lang.CharSequence, int);
+    method public android.support.v4.media.session.PlaybackStateCompat.CustomAction build();
+    method public android.support.v4.media.session.PlaybackStateCompat.CustomAction.Builder setExtras(android.os.Bundle);
+  }
+
+}
+
+package android.support.v4.net {
+
+  public final class ConnectivityManagerCompat {
+    method public static android.net.NetworkInfo getNetworkInfoFromBroadcast(android.net.ConnectivityManager, android.content.Intent);
+    method public static int getRestrictBackgroundStatus(android.net.ConnectivityManager);
+    method public static boolean isActiveNetworkMetered(android.net.ConnectivityManager);
+    field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+    field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+    field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
+  }
+
+  public final class TrafficStatsCompat {
+    method public static void clearThreadStatsTag();
+    method public static int getThreadStatsTag();
+    method public static void incrementOperationCount(int);
+    method public static void incrementOperationCount(int, int);
+    method public static void setThreadStatsTag(int);
+    method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method public static void tagSocket(java.net.Socket) throws java.net.SocketException;
+    method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method public static void untagSocket(java.net.Socket) throws java.net.SocketException;
+  }
+
+}
+
+package android.support.v4.os {
+
+  public final class AsyncTaskCompat {
+    method public static <Params, Progress, Result> android.os.AsyncTask<Params, Progress, Result> executeParallel(android.os.AsyncTask<Params, Progress, Result>, Params...);
+  }
+
+  public class BuildCompat {
+    method public static boolean isAtLeastN();
+    method public static boolean isAtLeastNMR1();
+    method public static boolean isAtLeastO();
+  }
+
+  public final class CancellationSignal {
+    ctor public CancellationSignal();
+    method public void cancel();
+    method public java.lang.Object getCancellationSignalObject();
+    method public boolean isCanceled();
+    method public void setOnCancelListener(android.support.v4.os.CancellationSignal.OnCancelListener);
+    method public void throwIfCanceled();
+  }
+
+  public static abstract interface CancellationSignal.OnCancelListener {
+    method public abstract void onCancel();
+  }
+
+  public final class EnvironmentCompat {
+    method public static java.lang.String getStorageState(java.io.File);
+    field public static final java.lang.String MEDIA_UNKNOWN = "unknown";
+  }
+
+  public class OperationCanceledException extends java.lang.RuntimeException {
+    ctor public OperationCanceledException();
+    ctor public OperationCanceledException(java.lang.String);
+  }
+
+  public final class ParcelableCompat {
+    method public static <T> android.os.Parcelable.Creator<T> newCreator(android.support.v4.os.ParcelableCompatCreatorCallbacks<T>);
+  }
+
+  public abstract interface ParcelableCompatCreatorCallbacks<T> {
+    method public abstract T createFromParcel(android.os.Parcel, java.lang.ClassLoader);
+    method public abstract T[] newArray(int);
+  }
+
+  public final class TraceCompat {
+    method public static void beginSection(java.lang.String);
+    method public static void endSection();
+  }
+
+  public class UserManagerCompat {
+    method public static boolean isUserUnlocked(android.content.Context);
+  }
+
+}
+
+package android.support.v4.print {
+
+  public final class PrintHelper {
+    ctor public PrintHelper(android.content.Context);
+    method public int getColorMode();
+    method public int getOrientation();
+    method public int getScaleMode();
+    method public void printBitmap(java.lang.String, android.graphics.Bitmap);
+    method public void printBitmap(java.lang.String, android.graphics.Bitmap, android.support.v4.print.PrintHelper.OnPrintFinishCallback);
+    method public void printBitmap(java.lang.String, android.net.Uri) throws java.io.FileNotFoundException;
+    method public void printBitmap(java.lang.String, android.net.Uri, android.support.v4.print.PrintHelper.OnPrintFinishCallback) throws java.io.FileNotFoundException;
+    method public void setColorMode(int);
+    method public void setOrientation(int);
+    method public void setScaleMode(int);
+    method public static boolean systemSupportsPrint();
+    field public static final int COLOR_MODE_COLOR = 2; // 0x2
+    field public static final int COLOR_MODE_MONOCHROME = 1; // 0x1
+    field public static final int ORIENTATION_LANDSCAPE = 1; // 0x1
+    field public static final int ORIENTATION_PORTRAIT = 2; // 0x2
+    field public static final int SCALE_MODE_FILL = 2; // 0x2
+    field public static final int SCALE_MODE_FIT = 1; // 0x1
+  }
+
+  public static abstract interface PrintHelper.OnPrintFinishCallback {
+    method public abstract void onFinish();
+  }
+
+}
+
+package android.support.v4.provider {
+
+  public abstract class DocumentFile {
+    method public abstract boolean canRead();
+    method public abstract boolean canWrite();
+    method public abstract android.support.v4.provider.DocumentFile createDirectory(java.lang.String);
+    method public abstract android.support.v4.provider.DocumentFile createFile(java.lang.String, java.lang.String);
+    method public abstract boolean delete();
+    method public abstract boolean exists();
+    method public android.support.v4.provider.DocumentFile findFile(java.lang.String);
+    method public static android.support.v4.provider.DocumentFile fromFile(java.io.File);
+    method public static android.support.v4.provider.DocumentFile fromSingleUri(android.content.Context, android.net.Uri);
+    method public static android.support.v4.provider.DocumentFile fromTreeUri(android.content.Context, android.net.Uri);
+    method public abstract java.lang.String getName();
+    method public android.support.v4.provider.DocumentFile getParentFile();
+    method public abstract java.lang.String getType();
+    method public abstract android.net.Uri getUri();
+    method public abstract boolean isDirectory();
+    method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
+    method public abstract boolean isFile();
+    method public abstract boolean isVirtual();
+    method public abstract long lastModified();
+    method public abstract long length();
+    method public abstract android.support.v4.provider.DocumentFile[] listFiles();
+    method public abstract boolean renameTo(java.lang.String);
+  }
+
+}
+
+package android.support.v4.text {
+
+  public final class BidiFormatter {
+    method public static android.support.v4.text.BidiFormatter getInstance();
+    method public static android.support.v4.text.BidiFormatter getInstance(boolean);
+    method public static android.support.v4.text.BidiFormatter getInstance(java.util.Locale);
+    method public boolean getStereoReset();
+    method public boolean isRtl(java.lang.String);
+    method public boolean isRtl(java.lang.CharSequence);
+    method public boolean isRtlContext();
+    method public java.lang.String unicodeWrap(java.lang.String, android.support.v4.text.TextDirectionHeuristicCompat, boolean);
+    method public java.lang.CharSequence unicodeWrap(java.lang.CharSequence, android.support.v4.text.TextDirectionHeuristicCompat, boolean);
+    method public java.lang.String unicodeWrap(java.lang.String, android.support.v4.text.TextDirectionHeuristicCompat);
+    method public java.lang.CharSequence unicodeWrap(java.lang.CharSequence, android.support.v4.text.TextDirectionHeuristicCompat);
+    method public java.lang.String unicodeWrap(java.lang.String, boolean);
+    method public java.lang.CharSequence unicodeWrap(java.lang.CharSequence, boolean);
+    method public java.lang.String unicodeWrap(java.lang.String);
+    method public java.lang.CharSequence unicodeWrap(java.lang.CharSequence);
+  }
+
+  public static final class BidiFormatter.Builder {
+    ctor public BidiFormatter.Builder();
+    ctor public BidiFormatter.Builder(boolean);
+    ctor public BidiFormatter.Builder(java.util.Locale);
+    method public android.support.v4.text.BidiFormatter build();
+    method public android.support.v4.text.BidiFormatter.Builder setTextDirectionHeuristic(android.support.v4.text.TextDirectionHeuristicCompat);
+    method public android.support.v4.text.BidiFormatter.Builder stereoReset(boolean);
+  }
+
+  public final class ICUCompat {
+    method public static java.lang.String maximizeAndGetScript(java.util.Locale);
+  }
+
+  public abstract interface TextDirectionHeuristicCompat {
+    method public abstract boolean isRtl(char[], int, int);
+    method public abstract boolean isRtl(java.lang.CharSequence, int, int);
+  }
+
+  public final class TextDirectionHeuristicsCompat {
+    field public static final android.support.v4.text.TextDirectionHeuristicCompat ANYRTL_LTR;
+    field public static final android.support.v4.text.TextDirectionHeuristicCompat FIRSTSTRONG_LTR;
+    field public static final android.support.v4.text.TextDirectionHeuristicCompat FIRSTSTRONG_RTL;
+    field public static final android.support.v4.text.TextDirectionHeuristicCompat LOCALE;
+    field public static final android.support.v4.text.TextDirectionHeuristicCompat LTR;
+    field public static final android.support.v4.text.TextDirectionHeuristicCompat RTL;
+  }
+
+  public final class TextUtilsCompat {
+    method public static int getLayoutDirectionFromLocale(java.util.Locale);
+    method public static java.lang.String htmlEncode(java.lang.String);
+    field public static final java.util.Locale ROOT;
+  }
+
+}
+
+package android.support.v4.text.util {
+
+  public final class LinkifyCompat {
+    method public static final boolean addLinks(android.text.Spannable, int);
+    method public static final boolean addLinks(android.widget.TextView, int);
+    method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String);
+    method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
+    method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
+    method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String);
+    method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
+    method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
+  }
+
+  public static abstract class LinkifyCompat.LinkifyMask implements java.lang.annotation.Annotation {
+  }
+
+}
+
+package android.support.v4.util {
+
+  public class ArrayMap<K, V> extends android.support.v4.util.SimpleArrayMap implements java.util.Map {
+    ctor public ArrayMap();
+    ctor public ArrayMap(int);
+    ctor public ArrayMap(android.support.v4.util.SimpleArrayMap);
+    method public boolean containsAll(java.util.Collection<?>);
+    method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public java.util.Set<K> keySet();
+    method public void putAll(java.util.Map<? extends K, ? extends V>);
+    method public boolean removeAll(java.util.Collection<?>);
+    method public boolean retainAll(java.util.Collection<?>);
+    method public java.util.Collection<V> values();
+  }
+
+  public final class ArraySet<E> implements java.util.Collection java.util.Set {
+    ctor public ArraySet();
+    ctor public ArraySet(int);
+    ctor public ArraySet(android.support.v4.util.ArraySet<E>);
+    method public boolean add(E);
+    method public void addAll(android.support.v4.util.ArraySet<? extends E>);
+    method public boolean addAll(java.util.Collection<? extends E>);
+    method public void clear();
+    method public boolean contains(java.lang.Object);
+    method public boolean containsAll(java.util.Collection<?>);
+    method public void ensureCapacity(int);
+    method public int indexOf(java.lang.Object);
+    method public boolean isEmpty();
+    method public java.util.Iterator<E> iterator();
+    method public boolean remove(java.lang.Object);
+    method public boolean removeAll(android.support.v4.util.ArraySet<? extends E>);
+    method public boolean removeAll(java.util.Collection<?>);
+    method public E removeAt(int);
+    method public boolean retainAll(java.util.Collection<?>);
+    method public int size();
+    method public java.lang.Object[] toArray();
+    method public <T> T[] toArray(T[]);
+    method public E valueAt(int);
+  }
+
+  public class AtomicFile {
+    ctor public AtomicFile(java.io.File);
+    method public void delete();
+    method public void failWrite(java.io.FileOutputStream);
+    method public void finishWrite(java.io.FileOutputStream);
+    method public java.io.File getBaseFile();
+    method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
+    method public byte[] readFully() throws java.io.IOException;
+    method public java.io.FileOutputStream startWrite() throws java.io.IOException;
+  }
+
+  public final class CircularArray<E> {
+    ctor public CircularArray();
+    ctor public CircularArray(int);
+    method public void addFirst(E);
+    method public void addLast(E);
+    method public void clear();
+    method public E get(int);
+    method public E getFirst();
+    method public E getLast();
+    method public boolean isEmpty();
+    method public E popFirst();
+    method public E popLast();
+    method public void removeFromEnd(int);
+    method public void removeFromStart(int);
+    method public int size();
+  }
+
+  public final class CircularIntArray {
+    ctor public CircularIntArray();
+    ctor public CircularIntArray(int);
+    method public void addFirst(int);
+    method public void addLast(int);
+    method public void clear();
+    method public int get(int);
+    method public int getFirst();
+    method public int getLast();
+    method public boolean isEmpty();
+    method public int popFirst();
+    method public int popLast();
+    method public void removeFromEnd(int);
+    method public void removeFromStart(int);
+    method public int size();
+  }
+
+  public class LongSparseArray<E> {
+    ctor public LongSparseArray();
+    ctor public LongSparseArray(int);
+    method public void append(long, E);
+    method public void clear();
+    method public android.support.v4.util.LongSparseArray<E> clone();
+    method public void delete(long);
+    method public E get(long);
+    method public E get(long, E);
+    method public int indexOfKey(long);
+    method public int indexOfValue(E);
+    method public long keyAt(int);
+    method public void put(long, E);
+    method public void remove(long);
+    method public void removeAt(int);
+    method public void setValueAt(int, E);
+    method public int size();
+    method public E valueAt(int);
+  }
+
+  public class LruCache<K, V> {
+    ctor public LruCache(int);
+    method protected V create(K);
+    method public final synchronized int createCount();
+    method protected void entryRemoved(boolean, K, V, V);
+    method public final void evictAll();
+    method public final synchronized int evictionCount();
+    method public final V get(K);
+    method public final synchronized int hitCount();
+    method public final synchronized int maxSize();
+    method public final synchronized int missCount();
+    method public final V put(K, V);
+    method public final synchronized int putCount();
+    method public final V remove(K);
+    method public void resize(int);
+    method public final synchronized int size();
+    method protected int sizeOf(K, V);
+    method public final synchronized java.util.Map<K, V> snapshot();
+    method public final synchronized java.lang.String toString();
+    method public void trimToSize(int);
+  }
+
+  public class Pair<F, S> {
+    ctor public Pair(F, S);
+    method public static <A, B> android.support.v4.util.Pair<A, B> create(A, B);
+    field public final F first;
+    field public final S second;
+  }
+
+  public final class PatternsCompat {
+    field public static final java.util.regex.Pattern DOMAIN_NAME;
+    field public static final java.util.regex.Pattern EMAIL_ADDRESS;
+    field public static final java.util.regex.Pattern IP_ADDRESS;
+    field public static final java.util.regex.Pattern WEB_URL;
+  }
+
+  public final class Pools {
+  }
+
+  public static abstract interface Pools.Pool<T> {
+    method public abstract T acquire();
+    method public abstract boolean release(T);
+  }
+
+  public static class Pools.SimplePool<T> implements android.support.v4.util.Pools.Pool {
+    ctor public Pools.SimplePool(int);
+    method public T acquire();
+    method public boolean release(T);
+  }
+
+  public static class Pools.SynchronizedPool<T> extends android.support.v4.util.Pools.SimplePool {
+    ctor public Pools.SynchronizedPool(int);
+  }
+
+  public class SimpleArrayMap<K, V> {
+    ctor public SimpleArrayMap();
+    ctor public SimpleArrayMap(int);
+    ctor public SimpleArrayMap(android.support.v4.util.SimpleArrayMap);
+    method public void clear();
+    method public boolean containsKey(java.lang.Object);
+    method public boolean containsValue(java.lang.Object);
+    method public void ensureCapacity(int);
+    method public V get(java.lang.Object);
+    method public int indexOfKey(java.lang.Object);
+    method public boolean isEmpty();
+    method public K keyAt(int);
+    method public V put(K, V);
+    method public void putAll(android.support.v4.util.SimpleArrayMap<? extends K, ? extends V>);
+    method public V remove(java.lang.Object);
+    method public V removeAt(int);
+    method public V setValueAt(int, V);
+    method public int size();
+    method public V valueAt(int);
+  }
+
+  public class SparseArrayCompat<E> {
+    ctor public SparseArrayCompat();
+    ctor public SparseArrayCompat(int);
+    method public void append(int, E);
+    method public void clear();
+    method public android.support.v4.util.SparseArrayCompat<E> clone();
+    method public void delete(int);
+    method public E get(int);
+    method public E get(int, E);
+    method public int indexOfKey(int);
+    method public int indexOfValue(E);
+    method public int keyAt(int);
+    method public void put(int, E);
+    method public void remove(int);
+    method public void removeAt(int);
+    method public void removeAtRange(int, int);
+    method public void setValueAt(int, E);
+    method public int size();
+    method public E valueAt(int);
+  }
+
+}
+
+package android.support.v4.view {
+
+  public abstract class AbsSavedState implements android.os.Parcelable {
+    ctor protected AbsSavedState(android.os.Parcelable);
+    ctor protected AbsSavedState(android.os.Parcel);
+    ctor protected AbsSavedState(android.os.Parcel, java.lang.ClassLoader);
+    method public int describeContents();
+    method public final android.os.Parcelable getSuperState();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.support.v4.view.AbsSavedState> CREATOR;
+    field public static final android.support.v4.view.AbsSavedState EMPTY_STATE;
+  }
+
+  public class AccessibilityDelegateCompat {
+    ctor public AccessibilityDelegateCompat();
+    method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public android.support.v4.view.accessibility.AccessibilityNodeProviderCompat getAccessibilityNodeProvider(android.view.View);
+    method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(android.view.View, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle);
+    method public void sendAccessibilityEvent(android.view.View, int);
+    method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
+  }
+
+  public abstract class ActionProvider {
+    ctor public ActionProvider(android.content.Context);
+    method public android.content.Context getContext();
+    method public boolean hasSubMenu();
+    method public boolean isVisible();
+    method public abstract android.view.View onCreateActionView();
+    method public android.view.View onCreateActionView(android.view.MenuItem);
+    method public boolean onPerformDefaultAction();
+    method public void onPrepareSubMenu(android.view.SubMenu);
+    method public boolean overridesItemVisibility();
+    method public void refreshVisibility();
+    method public void setVisibilityListener(android.support.v4.view.ActionProvider.VisibilityListener);
+  }
+
+  public static abstract interface ActionProvider.VisibilityListener {
+    method public abstract void onActionProviderVisibilityChanged(boolean);
+  }
+
+  public final class AsyncLayoutInflater {
+    ctor public AsyncLayoutInflater(android.content.Context);
+    method public void inflate(int, android.view.ViewGroup, android.support.v4.view.AsyncLayoutInflater.OnInflateFinishedListener);
+  }
+
+  public static abstract interface AsyncLayoutInflater.OnInflateFinishedListener {
+    method public abstract void onInflateFinished(android.view.View, int, android.view.ViewGroup);
+  }
+
+  public final class GestureDetectorCompat {
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener);
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler);
+    method public boolean isLongpressEnabled();
+    method public boolean onTouchEvent(android.view.MotionEvent);
+    method public void setIsLongpressEnabled(boolean);
+    method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener);
+  }
+
+  public final class GravityCompat {
+    method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
+    method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static int getAbsoluteGravity(int, int);
+    field public static final int END = 8388613; // 0x800005
+    field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
+    field public static final int RELATIVE_LAYOUT_DIRECTION = 8388608; // 0x800000
+    field public static final int START = 8388611; // 0x800003
+  }
+
+  public final class InputDeviceCompat {
+    field public static final int SOURCE_ANY = -256; // 0xffffff00
+    field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
+    field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
+    field public static final int SOURCE_CLASS_MASK = 255; // 0xff
+    field public static final int SOURCE_CLASS_NONE = 0; // 0x0
+    field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
+    field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
+    field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
+    field public static final int SOURCE_DPAD = 513; // 0x201
+    field public static final int SOURCE_GAMEPAD = 1025; // 0x401
+    field public static final int SOURCE_HDMI = 33554433; // 0x2000001
+    field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
+    field public static final int SOURCE_KEYBOARD = 257; // 0x101
+    field public static final int SOURCE_MOUSE = 8194; // 0x2002
+    field public static final int SOURCE_STYLUS = 16386; // 0x4002
+    field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
+    field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
+    field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
+    field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
+    field public static final int SOURCE_UNKNOWN = 0; // 0x0
+  }
+
+  public final class KeyEventCompat {
+    method public static deprecated boolean dispatch(android.view.KeyEvent, android.view.KeyEvent.Callback, java.lang.Object, java.lang.Object);
+    method public static deprecated java.lang.Object getKeyDispatcherState(android.view.View);
+    method public static boolean hasModifiers(android.view.KeyEvent, int);
+    method public static boolean hasNoModifiers(android.view.KeyEvent);
+    method public static boolean isCtrlPressed(android.view.KeyEvent);
+    method public static deprecated boolean isTracking(android.view.KeyEvent);
+    method public static boolean metaStateHasModifiers(int, int);
+    method public static boolean metaStateHasNoModifiers(int);
+    method public static int normalizeMetaState(int);
+    method public static deprecated void startTracking(android.view.KeyEvent);
+  }
+
+  public final class LayoutInflaterCompat {
+    method public static android.support.v4.view.LayoutInflaterFactory getFactory(android.view.LayoutInflater);
+    method public static void setFactory(android.view.LayoutInflater, android.support.v4.view.LayoutInflaterFactory);
+  }
+
+  public abstract interface LayoutInflaterFactory {
+    method public abstract android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+  }
+
+  public final class MarginLayoutParamsCompat {
+    method public static int getLayoutDirection(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginEnd(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginStart(android.view.ViewGroup.MarginLayoutParams);
+    method public static boolean isMarginRelative(android.view.ViewGroup.MarginLayoutParams);
+    method public static void resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginStart(android.view.ViewGroup.MarginLayoutParams, int);
+  }
+
+  public final class MenuCompat {
+    method public static deprecated void setShowAsAction(android.view.MenuItem, int);
+  }
+
+  public final class MenuItemCompat {
+    method public static boolean collapseActionView(android.view.MenuItem);
+    method public static boolean expandActionView(android.view.MenuItem);
+    method public static android.support.v4.view.ActionProvider getActionProvider(android.view.MenuItem);
+    method public static android.view.View getActionView(android.view.MenuItem);
+    method public static boolean isActionViewExpanded(android.view.MenuItem);
+    method public static android.view.MenuItem setActionProvider(android.view.MenuItem, android.support.v4.view.ActionProvider);
+    method public static android.view.MenuItem setActionView(android.view.MenuItem, android.view.View);
+    method public static android.view.MenuItem setActionView(android.view.MenuItem, int);
+    method public static android.view.MenuItem setOnActionExpandListener(android.view.MenuItem, android.support.v4.view.MenuItemCompat.OnActionExpandListener);
+    method public static void setShowAsAction(android.view.MenuItem, int);
+    field public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
+    field public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
+    field public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
+    field public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
+    field public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
+  }
+
+  public static abstract interface MenuItemCompat.OnActionExpandListener {
+    method public abstract boolean onMenuItemActionCollapse(android.view.MenuItem);
+    method public abstract boolean onMenuItemActionExpand(android.view.MenuItem);
+  }
+
+  public final class MotionEventCompat {
+    method public static deprecated int findPointerIndex(android.view.MotionEvent, int);
+    method public static int getActionIndex(android.view.MotionEvent);
+    method public static int getActionMasked(android.view.MotionEvent);
+    method public static float getAxisValue(android.view.MotionEvent, int);
+    method public static float getAxisValue(android.view.MotionEvent, int, int);
+    method public static int getButtonState(android.view.MotionEvent);
+    method public static deprecated int getPointerCount(android.view.MotionEvent);
+    method public static deprecated int getPointerId(android.view.MotionEvent, int);
+    method public static deprecated int getSource(android.view.MotionEvent);
+    method public static deprecated float getX(android.view.MotionEvent, int);
+    method public static deprecated float getY(android.view.MotionEvent, int);
+    method public static boolean isFromSource(android.view.MotionEvent, int);
+    field public static final int ACTION_HOVER_ENTER = 9; // 0x9
+    field public static final int ACTION_HOVER_EXIT = 10; // 0xa
+    field public static final int ACTION_HOVER_MOVE = 7; // 0x7
+    field public static final int ACTION_MASK = 255; // 0xff
+    field public static final int ACTION_POINTER_DOWN = 5; // 0x5
+    field public static final int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
+    field public static final int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
+    field public static final int ACTION_POINTER_UP = 6; // 0x6
+    field public static final int ACTION_SCROLL = 8; // 0x8
+    field public static final int AXIS_BRAKE = 23; // 0x17
+    field public static final int AXIS_DISTANCE = 24; // 0x18
+    field public static final int AXIS_GAS = 22; // 0x16
+    field public static final int AXIS_GENERIC_1 = 32; // 0x20
+    field public static final int AXIS_GENERIC_10 = 41; // 0x29
+    field public static final int AXIS_GENERIC_11 = 42; // 0x2a
+    field public static final int AXIS_GENERIC_12 = 43; // 0x2b
+    field public static final int AXIS_GENERIC_13 = 44; // 0x2c
+    field public static final int AXIS_GENERIC_14 = 45; // 0x2d
+    field public static final int AXIS_GENERIC_15 = 46; // 0x2e
+    field public static final int AXIS_GENERIC_16 = 47; // 0x2f
+    field public static final int AXIS_GENERIC_2 = 33; // 0x21
+    field public static final int AXIS_GENERIC_3 = 34; // 0x22
+    field public static final int AXIS_GENERIC_4 = 35; // 0x23
+    field public static final int AXIS_GENERIC_5 = 36; // 0x24
+    field public static final int AXIS_GENERIC_6 = 37; // 0x25
+    field public static final int AXIS_GENERIC_7 = 38; // 0x26
+    field public static final int AXIS_GENERIC_8 = 39; // 0x27
+    field public static final int AXIS_GENERIC_9 = 40; // 0x28
+    field public static final int AXIS_HAT_X = 15; // 0xf
+    field public static final int AXIS_HAT_Y = 16; // 0x10
+    field public static final int AXIS_HSCROLL = 10; // 0xa
+    field public static final int AXIS_LTRIGGER = 17; // 0x11
+    field public static final int AXIS_ORIENTATION = 8; // 0x8
+    field public static final int AXIS_PRESSURE = 2; // 0x2
+    field public static final int AXIS_RELATIVE_X = 27; // 0x1b
+    field public static final int AXIS_RELATIVE_Y = 28; // 0x1c
+    field public static final int AXIS_RTRIGGER = 18; // 0x12
+    field public static final int AXIS_RUDDER = 20; // 0x14
+    field public static final int AXIS_RX = 12; // 0xc
+    field public static final int AXIS_RY = 13; // 0xd
+    field public static final int AXIS_RZ = 14; // 0xe
+    field public static final int AXIS_SIZE = 3; // 0x3
+    field public static final int AXIS_THROTTLE = 19; // 0x13
+    field public static final int AXIS_TILT = 25; // 0x19
+    field public static final int AXIS_TOOL_MAJOR = 6; // 0x6
+    field public static final int AXIS_TOOL_MINOR = 7; // 0x7
+    field public static final int AXIS_TOUCH_MAJOR = 4; // 0x4
+    field public static final int AXIS_TOUCH_MINOR = 5; // 0x5
+    field public static final int AXIS_VSCROLL = 9; // 0x9
+    field public static final int AXIS_WHEEL = 21; // 0x15
+    field public static final int AXIS_X = 0; // 0x0
+    field public static final int AXIS_Y = 1; // 0x1
+    field public static final int AXIS_Z = 11; // 0xb
+    field public static final int BUTTON_PRIMARY = 1; // 0x1
+  }
+
+  public abstract interface NestedScrollingChild {
+    method public abstract boolean dispatchNestedFling(float, float, boolean);
+    method public abstract boolean dispatchNestedPreFling(float, float);
+    method public abstract boolean dispatchNestedPreScroll(int, int, int[], int[]);
+    method public abstract boolean dispatchNestedScroll(int, int, int, int, int[]);
+    method public abstract boolean hasNestedScrollingParent();
+    method public abstract boolean isNestedScrollingEnabled();
+    method public abstract void setNestedScrollingEnabled(boolean);
+    method public abstract boolean startNestedScroll(int);
+    method public abstract void stopNestedScroll();
+  }
+
+  public class NestedScrollingChildHelper {
+    ctor public NestedScrollingChildHelper(android.view.View);
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[], int[]);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]);
+    method public boolean hasNestedScrollingParent();
+    method public boolean isNestedScrollingEnabled();
+    method public void onDetachedFromWindow();
+    method public void onStopNestedScroll(android.view.View);
+    method public void setNestedScrollingEnabled(boolean);
+    method public boolean startNestedScroll(int);
+    method public void stopNestedScroll();
+  }
+
+  public abstract interface NestedScrollingParent {
+    method public abstract int getNestedScrollAxes();
+    method public abstract boolean onNestedFling(android.view.View, float, float, boolean);
+    method public abstract boolean onNestedPreFling(android.view.View, float, float);
+    method public abstract void onNestedPreScroll(android.view.View, int, int, int[]);
+    method public abstract void onNestedScroll(android.view.View, int, int, int, int);
+    method public abstract void onNestedScrollAccepted(android.view.View, android.view.View, int);
+    method public abstract boolean onStartNestedScroll(android.view.View, android.view.View, int);
+    method public abstract void onStopNestedScroll(android.view.View);
+  }
+
+  public class NestedScrollingParentHelper {
+    ctor public NestedScrollingParentHelper(android.view.ViewGroup);
+    method public int getNestedScrollAxes();
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
+    method public void onStopNestedScroll(android.view.View);
+  }
+
+  public abstract interface OnApplyWindowInsetsListener {
+    method public abstract android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
+  }
+
+  public abstract class PagerAdapter {
+    ctor public PagerAdapter();
+    method public void destroyItem(android.view.ViewGroup, int, java.lang.Object);
+    method public deprecated void destroyItem(android.view.View, int, java.lang.Object);
+    method public void finishUpdate(android.view.ViewGroup);
+    method public deprecated void finishUpdate(android.view.View);
+    method public abstract int getCount();
+    method public int getItemPosition(java.lang.Object);
+    method public java.lang.CharSequence getPageTitle(int);
+    method public float getPageWidth(int);
+    method public java.lang.Object instantiateItem(android.view.ViewGroup, int);
+    method public deprecated java.lang.Object instantiateItem(android.view.View, int);
+    method public abstract boolean isViewFromObject(android.view.View, java.lang.Object);
+    method public void notifyDataSetChanged();
+    method public void registerDataSetObserver(android.database.DataSetObserver);
+    method public void restoreState(android.os.Parcelable, java.lang.ClassLoader);
+    method public android.os.Parcelable saveState();
+    method public void setPrimaryItem(android.view.ViewGroup, int, java.lang.Object);
+    method public deprecated void setPrimaryItem(android.view.View, int, java.lang.Object);
+    method public void startUpdate(android.view.ViewGroup);
+    method public deprecated void startUpdate(android.view.View);
+    method public void unregisterDataSetObserver(android.database.DataSetObserver);
+    field public static final int POSITION_NONE = -2; // 0xfffffffe
+    field public static final int POSITION_UNCHANGED = -1; // 0xffffffff
+  }
+
+  public class PagerTabStrip extends android.support.v4.view.PagerTitleStrip {
+    ctor public PagerTabStrip(android.content.Context);
+    ctor public PagerTabStrip(android.content.Context, android.util.AttributeSet);
+    method public boolean getDrawFullUnderline();
+    method public int getTabIndicatorColor();
+    method public void setDrawFullUnderline(boolean);
+    method public void setTabIndicatorColor(int);
+    method public void setTabIndicatorColorResource(int);
+  }
+
+  public class PagerTitleStrip extends android.view.ViewGroup {
+    ctor public PagerTitleStrip(android.content.Context);
+    ctor public PagerTitleStrip(android.content.Context, android.util.AttributeSet);
+    method public int getTextSpacing();
+    method protected void onLayout(boolean, int, int, int, int);
+    method public void setGravity(int);
+    method public void setNonPrimaryAlpha(float);
+    method public void setTextColor(int);
+    method public void setTextSize(int, float);
+    method public void setTextSpacing(int);
+  }
+
+  public final class PointerIconCompat {
+    method public static android.support.v4.view.PointerIconCompat create(android.graphics.Bitmap, float, float);
+    method public static android.support.v4.view.PointerIconCompat getSystemIcon(android.content.Context, int);
+    method public static android.support.v4.view.PointerIconCompat load(android.content.res.Resources, int);
+    field public static final int TYPE_ALIAS = 1010; // 0x3f2
+    field public static final int TYPE_ALL_SCROLL = 1013; // 0x3f5
+    field public static final int TYPE_ARROW = 1000; // 0x3e8
+    field public static final int TYPE_CELL = 1006; // 0x3ee
+    field public static final int TYPE_CONTEXT_MENU = 1001; // 0x3e9
+    field public static final int TYPE_COPY = 1011; // 0x3f3
+    field public static final int TYPE_CROSSHAIR = 1007; // 0x3ef
+    field public static final int TYPE_DEFAULT = 1000; // 0x3e8
+    field public static final int TYPE_GRAB = 1020; // 0x3fc
+    field public static final int TYPE_GRABBING = 1021; // 0x3fd
+    field public static final int TYPE_HAND = 1002; // 0x3ea
+    field public static final int TYPE_HELP = 1003; // 0x3eb
+    field public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; // 0x3f6
+    field public static final int TYPE_NO_DROP = 1012; // 0x3f4
+    field public static final int TYPE_NULL = 0; // 0x0
+    field public static final int TYPE_TEXT = 1008; // 0x3f0
+    field public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; // 0x3f9
+    field public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; // 0x3f8
+    field public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; // 0x3f7
+    field public static final int TYPE_VERTICAL_TEXT = 1009; // 0x3f1
+    field public static final int TYPE_WAIT = 1004; // 0x3ec
+    field public static final int TYPE_ZOOM_IN = 1018; // 0x3fa
+    field public static final int TYPE_ZOOM_OUT = 1019; // 0x3fb
+  }
+
+  public final class ScaleGestureDetectorCompat {
+    method public static boolean isQuickScaleEnabled(java.lang.Object);
+    method public static void setQuickScaleEnabled(java.lang.Object, boolean);
+  }
+
+  public abstract interface ScrollingView {
+    method public abstract int computeHorizontalScrollExtent();
+    method public abstract int computeHorizontalScrollOffset();
+    method public abstract int computeHorizontalScrollRange();
+    method public abstract int computeVerticalScrollExtent();
+    method public abstract int computeVerticalScrollOffset();
+    method public abstract int computeVerticalScrollRange();
+  }
+
+  public abstract interface TintableBackgroundView {
+    method public abstract android.content.res.ColorStateList getSupportBackgroundTintList();
+    method public abstract android.graphics.PorterDuff.Mode getSupportBackgroundTintMode();
+    method public abstract void setSupportBackgroundTintList(android.content.res.ColorStateList);
+    method public abstract void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode);
+  }
+
+  public final class VelocityTrackerCompat {
+    method public static float getXVelocity(android.view.VelocityTracker, int);
+    method public static float getYVelocity(android.view.VelocityTracker, int);
+  }
+
+  public class ViewCompat {
+    ctor protected ViewCompat();
+    method public static android.support.v4.view.ViewPropertyAnimatorCompat animate(android.view.View);
+    method public static boolean canScrollHorizontally(android.view.View, int);
+    method public static boolean canScrollVertically(android.view.View, int);
+    method public static int combineMeasuredStates(int, int);
+    method public static android.support.v4.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
+    method public static void dispatchFinishTemporaryDetach(android.view.View);
+    method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
+    method public static boolean dispatchNestedPreFling(android.view.View, float, float);
+    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[], int[]);
+    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]);
+    method public static void dispatchStartTemporaryDetach(android.view.View);
+    method public static int getAccessibilityLiveRegion(android.view.View);
+    method public static android.support.v4.view.accessibility.AccessibilityNodeProviderCompat getAccessibilityNodeProvider(android.view.View);
+    method public static float getAlpha(android.view.View);
+    method public static android.content.res.ColorStateList getBackgroundTintList(android.view.View);
+    method public static android.graphics.PorterDuff.Mode getBackgroundTintMode(android.view.View);
+    method public static android.graphics.Rect getClipBounds(android.view.View);
+    method public static android.view.Display getDisplay(android.view.View);
+    method public static float getElevation(android.view.View);
+    method public static boolean getFitsSystemWindows(android.view.View);
+    method public static int getImportantForAccessibility(android.view.View);
+    method public static int getLabelFor(android.view.View);
+    method public static int getLayerType(android.view.View);
+    method public static int getLayoutDirection(android.view.View);
+    method public static android.graphics.Matrix getMatrix(android.view.View);
+    method public static int getMeasuredHeightAndState(android.view.View);
+    method public static int getMeasuredState(android.view.View);
+    method public static int getMeasuredWidthAndState(android.view.View);
+    method public static int getMinimumHeight(android.view.View);
+    method public static int getMinimumWidth(android.view.View);
+    method public static deprecated int getOverScrollMode(android.view.View);
+    method public static int getPaddingEnd(android.view.View);
+    method public static int getPaddingStart(android.view.View);
+    method public static android.view.ViewParent getParentForAccessibility(android.view.View);
+    method public static float getPivotX(android.view.View);
+    method public static float getPivotY(android.view.View);
+    method public static float getRotation(android.view.View);
+    method public static float getRotationX(android.view.View);
+    method public static float getRotationY(android.view.View);
+    method public static float getScaleX(android.view.View);
+    method public static float getScaleY(android.view.View);
+    method public static int getScrollIndicators(android.view.View);
+    method public static java.lang.String getTransitionName(android.view.View);
+    method public static float getTranslationX(android.view.View);
+    method public static float getTranslationY(android.view.View);
+    method public static float getTranslationZ(android.view.View);
+    method public static int getWindowSystemUiVisibility(android.view.View);
+    method public static float getX(android.view.View);
+    method public static float getY(android.view.View);
+    method public static float getZ(android.view.View);
+    method public static boolean hasAccessibilityDelegate(android.view.View);
+    method public static boolean hasNestedScrollingParent(android.view.View);
+    method public static boolean hasOnClickListeners(android.view.View);
+    method public static boolean hasOverlappingRendering(android.view.View);
+    method public static boolean hasTransientState(android.view.View);
+    method public static boolean isAttachedToWindow(android.view.View);
+    method public static boolean isImportantForAccessibility(android.view.View);
+    method public static boolean isInLayout(android.view.View);
+    method public static boolean isLaidOut(android.view.View);
+    method public static boolean isLayoutDirectionResolved(android.view.View);
+    method public static boolean isNestedScrollingEnabled(android.view.View);
+    method public static deprecated boolean isOpaque(android.view.View);
+    method public static boolean isPaddingRelative(android.view.View);
+    method public static void jumpDrawablesToCurrentState(android.view.View);
+    method public static void offsetLeftAndRight(android.view.View, int);
+    method public static void offsetTopAndBottom(android.view.View, int);
+    method public static android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
+    method public static void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public static void onInitializeAccessibilityNodeInfo(android.view.View, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+    method public static void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle);
+    method public static void postInvalidateOnAnimation(android.view.View);
+    method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
+    method public static void postOnAnimation(android.view.View, java.lang.Runnable);
+    method public static void postOnAnimationDelayed(android.view.View, java.lang.Runnable, long);
+    method public static void requestApplyInsets(android.view.View);
+    method public static int resolveSizeAndState(int, int, int);
+    method public static void setAccessibilityDelegate(android.view.View, android.support.v4.view.AccessibilityDelegateCompat);
+    method public static void setAccessibilityLiveRegion(android.view.View, int);
+    method public static void setActivated(android.view.View, boolean);
+    method public static void setAlpha(android.view.View, float);
+    method public static void setBackground(android.view.View, android.graphics.drawable.Drawable);
+    method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList);
+    method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode);
+    method public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup, boolean);
+    method public static void setClipBounds(android.view.View, android.graphics.Rect);
+    method public static void setElevation(android.view.View, float);
+    method public static void setFitsSystemWindows(android.view.View, boolean);
+    method public static void setHasTransientState(android.view.View, boolean);
+    method public static void setImportantForAccessibility(android.view.View, int);
+    method public static void setLabelFor(android.view.View, int);
+    method public static void setLayerPaint(android.view.View, android.graphics.Paint);
+    method public static void setLayerType(android.view.View, int, android.graphics.Paint);
+    method public static void setLayoutDirection(android.view.View, int);
+    method public static void setNestedScrollingEnabled(android.view.View, boolean);
+    method public static void setOnApplyWindowInsetsListener(android.view.View, android.support.v4.view.OnApplyWindowInsetsListener);
+    method public static deprecated void setOverScrollMode(android.view.View, int);
+    method public static void setPaddingRelative(android.view.View, int, int, int, int);
+    method public static void setPivotX(android.view.View, float);
+    method public static void setPivotY(android.view.View, float);
+    method public static void setPointerIcon(android.view.View, android.support.v4.view.PointerIconCompat);
+    method public static void setRotation(android.view.View, float);
+    method public static void setRotationX(android.view.View, float);
+    method public static void setRotationY(android.view.View, float);
+    method public static void setSaveFromParentEnabled(android.view.View, boolean);
+    method public static void setScaleX(android.view.View, float);
+    method public static void setScaleY(android.view.View, float);
+    method public static void setScrollIndicators(android.view.View, int);
+    method public static void setScrollIndicators(android.view.View, int, int);
+    method public static void setTransitionName(android.view.View, java.lang.String);
+    method public static void setTranslationX(android.view.View, float);
+    method public static void setTranslationY(android.view.View, float);
+    method public static void setTranslationZ(android.view.View, float);
+    method public static void setX(android.view.View, float);
+    method public static void setY(android.view.View, float);
+    method public static void setZ(android.view.View, float);
+    method public static boolean startNestedScroll(android.view.View, int);
+    method public static void stopNestedScroll(android.view.View);
+    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
+    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
+    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
+    field public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
+    field public static final int LAYER_TYPE_NONE = 0; // 0x0
+    field public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
+    field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
+    field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
+    field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
+    field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
+    field public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
+    field public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
+    field public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
+    field public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
+    field public static final deprecated int OVER_SCROLL_ALWAYS = 0; // 0x0
+    field public static final deprecated int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
+    field public static final deprecated int OVER_SCROLL_NEVER = 2; // 0x2
+    field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
+    field public static final int SCROLL_AXIS_NONE = 0; // 0x0
+    field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_END = 32; // 0x20
+    field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
+    field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
+    field public static final int SCROLL_INDICATOR_START = 16; // 0x10
+    field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
+  }
+
+  public final class ViewConfigurationCompat {
+    method public static deprecated int getScaledPagingTouchSlop(android.view.ViewConfiguration);
+    method public static boolean hasPermanentMenuKey(android.view.ViewConfiguration);
+  }
+
+  public final class ViewGroupCompat {
+    method public static int getLayoutMode(android.view.ViewGroup);
+    method public static int getNestedScrollAxes(android.view.ViewGroup);
+    method public static boolean isTransitionGroup(android.view.ViewGroup);
+    method public static boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public static void setLayoutMode(android.view.ViewGroup, int);
+    method public static void setMotionEventSplittingEnabled(android.view.ViewGroup, boolean);
+    method public static void setTransitionGroup(android.view.ViewGroup, boolean);
+    field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
+    field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
+  }
+
+  public class ViewPager extends android.view.ViewGroup {
+    ctor public ViewPager(android.content.Context);
+    ctor public ViewPager(android.content.Context, android.util.AttributeSet);
+    method public void addOnAdapterChangeListener(android.support.v4.view.ViewPager.OnAdapterChangeListener);
+    method public void addOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener);
+    method public boolean arrowScroll(int);
+    method public boolean beginFakeDrag();
+    method protected boolean canScroll(android.view.View, boolean, int, int, int);
+    method public void clearOnPageChangeListeners();
+    method public void endFakeDrag();
+    method public boolean executeKeyEvent(android.view.KeyEvent);
+    method public void fakeDragBy(float);
+    method public android.support.v4.view.PagerAdapter getAdapter();
+    method public int getCurrentItem();
+    method public int getOffscreenPageLimit();
+    method public int getPageMargin();
+    method public boolean isFakeDragging();
+    method protected void onLayout(boolean, int, int, int, int);
+    method protected void onPageScrolled(int, float, int);
+    method public void onRestoreInstanceState(android.os.Parcelable);
+    method public android.os.Parcelable onSaveInstanceState();
+    method public void removeOnAdapterChangeListener(android.support.v4.view.ViewPager.OnAdapterChangeListener);
+    method public void removeOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener);
+    method public void setAdapter(android.support.v4.view.PagerAdapter);
+    method public void setCurrentItem(int);
+    method public void setCurrentItem(int, boolean);
+    method public void setOffscreenPageLimit(int);
+    method public deprecated void setOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener);
+    method public void setPageMargin(int);
+    method public void setPageMarginDrawable(android.graphics.drawable.Drawable);
+    method public void setPageMarginDrawable(int);
+    method public void setPageTransformer(boolean, android.support.v4.view.ViewPager.PageTransformer);
+    method public void setPageTransformer(boolean, android.support.v4.view.ViewPager.PageTransformer, int);
+    field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+    field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+    field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+  }
+
+  public static abstract class ViewPager.DecorView implements java.lang.annotation.Annotation {
+  }
+
+  public static class ViewPager.LayoutParams extends android.view.ViewGroup.LayoutParams {
+    ctor public ViewPager.LayoutParams();
+    ctor public ViewPager.LayoutParams(android.content.Context, android.util.AttributeSet);
+    field public int gravity;
+    field public boolean isDecor;
+  }
+
+  public static abstract interface ViewPager.OnAdapterChangeListener {
+    method public abstract void onAdapterChanged(android.support.v4.view.ViewPager, android.support.v4.view.PagerAdapter, android.support.v4.view.PagerAdapter);
+  }
+
+  public static abstract interface ViewPager.OnPageChangeListener {
+    method public abstract void onPageScrollStateChanged(int);
+    method public abstract void onPageScrolled(int, float, int);
+    method public abstract void onPageSelected(int);
+  }
+
+  public static abstract interface ViewPager.PageTransformer {
+    method public abstract void transformPage(android.view.View, float);
+  }
+
+  public static class ViewPager.SavedState extends android.support.v4.view.AbsSavedState {
+    ctor public ViewPager.SavedState(android.os.Parcelable);
+    field public static final android.os.Parcelable.Creator<android.support.v4.view.ViewPager.SavedState> CREATOR;
+  }
+
+  public static class ViewPager.SimpleOnPageChangeListener implements android.support.v4.view.ViewPager.OnPageChangeListener {
+    ctor public ViewPager.SimpleOnPageChangeListener();
+    method public void onPageScrollStateChanged(int);
+    method public void onPageScrolled(int, float, int);
+    method public void onPageSelected(int);
+  }
+
+  public final class ViewParentCompat {
+    method public static void notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean);
+    method public static boolean onNestedPreFling(android.view.ViewParent, android.view.View, float, float);
+    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int);
+    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View);
+    method public static boolean requestSendAccessibilityEvent(android.view.ViewParent, android.view.View, android.view.accessibility.AccessibilityEvent);
+  }
+
+  public final class ViewPropertyAnimatorCompat {
+    method public android.support.v4.view.ViewPropertyAnimatorCompat alpha(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat alphaBy(float);
+    method public void cancel();
+    method public long getDuration();
+    method public android.view.animation.Interpolator getInterpolator();
+    method public long getStartDelay();
+    method public android.support.v4.view.ViewPropertyAnimatorCompat rotation(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat rotationBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat rotationX(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat rotationXBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat rotationY(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat rotationYBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat scaleX(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat scaleXBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat scaleY(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat scaleYBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat setDuration(long);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat setInterpolator(android.view.animation.Interpolator);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat setListener(android.support.v4.view.ViewPropertyAnimatorListener);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat setStartDelay(long);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat setUpdateListener(android.support.v4.view.ViewPropertyAnimatorUpdateListener);
+    method public void start();
+    method public android.support.v4.view.ViewPropertyAnimatorCompat translationX(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat translationXBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat translationY(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat translationYBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat translationZ(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat translationZBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat withEndAction(java.lang.Runnable);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat withLayer();
+    method public android.support.v4.view.ViewPropertyAnimatorCompat withStartAction(java.lang.Runnable);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat x(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat xBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat y(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat yBy(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat z(float);
+    method public android.support.v4.view.ViewPropertyAnimatorCompat zBy(float);
+  }
+
+  public abstract interface ViewPropertyAnimatorListener {
+    method public abstract void onAnimationCancel(android.view.View);
+    method public abstract void onAnimationEnd(android.view.View);
+    method public abstract void onAnimationStart(android.view.View);
+  }
+
+  public class ViewPropertyAnimatorListenerAdapter implements android.support.v4.view.ViewPropertyAnimatorListener {
+    ctor public ViewPropertyAnimatorListenerAdapter();
+    method public void onAnimationCancel(android.view.View);
+    method public void onAnimationEnd(android.view.View);
+    method public void onAnimationStart(android.view.View);
+  }
+
+  public abstract interface ViewPropertyAnimatorUpdateListener {
+    method public abstract void onAnimationUpdate(android.view.View);
+  }
+
+  public final class WindowCompat {
+    field public static final int FEATURE_ACTION_BAR = 8; // 0x8
+    field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
+    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+  }
+
+  public class WindowInsetsCompat {
+    ctor public WindowInsetsCompat(android.support.v4.view.WindowInsetsCompat);
+    method public android.support.v4.view.WindowInsetsCompat consumeStableInsets();
+    method public android.support.v4.view.WindowInsetsCompat consumeSystemWindowInsets();
+    method public int getStableInsetBottom();
+    method public int getStableInsetLeft();
+    method public int getStableInsetRight();
+    method public int getStableInsetTop();
+    method public int getSystemWindowInsetBottom();
+    method public int getSystemWindowInsetLeft();
+    method public int getSystemWindowInsetRight();
+    method public int getSystemWindowInsetTop();
+    method public boolean hasInsets();
+    method public boolean hasStableInsets();
+    method public boolean hasSystemWindowInsets();
+    method public boolean isConsumed();
+    method public boolean isRound();
+    method public android.support.v4.view.WindowInsetsCompat replaceSystemWindowInsets(int, int, int, int);
+    method public android.support.v4.view.WindowInsetsCompat replaceSystemWindowInsets(android.graphics.Rect);
+  }
+
+}
+
+package android.support.v4.view.accessibility {
+
+  public final class AccessibilityEventCompat {
+    method public static void appendRecord(android.view.accessibility.AccessibilityEvent, android.support.v4.view.accessibility.AccessibilityRecordCompat);
+    method public static android.support.v4.view.accessibility.AccessibilityRecordCompat asRecord(android.view.accessibility.AccessibilityEvent);
+    method public int getAction(android.view.accessibility.AccessibilityEvent);
+    method public static int getContentChangeTypes(android.view.accessibility.AccessibilityEvent);
+    method public int getMovementGranularity(android.view.accessibility.AccessibilityEvent);
+    method public static android.support.v4.view.accessibility.AccessibilityRecordCompat getRecord(android.view.accessibility.AccessibilityEvent, int);
+    method public static int getRecordCount(android.view.accessibility.AccessibilityEvent);
+    method public void setAction(android.view.accessibility.AccessibilityEvent, int);
+    method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int);
+    method public void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
+    field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
+    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
+    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
+    field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+    field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+    field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
+    field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
+    field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
+    field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
+    field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
+    field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000
+    field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000
+    field public static final int TYPE_VIEW_CONTEXT_CLICKED = 8388608; // 0x800000
+    field public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
+    field public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
+    field public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
+    field public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
+    field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
+    field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
+    field public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
+  }
+
+  public final class AccessibilityManagerCompat {
+    method public static boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener);
+    method public static boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+    method public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager, int);
+    method public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager);
+    method public static boolean isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager);
+    method public static boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener);
+    method public static boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+  }
+
+  public static abstract interface AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    method public abstract void onAccessibilityStateChanged(boolean);
+  }
+
+  public static abstract deprecated class AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat implements android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    ctor public AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat();
+  }
+
+  public static abstract interface AccessibilityManagerCompat.TouchExplorationStateChangeListener {
+    method public abstract void onTouchExplorationStateChanged(boolean);
+  }
+
+  public class AccessibilityNodeInfoCompat {
+    ctor public AccessibilityNodeInfoCompat(java.lang.Object);
+    method public void addAction(int);
+    method public void addAction(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat);
+    method public void addChild(android.view.View);
+    method public void addChild(android.view.View, int);
+    method public boolean canOpenPopup();
+    method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(java.lang.String);
+    method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByViewId(java.lang.String);
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat findFocus(int);
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat focusSearch(int);
+    method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat> getActionList();
+    method public int getActions();
+    method public void getBoundsInParent(android.graphics.Rect);
+    method public void getBoundsInScreen(android.graphics.Rect);
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getChild(int);
+    method public int getChildCount();
+    method public java.lang.CharSequence getClassName();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat getCollectionInfo();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat getCollectionItemInfo();
+    method public java.lang.CharSequence getContentDescription();
+    method public int getDrawingOrder();
+    method public java.lang.CharSequence getError();
+    method public android.os.Bundle getExtras();
+    method public java.lang.Object getInfo();
+    method public int getInputType();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getLabelFor();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getLabeledBy();
+    method public int getLiveRegion();
+    method public int getMaxTextLength();
+    method public int getMovementGranularities();
+    method public java.lang.CharSequence getPackageName();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getParent();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat getRangeInfo();
+    method public java.lang.CharSequence getRoleDescription();
+    method public java.lang.CharSequence getText();
+    method public int getTextSelectionEnd();
+    method public int getTextSelectionStart();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getTraversalAfter();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getTraversalBefore();
+    method public java.lang.String getViewIdResourceName();
+    method public android.support.v4.view.accessibility.AccessibilityWindowInfoCompat getWindow();
+    method public int getWindowId();
+    method public boolean isAccessibilityFocused();
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isClickable();
+    method public boolean isContentInvalid();
+    method public boolean isContextClickable();
+    method public boolean isDismissable();
+    method public boolean isEditable();
+    method public boolean isEnabled();
+    method public boolean isFocusable();
+    method public boolean isFocused();
+    method public boolean isImportantForAccessibility();
+    method public boolean isLongClickable();
+    method public boolean isMultiLine();
+    method public boolean isPassword();
+    method public boolean isScrollable();
+    method public boolean isSelected();
+    method public boolean isVisibleToUser();
+    method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain(android.view.View);
+    method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain(android.view.View, int);
+    method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain();
+    method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+    method public boolean performAction(int);
+    method public boolean performAction(int, android.os.Bundle);
+    method public void recycle();
+    method public boolean refresh();
+    method public boolean removeAction(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat);
+    method public boolean removeChild(android.view.View);
+    method public boolean removeChild(android.view.View, int);
+    method public void setAccessibilityFocused(boolean);
+    method public void setBoundsInParent(android.graphics.Rect);
+    method public void setBoundsInScreen(android.graphics.Rect);
+    method public void setCanOpenPopup(boolean);
+    method public void setCheckable(boolean);
+    method public void setChecked(boolean);
+    method public void setClassName(java.lang.CharSequence);
+    method public void setClickable(boolean);
+    method public void setCollectionInfo(java.lang.Object);
+    method public void setCollectionItemInfo(java.lang.Object);
+    method public void setContentDescription(java.lang.CharSequence);
+    method public void setContentInvalid(boolean);
+    method public void setContextClickable(boolean);
+    method public void setDismissable(boolean);
+    method public void setDrawingOrder(int);
+    method public void setEditable(boolean);
+    method public void setEnabled(boolean);
+    method public void setError(java.lang.CharSequence);
+    method public void setFocusable(boolean);
+    method public void setFocused(boolean);
+    method public void setImportantForAccessibility(boolean);
+    method public void setInputType(int);
+    method public void setLabelFor(android.view.View);
+    method public void setLabelFor(android.view.View, int);
+    method public void setLabeledBy(android.view.View);
+    method public void setLabeledBy(android.view.View, int);
+    method public void setLiveRegion(int);
+    method public void setLongClickable(boolean);
+    method public void setMaxTextLength(int);
+    method public void setMovementGranularities(int);
+    method public void setMultiLine(boolean);
+    method public void setPackageName(java.lang.CharSequence);
+    method public void setParent(android.view.View);
+    method public void setParent(android.view.View, int);
+    method public void setPassword(boolean);
+    method public void setRangeInfo(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat);
+    method public void setRoleDescription(java.lang.CharSequence);
+    method public void setScrollable(boolean);
+    method public void setSelected(boolean);
+    method public void setSource(android.view.View);
+    method public void setSource(android.view.View, int);
+    method public void setText(java.lang.CharSequence);
+    method public void setTextSelection(int, int);
+    method public void setTraversalAfter(android.view.View);
+    method public void setTraversalAfter(android.view.View, int);
+    method public void setTraversalBefore(android.view.View);
+    method public void setTraversalBefore(android.view.View, int);
+    method public void setViewIdResourceName(java.lang.String);
+    method public void setVisibleToUser(boolean);
+    field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
+    field public static final java.lang.String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
+    field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
+    field public static final java.lang.String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
+    field public static final java.lang.String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+    field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
+    field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
+    field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
+    field public static final int ACTION_CLICK = 16; // 0x10
+    field public static final int ACTION_COLLAPSE = 524288; // 0x80000
+    field public static final int ACTION_COPY = 16384; // 0x4000
+    field public static final int ACTION_CUT = 65536; // 0x10000
+    field public static final int ACTION_DISMISS = 1048576; // 0x100000
+    field public static final int ACTION_EXPAND = 262144; // 0x40000
+    field public static final int ACTION_FOCUS = 1; // 0x1
+    field public static final int ACTION_LONG_CLICK = 32; // 0x20
+    field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
+    field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
+    field public static final int ACTION_PASTE = 32768; // 0x8000
+    field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
+    field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
+    field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
+    field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
+    field public static final int ACTION_SELECT = 4; // 0x4
+    field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
+    field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
+    field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
+    field public static final int FOCUS_INPUT = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
+    field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
+    field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
+    field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
+  }
+
+  public static class AccessibilityNodeInfoCompat.AccessibilityActionCompat {
+    ctor public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, java.lang.CharSequence);
+    method public int getId();
+    method public java.lang.CharSequence getLabel();
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_ACCESSIBILITY_FOCUS;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLEAR_FOCUS;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLEAR_SELECTION;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLICK;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_COLLAPSE;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CONTEXT_CLICK;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_COPY;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CUT;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DISMISS;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_EXPAND;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_FOCUS;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_LONG_CLICK;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_NEXT_HTML_ELEMENT;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PASTE;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PREVIOUS_HTML_ELEMENT;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_BACKWARD;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_DOWN;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_FORWARD;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_LEFT;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_RIGHT;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_TO_POSITION;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_UP;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SELECT;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SET_PROGRESS;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SET_SELECTION;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SET_TEXT;
+    field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SHOW_ON_SCREEN;
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionInfoCompat {
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public int getSelectionMode();
+    method public boolean isHierarchical();
+    method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat obtain(int, int, boolean, int);
+    method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat obtain(int, int, boolean);
+    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+    field public static final int SELECTION_MODE_NONE = 0; // 0x0
+    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionItemInfoCompat {
+    method public int getColumnIndex();
+    method public int getColumnSpan();
+    method public int getRowIndex();
+    method public int getRowSpan();
+    method public boolean isHeading();
+    method public boolean isSelected();
+    method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat obtain(int, int, int, int, boolean, boolean);
+    method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat obtain(int, int, int, int, boolean);
+  }
+
+  public static class AccessibilityNodeInfoCompat.RangeInfoCompat {
+    method public float getCurrent();
+    method public float getMax();
+    method public float getMin();
+    method public int getType();
+    method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat obtain(int, float, float, float);
+    field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
+    field public static final int RANGE_TYPE_INT = 0; // 0x0
+    field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
+  }
+
+  public class AccessibilityNodeProviderCompat {
+    ctor public AccessibilityNodeProviderCompat();
+    ctor public AccessibilityNodeProviderCompat(java.lang.Object);
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int);
+    method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(java.lang.String, int);
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat findFocus(int);
+    method public java.lang.Object getProvider();
+    method public boolean performAction(int, int, android.os.Bundle);
+    field public static final int HOST_VIEW_ID = -1; // 0xffffffff
+  }
+
+  public class AccessibilityRecordCompat {
+    ctor public deprecated AccessibilityRecordCompat(java.lang.Object);
+    method public int getAddedCount();
+    method public java.lang.CharSequence getBeforeText();
+    method public java.lang.CharSequence getClassName();
+    method public java.lang.CharSequence getContentDescription();
+    method public int getCurrentItemIndex();
+    method public int getFromIndex();
+    method public deprecated java.lang.Object getImpl();
+    method public int getItemCount();
+    method public int getMaxScrollX();
+    method public int getMaxScrollY();
+    method public android.os.Parcelable getParcelableData();
+    method public int getRemovedCount();
+    method public int getScrollX();
+    method public int getScrollY();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getSource();
+    method public java.util.List<java.lang.CharSequence> getText();
+    method public int getToIndex();
+    method public int getWindowId();
+    method public boolean isChecked();
+    method public boolean isEnabled();
+    method public boolean isFullScreen();
+    method public boolean isPassword();
+    method public boolean isScrollable();
+    method public static android.support.v4.view.accessibility.AccessibilityRecordCompat obtain(android.support.v4.view.accessibility.AccessibilityRecordCompat);
+    method public static android.support.v4.view.accessibility.AccessibilityRecordCompat obtain();
+    method public void recycle();
+    method public void setAddedCount(int);
+    method public void setBeforeText(java.lang.CharSequence);
+    method public void setChecked(boolean);
+    method public void setClassName(java.lang.CharSequence);
+    method public void setContentDescription(java.lang.CharSequence);
+    method public void setCurrentItemIndex(int);
+    method public void setEnabled(boolean);
+    method public void setFromIndex(int);
+    method public void setFullScreen(boolean);
+    method public void setItemCount(int);
+    method public void setMaxScrollX(int);
+    method public void setMaxScrollY(int);
+    method public void setParcelableData(android.os.Parcelable);
+    method public void setPassword(boolean);
+    method public void setRemovedCount(int);
+    method public void setScrollX(int);
+    method public void setScrollY(int);
+    method public void setScrollable(boolean);
+    method public void setSource(android.view.View);
+    method public void setSource(android.view.View, int);
+    method public void setToIndex(int);
+  }
+
+  public class AccessibilityWindowInfoCompat {
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getAnchor();
+    method public void getBoundsInScreen(android.graphics.Rect);
+    method public android.support.v4.view.accessibility.AccessibilityWindowInfoCompat getChild(int);
+    method public int getChildCount();
+    method public int getId();
+    method public int getLayer();
+    method public android.support.v4.view.accessibility.AccessibilityWindowInfoCompat getParent();
+    method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getRoot();
+    method public java.lang.CharSequence getTitle();
+    method public int getType();
+    method public boolean isAccessibilityFocused();
+    method public boolean isActive();
+    method public boolean isFocused();
+    method public static android.support.v4.view.accessibility.AccessibilityWindowInfoCompat obtain();
+    method public static android.support.v4.view.accessibility.AccessibilityWindowInfoCompat obtain(android.support.v4.view.accessibility.AccessibilityWindowInfoCompat);
+    method public void recycle();
+    field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
+    field public static final int TYPE_APPLICATION = 1; // 0x1
+    field public static final int TYPE_INPUT_METHOD = 2; // 0x2
+    field public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5; // 0x5
+    field public static final int TYPE_SYSTEM = 3; // 0x3
+  }
+
+}
+
+package android.support.v4.view.animation {
+
+  public class FastOutLinearInInterpolator extends android.support.v4.view.animation.LookupTableInterpolator {
+    ctor public FastOutLinearInInterpolator();
+  }
+
+  public class FastOutSlowInInterpolator extends android.support.v4.view.animation.LookupTableInterpolator {
+    ctor public FastOutSlowInInterpolator();
+  }
+
+  public class LinearOutSlowInInterpolator extends android.support.v4.view.animation.LookupTableInterpolator {
+    ctor public LinearOutSlowInInterpolator();
+  }
+
+   abstract class LookupTableInterpolator implements android.view.animation.Interpolator {
+    ctor public LookupTableInterpolator(float[]);
+    method public float getInterpolation(float);
+  }
+
+  public final class PathInterpolatorCompat {
+    method public static android.view.animation.Interpolator create(android.graphics.Path);
+    method public static android.view.animation.Interpolator create(float, float);
+    method public static android.view.animation.Interpolator create(float, float, float, float);
+  }
+
+}
+
+package android.support.v4.widget {
+
+  public abstract class AutoScrollHelper implements android.view.View.OnTouchListener {
+    ctor public AutoScrollHelper(android.view.View);
+    method public abstract boolean canTargetScrollHorizontally(int);
+    method public abstract boolean canTargetScrollVertically(int);
+    method public boolean isEnabled();
+    method public boolean isExclusive();
+    method public boolean onTouch(android.view.View, android.view.MotionEvent);
+    method public abstract void scrollTargetBy(int, int);
+    method public android.support.v4.widget.AutoScrollHelper setActivationDelay(int);
+    method public android.support.v4.widget.AutoScrollHelper setEdgeType(int);
+    method public android.support.v4.widget.AutoScrollHelper setEnabled(boolean);
+    method public android.support.v4.widget.AutoScrollHelper setExclusive(boolean);
+    method public android.support.v4.widget.AutoScrollHelper setMaximumEdges(float, float);
+    method public android.support.v4.widget.AutoScrollHelper setMaximumVelocity(float, float);
+    method public android.support.v4.widget.AutoScrollHelper setMinimumVelocity(float, float);
+    method public android.support.v4.widget.AutoScrollHelper setRampDownDuration(int);
+    method public android.support.v4.widget.AutoScrollHelper setRampUpDuration(int);
+    method public android.support.v4.widget.AutoScrollHelper setRelativeEdges(float, float);
+    method public android.support.v4.widget.AutoScrollHelper setRelativeVelocity(float, float);
+    field public static final int EDGE_TYPE_INSIDE = 0; // 0x0
+    field public static final int EDGE_TYPE_INSIDE_EXTEND = 1; // 0x1
+    field public static final int EDGE_TYPE_OUTSIDE = 2; // 0x2
+    field public static final float NO_MAX = 3.4028235E38f;
+    field public static final float NO_MIN = 0.0f;
+    field public static final float RELATIVE_UNSPECIFIED = 0.0f;
+  }
+
+  public final class CompoundButtonCompat {
+    method public static android.graphics.drawable.Drawable getButtonDrawable(android.widget.CompoundButton);
+    method public static android.content.res.ColorStateList getButtonTintList(android.widget.CompoundButton);
+    method public static android.graphics.PorterDuff.Mode getButtonTintMode(android.widget.CompoundButton);
+    method public static void setButtonTintList(android.widget.CompoundButton, android.content.res.ColorStateList);
+    method public static void setButtonTintMode(android.widget.CompoundButton, android.graphics.PorterDuff.Mode);
+  }
+
+  public class ContentLoadingProgressBar extends android.widget.ProgressBar {
+    ctor public ContentLoadingProgressBar(android.content.Context);
+    ctor public ContentLoadingProgressBar(android.content.Context, android.util.AttributeSet);
+    method public void hide();
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
+    method public void show();
+  }
+
+  public abstract class CursorAdapter extends android.widget.BaseAdapter {
+    ctor public deprecated CursorAdapter(android.content.Context, android.database.Cursor);
+    ctor public CursorAdapter(android.content.Context, android.database.Cursor, boolean);
+    ctor public CursorAdapter(android.content.Context, android.database.Cursor, int);
+    method public abstract void bindView(android.view.View, android.content.Context, android.database.Cursor);
+    method public void changeCursor(android.database.Cursor);
+    method public java.lang.CharSequence convertToString(android.database.Cursor);
+    method public int getCount();
+    method public android.database.Cursor getCursor();
+    method public android.widget.Filter getFilter();
+    method public android.widget.FilterQueryProvider getFilterQueryProvider();
+    method public java.lang.Object getItem(int);
+    method public long getItemId(int);
+    method public android.view.View getView(int, android.view.View, android.view.ViewGroup);
+    method protected deprecated void init(android.content.Context, android.database.Cursor, boolean);
+    method public android.view.View newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup);
+    method public abstract android.view.View newView(android.content.Context, android.database.Cursor, android.view.ViewGroup);
+    method protected void onContentChanged();
+    method public android.database.Cursor runQueryOnBackgroundThread(java.lang.CharSequence);
+    method public void setFilterQueryProvider(android.widget.FilterQueryProvider);
+    method public android.database.Cursor swapCursor(android.database.Cursor);
+    field public static final deprecated int FLAG_AUTO_REQUERY = 1; // 0x1
+    field public static final int FLAG_REGISTER_CONTENT_OBSERVER = 2; // 0x2
+  }
+
+  public class DrawerLayout extends android.view.ViewGroup {
+    ctor public DrawerLayout(android.content.Context);
+    ctor public DrawerLayout(android.content.Context, android.util.AttributeSet);
+    ctor public DrawerLayout(android.content.Context, android.util.AttributeSet, int);
+    method public void addDrawerListener(android.support.v4.widget.DrawerLayout.DrawerListener);
+    method public void closeDrawer(android.view.View);
+    method public void closeDrawer(android.view.View, boolean);
+    method public void closeDrawer(int);
+    method public void closeDrawer(int, boolean);
+    method public void closeDrawers();
+    method public float getDrawerElevation();
+    method public int getDrawerLockMode(int);
+    method public int getDrawerLockMode(android.view.View);
+    method public java.lang.CharSequence getDrawerTitle(int);
+    method public android.graphics.drawable.Drawable getStatusBarBackgroundDrawable();
+    method public boolean isDrawerOpen(android.view.View);
+    method public boolean isDrawerOpen(int);
+    method public boolean isDrawerVisible(android.view.View);
+    method public boolean isDrawerVisible(int);
+    method public void onDraw(android.graphics.Canvas);
+    method protected void onLayout(boolean, int, int, int, int);
+    method public void openDrawer(android.view.View);
+    method public void openDrawer(android.view.View, boolean);
+    method public void openDrawer(int);
+    method public void openDrawer(int, boolean);
+    method public void removeDrawerListener(android.support.v4.widget.DrawerLayout.DrawerListener);
+    method public void setDrawerElevation(float);
+    method public deprecated void setDrawerListener(android.support.v4.widget.DrawerLayout.DrawerListener);
+    method public void setDrawerLockMode(int);
+    method public void setDrawerLockMode(int, int);
+    method public void setDrawerLockMode(int, android.view.View);
+    method public void setDrawerShadow(android.graphics.drawable.Drawable, int);
+    method public void setDrawerShadow(int, int);
+    method public void setDrawerTitle(int, java.lang.CharSequence);
+    method public void setScrimColor(int);
+    method public void setStatusBarBackground(android.graphics.drawable.Drawable);
+    method public void setStatusBarBackground(int);
+    method public void setStatusBarBackgroundColor(int);
+    field public static final int LOCK_MODE_LOCKED_CLOSED = 1; // 0x1
+    field public static final int LOCK_MODE_LOCKED_OPEN = 2; // 0x2
+    field public static final int LOCK_MODE_UNDEFINED = 3; // 0x3
+    field public static final int LOCK_MODE_UNLOCKED = 0; // 0x0
+    field public static final int STATE_DRAGGING = 1; // 0x1
+    field public static final int STATE_IDLE = 0; // 0x0
+    field public static final int STATE_SETTLING = 2; // 0x2
+  }
+
+  public static abstract interface DrawerLayout.DrawerListener {
+    method public abstract void onDrawerClosed(android.view.View);
+    method public abstract void onDrawerOpened(android.view.View);
+    method public abstract void onDrawerSlide(android.view.View, float);
+    method public abstract void onDrawerStateChanged(int);
+  }
+
+  public static class DrawerLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public DrawerLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public DrawerLayout.LayoutParams(int, int);
+    ctor public DrawerLayout.LayoutParams(int, int, int);
+    ctor public DrawerLayout.LayoutParams(android.support.v4.widget.DrawerLayout.LayoutParams);
+    ctor public DrawerLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public DrawerLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    field public int gravity;
+  }
+
+  protected static class DrawerLayout.SavedState extends android.support.v4.view.AbsSavedState {
+    ctor public DrawerLayout.SavedState(android.os.Parcel, java.lang.ClassLoader);
+    ctor public DrawerLayout.SavedState(android.os.Parcelable);
+    field public static final android.os.Parcelable.Creator<android.support.v4.widget.DrawerLayout.SavedState> CREATOR;
+  }
+
+  public static abstract class DrawerLayout.SimpleDrawerListener implements android.support.v4.widget.DrawerLayout.DrawerListener {
+    ctor public DrawerLayout.SimpleDrawerListener();
+    method public void onDrawerClosed(android.view.View);
+    method public void onDrawerOpened(android.view.View);
+    method public void onDrawerSlide(android.view.View, float);
+    method public void onDrawerStateChanged(int);
+  }
+
+  public final class EdgeEffectCompat {
+    ctor public EdgeEffectCompat(android.content.Context);
+    method public boolean draw(android.graphics.Canvas);
+    method public void finish();
+    method public boolean isFinished();
+    method public boolean onAbsorb(int);
+    method public deprecated boolean onPull(float);
+    method public boolean onPull(float, float);
+    method public boolean onRelease();
+    method public void setSize(int, int);
+  }
+
+  public abstract class ExploreByTouchHelper extends android.support.v4.view.AccessibilityDelegateCompat {
+    ctor public ExploreByTouchHelper(android.view.View);
+    method public final boolean clearKeyboardFocusForVirtualView(int);
+    method public final boolean dispatchHoverEvent(android.view.MotionEvent);
+    method public final boolean dispatchKeyEvent(android.view.KeyEvent);
+    method public final int getAccessibilityFocusedVirtualViewId();
+    method public deprecated int getFocusedVirtualView();
+    method public final int getKeyboardFocusedVirtualViewId();
+    method protected abstract int getVirtualViewAt(float, float);
+    method protected abstract void getVisibleVirtualViews(java.util.List<java.lang.Integer>);
+    method public final void invalidateRoot();
+    method public final void invalidateVirtualView(int);
+    method public final void invalidateVirtualView(int, int);
+    method public final void onFocusChanged(boolean, int, android.graphics.Rect);
+    method protected abstract boolean onPerformActionForVirtualView(int, int, android.os.Bundle);
+    method protected void onPopulateEventForHost(android.view.accessibility.AccessibilityEvent);
+    method protected void onPopulateEventForVirtualView(int, android.view.accessibility.AccessibilityEvent);
+    method protected void onPopulateNodeForHost(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+    method protected abstract void onPopulateNodeForVirtualView(int, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+    method protected void onVirtualViewKeyboardFocusChanged(int, boolean);
+    method public final boolean requestKeyboardFocusForVirtualView(int);
+    method public final boolean sendEventForVirtualView(int, int);
+    field public static final int HOST_ID = -1; // 0xffffffff
+    field public static final int INVALID_ID = -2147483648; // 0x80000000
+  }
+
+  public final class ListPopupWindowCompat {
+    method public static android.view.View.OnTouchListener createDragToOpenListener(java.lang.Object, android.view.View);
+  }
+
+  public class ListViewAutoScrollHelper extends android.support.v4.widget.AutoScrollHelper {
+    ctor public ListViewAutoScrollHelper(android.widget.ListView);
+    method public boolean canTargetScrollHorizontally(int);
+    method public boolean canTargetScrollVertically(int);
+    method public void scrollTargetBy(int, int);
+  }
+
+  public final class ListViewCompat {
+    method public static void scrollListBy(android.widget.ListView, int);
+  }
+
+  public class NestedScrollView extends android.widget.FrameLayout implements android.support.v4.view.NestedScrollingChild android.support.v4.view.NestedScrollingParent android.support.v4.view.ScrollingView {
+    ctor public NestedScrollView(android.content.Context);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet, int);
+    method public boolean arrowScroll(int);
+    method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect);
+    method public boolean executeKeyEvent(android.view.KeyEvent);
+    method public void fling(int);
+    method public boolean fullScroll(int);
+    method public int getMaxScrollAmount();
+    method public boolean isFillViewport();
+    method public boolean isSmoothScrollingEnabled();
+    method public void onAttachedToWindow();
+    method public boolean pageScroll(int);
+    method public void setFillViewport(boolean);
+    method public void setOnScrollChangeListener(android.support.v4.widget.NestedScrollView.OnScrollChangeListener);
+    method public void setSmoothScrollingEnabled(boolean);
+    method public final void smoothScrollBy(int, int);
+    method public final void smoothScrollTo(int, int);
+  }
+
+  public static abstract interface NestedScrollView.OnScrollChangeListener {
+    method public abstract void onScrollChange(android.support.v4.widget.NestedScrollView, int, int, int, int);
+  }
+
+  public final class PopupMenuCompat {
+    method public static android.view.View.OnTouchListener getDragToOpenListener(java.lang.Object);
+  }
+
+  public final class PopupWindowCompat {
+    method public static boolean getOverlapAnchor(android.widget.PopupWindow);
+    method public static int getWindowLayoutType(android.widget.PopupWindow);
+    method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
+    method public static void setWindowLayoutType(android.widget.PopupWindow, int);
+    method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
+  }
+
+  public abstract class ResourceCursorAdapter extends android.support.v4.widget.CursorAdapter {
+    ctor public deprecated ResourceCursorAdapter(android.content.Context, int, android.database.Cursor);
+    ctor public deprecated ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, boolean);
+    ctor public ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, int);
+    method public android.view.View newView(android.content.Context, android.database.Cursor, android.view.ViewGroup);
+    method public void setDropDownViewResource(int);
+    method public void setViewResource(int);
+  }
+
+  public final class ScrollerCompat {
+    method public void abortAnimation();
+    method public boolean computeScrollOffset();
+    method public static android.support.v4.widget.ScrollerCompat create(android.content.Context);
+    method public static android.support.v4.widget.ScrollerCompat create(android.content.Context, android.view.animation.Interpolator);
+    method public void fling(int, int, int, int, int, int, int, int);
+    method public void fling(int, int, int, int, int, int, int, int, int, int);
+    method public float getCurrVelocity();
+    method public int getCurrX();
+    method public int getCurrY();
+    method public int getFinalX();
+    method public int getFinalY();
+    method public boolean isFinished();
+    method public boolean isOverScrolled();
+    method public void notifyHorizontalEdgeReached(int, int, int);
+    method public void notifyVerticalEdgeReached(int, int, int);
+    method public boolean springBack(int, int, int, int, int, int);
+    method public void startScroll(int, int, int, int);
+    method public void startScroll(int, int, int, int, int);
+  }
+
+  public final class SearchViewCompat {
+    method public static java.lang.CharSequence getQuery(android.view.View);
+    method public static boolean isIconified(android.view.View);
+    method public static boolean isQueryRefinementEnabled(android.view.View);
+    method public static boolean isSubmitButtonEnabled(android.view.View);
+    method public static android.view.View newSearchView(android.content.Context);
+    method public static void setIconified(android.view.View, boolean);
+    method public static void setImeOptions(android.view.View, int);
+    method public static void setInputType(android.view.View, int);
+    method public static void setMaxWidth(android.view.View, int);
+    method public static void setOnCloseListener(android.view.View, android.support.v4.widget.SearchViewCompat.OnCloseListener);
+    method public static void setOnQueryTextListener(android.view.View, android.support.v4.widget.SearchViewCompat.OnQueryTextListener);
+    method public static void setQuery(android.view.View, java.lang.CharSequence, boolean);
+    method public static void setQueryHint(android.view.View, java.lang.CharSequence);
+    method public static void setQueryRefinementEnabled(android.view.View, boolean);
+    method public static void setSearchableInfo(android.view.View, android.content.ComponentName);
+    method public static void setSubmitButtonEnabled(android.view.View, boolean);
+  }
+
+  public static abstract interface SearchViewCompat.OnCloseListener {
+    method public abstract boolean onClose();
+  }
+
+  public static abstract deprecated class SearchViewCompat.OnCloseListenerCompat implements android.support.v4.widget.SearchViewCompat.OnCloseListener {
+    ctor public SearchViewCompat.OnCloseListenerCompat();
+    method public boolean onClose();
+  }
+
+  public static abstract interface SearchViewCompat.OnQueryTextListener {
+    method public abstract boolean onQueryTextChange(java.lang.String);
+    method public abstract boolean onQueryTextSubmit(java.lang.String);
+  }
+
+  public static abstract deprecated class SearchViewCompat.OnQueryTextListenerCompat implements android.support.v4.widget.SearchViewCompat.OnQueryTextListener {
+    ctor public SearchViewCompat.OnQueryTextListenerCompat();
+    method public boolean onQueryTextChange(java.lang.String);
+    method public boolean onQueryTextSubmit(java.lang.String);
+  }
+
+  public class SimpleCursorAdapter extends android.support.v4.widget.ResourceCursorAdapter {
+    ctor public deprecated SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, java.lang.String[], int[]);
+    ctor public SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, java.lang.String[], int[], int);
+    method public void bindView(android.view.View, android.content.Context, android.database.Cursor);
+    method public void changeCursorAndColumns(android.database.Cursor, java.lang.String[], int[]);
+    method public android.support.v4.widget.SimpleCursorAdapter.CursorToStringConverter getCursorToStringConverter();
+    method public int getStringConversionColumn();
+    method public android.support.v4.widget.SimpleCursorAdapter.ViewBinder getViewBinder();
+    method public void setCursorToStringConverter(android.support.v4.widget.SimpleCursorAdapter.CursorToStringConverter);
+    method public void setStringConversionColumn(int);
+    method public void setViewBinder(android.support.v4.widget.SimpleCursorAdapter.ViewBinder);
+    method public void setViewImage(android.widget.ImageView, java.lang.String);
+    method public void setViewText(android.widget.TextView, java.lang.String);
+  }
+
+  public static abstract interface SimpleCursorAdapter.CursorToStringConverter {
+    method public abstract java.lang.CharSequence convertToString(android.database.Cursor);
+  }
+
+  public static abstract interface SimpleCursorAdapter.ViewBinder {
+    method public abstract boolean setViewValue(android.view.View, android.database.Cursor, int);
+  }
+
+  public class SlidingPaneLayout extends android.view.ViewGroup {
+    ctor public SlidingPaneLayout(android.content.Context);
+    ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet);
+    ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet, int);
+    method protected boolean canScroll(android.view.View, boolean, int, int, int);
+    method public deprecated boolean canSlide();
+    method public boolean closePane();
+    method public int getCoveredFadeColor();
+    method public int getParallaxDistance();
+    method public int getSliderFadeColor();
+    method public boolean isOpen();
+    method public boolean isSlideable();
+    method protected void onLayout(boolean, int, int, int, int);
+    method public boolean openPane();
+    method public void setCoveredFadeColor(int);
+    method public void setPanelSlideListener(android.support.v4.widget.SlidingPaneLayout.PanelSlideListener);
+    method public void setParallaxDistance(int);
+    method public deprecated void setShadowDrawable(android.graphics.drawable.Drawable);
+    method public void setShadowDrawableLeft(android.graphics.drawable.Drawable);
+    method public void setShadowDrawableRight(android.graphics.drawable.Drawable);
+    method public deprecated void setShadowResource(int);
+    method public void setShadowResourceLeft(int);
+    method public void setShadowResourceRight(int);
+    method public void setSliderFadeColor(int);
+    method public deprecated void smoothSlideClosed();
+    method public deprecated void smoothSlideOpen();
+  }
+
+  public static class SlidingPaneLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public SlidingPaneLayout.LayoutParams();
+    ctor public SlidingPaneLayout.LayoutParams(int, int);
+    ctor public SlidingPaneLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public SlidingPaneLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public SlidingPaneLayout.LayoutParams(android.support.v4.widget.SlidingPaneLayout.LayoutParams);
+    ctor public SlidingPaneLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+    field public float weight;
+  }
+
+  public static abstract interface SlidingPaneLayout.PanelSlideListener {
+    method public abstract void onPanelClosed(android.view.View);
+    method public abstract void onPanelOpened(android.view.View);
+    method public abstract void onPanelSlide(android.view.View, float);
+  }
+
+  public static class SlidingPaneLayout.SimplePanelSlideListener implements android.support.v4.widget.SlidingPaneLayout.PanelSlideListener {
+    ctor public SlidingPaneLayout.SimplePanelSlideListener();
+    method public void onPanelClosed(android.view.View);
+    method public void onPanelOpened(android.view.View);
+    method public void onPanelSlide(android.view.View, float);
+  }
+
+  public class Space extends android.view.View {
+    ctor public Space(android.content.Context, android.util.AttributeSet, int);
+    ctor public Space(android.content.Context, android.util.AttributeSet);
+    ctor public Space(android.content.Context);
+  }
+
+  public class SwipeRefreshLayout extends android.view.ViewGroup implements android.support.v4.view.NestedScrollingChild android.support.v4.view.NestedScrollingParent {
+    ctor public SwipeRefreshLayout(android.content.Context);
+    ctor public SwipeRefreshLayout(android.content.Context, android.util.AttributeSet);
+    method public boolean canChildScrollUp();
+    method public int getProgressCircleDiameter();
+    method public int getProgressViewEndOffset();
+    method public int getProgressViewStartOffset();
+    method public boolean isRefreshing();
+    method protected void onLayout(boolean, int, int, int, int);
+    method public void onMeasure(int, int);
+    method public deprecated void setColorScheme(int...);
+    method public void setColorSchemeColors(int...);
+    method public void setColorSchemeResources(int...);
+    method public void setDistanceToTriggerSync(int);
+    method public void setOnChildScrollUpCallback(android.support.v4.widget.SwipeRefreshLayout.OnChildScrollUpCallback);
+    method public void setOnRefreshListener(android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener);
+    method public deprecated void setProgressBackgroundColor(int);
+    method public void setProgressBackgroundColorSchemeColor(int);
+    method public void setProgressBackgroundColorSchemeResource(int);
+    method public void setProgressViewEndTarget(boolean, int);
+    method public void setProgressViewOffset(boolean, int, int);
+    method public void setRefreshing(boolean);
+    method public void setSize(int);
+    field public static final int DEFAULT = 1; // 0x1
+    field public static final int LARGE = 0; // 0x0
+    field protected int mFrom;
+    field protected int mOriginalOffsetTop;
+  }
+
+  public static abstract interface SwipeRefreshLayout.OnChildScrollUpCallback {
+    method public abstract boolean canChildScrollUp(android.support.v4.widget.SwipeRefreshLayout, android.view.View);
+  }
+
+  public static abstract interface SwipeRefreshLayout.OnRefreshListener {
+    method public abstract void onRefresh();
+  }
+
+  public final class TextViewCompat {
+    method public static android.graphics.drawable.Drawable[] getCompoundDrawablesRelative(android.widget.TextView);
+    method public static int getMaxLines(android.widget.TextView);
+    method public static int getMinLines(android.widget.TextView);
+    method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, int, int, int, int);
+    method public static void setTextAppearance(android.widget.TextView, int);
+  }
+
+  public abstract interface TintableCompoundButton {
+    method public abstract android.content.res.ColorStateList getSupportButtonTintList();
+    method public abstract android.graphics.PorterDuff.Mode getSupportButtonTintMode();
+    method public abstract void setSupportButtonTintList(android.content.res.ColorStateList);
+    method public abstract void setSupportButtonTintMode(android.graphics.PorterDuff.Mode);
+  }
+
+  public class ViewDragHelper {
+    method public void abort();
+    method protected boolean canScroll(android.view.View, boolean, int, int, int, int);
+    method public void cancel();
+    method public void captureChildView(android.view.View, int);
+    method public boolean checkTouchSlop(int);
+    method public boolean checkTouchSlop(int, int);
+    method public boolean continueSettling(boolean);
+    method public static android.support.v4.widget.ViewDragHelper create(android.view.ViewGroup, android.support.v4.widget.ViewDragHelper.Callback);
+    method public static android.support.v4.widget.ViewDragHelper create(android.view.ViewGroup, float, android.support.v4.widget.ViewDragHelper.Callback);
+    method public android.view.View findTopChildUnder(int, int);
+    method public void flingCapturedView(int, int, int, int);
+    method public int getActivePointerId();
+    method public android.view.View getCapturedView();
+    method public int getEdgeSize();
+    method public float getMinVelocity();
+    method public int getTouchSlop();
+    method public int getViewDragState();
+    method public boolean isCapturedViewUnder(int, int);
+    method public boolean isEdgeTouched(int);
+    method public boolean isEdgeTouched(int, int);
+    method public boolean isPointerDown(int);
+    method public boolean isViewUnder(android.view.View, int, int);
+    method public void processTouchEvent(android.view.MotionEvent);
+    method public void setEdgeTrackingEnabled(int);
+    method public void setMinVelocity(float);
+    method public boolean settleCapturedViewAt(int, int);
+    method public boolean shouldInterceptTouchEvent(android.view.MotionEvent);
+    method public boolean smoothSlideViewTo(android.view.View, int, int);
+    field public static final int DIRECTION_ALL = 3; // 0x3
+    field public static final int DIRECTION_HORIZONTAL = 1; // 0x1
+    field public static final int DIRECTION_VERTICAL = 2; // 0x2
+    field public static final int EDGE_ALL = 15; // 0xf
+    field public static final int EDGE_BOTTOM = 8; // 0x8
+    field public static final int EDGE_LEFT = 1; // 0x1
+    field public static final int EDGE_RIGHT = 2; // 0x2
+    field public static final int EDGE_TOP = 4; // 0x4
+    field public static final int INVALID_POINTER = -1; // 0xffffffff
+    field public static final int STATE_DRAGGING = 1; // 0x1
+    field public static final int STATE_IDLE = 0; // 0x0
+    field public static final int STATE_SETTLING = 2; // 0x2
+  }
+
+  public static abstract class ViewDragHelper.Callback {
+    ctor public ViewDragHelper.Callback();
+    method public int clampViewPositionHorizontal(android.view.View, int, int);
+    method public int clampViewPositionVertical(android.view.View, int, int);
+    method public int getOrderedChildIndex(int);
+    method public int getViewHorizontalDragRange(android.view.View);
+    method public int getViewVerticalDragRange(android.view.View);
+    method public void onEdgeDragStarted(int, int);
+    method public boolean onEdgeLock(int);
+    method public void onEdgeTouched(int, int);
+    method public void onViewCaptured(android.view.View, int);
+    method public void onViewDragStateChanged(int);
+    method public void onViewPositionChanged(android.view.View, int, int, int, int);
+    method public void onViewReleased(android.view.View, float, float);
+    method public abstract boolean tryCaptureView(android.view.View, int);
+  }
+
+}
+
+package android.support.v7.app {
+
+  public abstract class ActionBar {
+    ctor public ActionBar();
+    method public abstract void addOnMenuVisibilityListener(android.support.v7.app.ActionBar.OnMenuVisibilityListener);
+    method public abstract deprecated void addTab(android.support.v7.app.ActionBar.Tab);
+    method public abstract deprecated void addTab(android.support.v7.app.ActionBar.Tab, boolean);
+    method public abstract deprecated void addTab(android.support.v7.app.ActionBar.Tab, int);
+    method public abstract deprecated void addTab(android.support.v7.app.ActionBar.Tab, int, boolean);
+    method public abstract android.view.View getCustomView();
+    method public abstract int getDisplayOptions();
+    method public float getElevation();
+    method public abstract int getHeight();
+    method public int getHideOffset();
+    method public abstract deprecated int getNavigationItemCount();
+    method public abstract deprecated int getNavigationMode();
+    method public abstract deprecated int getSelectedNavigationIndex();
+    method public abstract deprecated android.support.v7.app.ActionBar.Tab getSelectedTab();
+    method public abstract java.lang.CharSequence getSubtitle();
+    method public abstract deprecated android.support.v7.app.ActionBar.Tab getTabAt(int);
+    method public abstract deprecated int getTabCount();
+    method public android.content.Context getThemedContext();
+    method public abstract java.lang.CharSequence getTitle();
+    method public abstract void hide();
+    method public boolean isHideOnContentScrollEnabled();
+    method public abstract boolean isShowing();
+    method public abstract deprecated android.support.v7.app.ActionBar.Tab newTab();
+    method public abstract deprecated void removeAllTabs();
+    method public abstract void removeOnMenuVisibilityListener(android.support.v7.app.ActionBar.OnMenuVisibilityListener);
+    method public abstract deprecated void removeTab(android.support.v7.app.ActionBar.Tab);
+    method public abstract deprecated void removeTabAt(int);
+    method public abstract deprecated void selectTab(android.support.v7.app.ActionBar.Tab);
+    method public abstract void setBackgroundDrawable(android.graphics.drawable.Drawable);
+    method public abstract void setCustomView(android.view.View);
+    method public abstract void setCustomView(android.view.View, android.support.v7.app.ActionBar.LayoutParams);
+    method public abstract void setCustomView(int);
+    method public abstract void setDisplayHomeAsUpEnabled(boolean);
+    method public abstract void setDisplayOptions(int);
+    method public abstract void setDisplayOptions(int, int);
+    method public abstract void setDisplayShowCustomEnabled(boolean);
+    method public abstract void setDisplayShowHomeEnabled(boolean);
+    method public abstract void setDisplayShowTitleEnabled(boolean);
+    method public abstract void setDisplayUseLogoEnabled(boolean);
+    method public void setElevation(float);
+    method public void setHideOffset(int);
+    method public void setHideOnContentScrollEnabled(boolean);
+    method public void setHomeActionContentDescription(java.lang.CharSequence);
+    method public void setHomeActionContentDescription(int);
+    method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
+    method public void setHomeAsUpIndicator(int);
+    method public void setHomeButtonEnabled(boolean);
+    method public abstract void setIcon(int);
+    method public abstract void setIcon(android.graphics.drawable.Drawable);
+    method public abstract deprecated void setListNavigationCallbacks(android.widget.SpinnerAdapter, android.support.v7.app.ActionBar.OnNavigationListener);
+    method public abstract void setLogo(int);
+    method public abstract void setLogo(android.graphics.drawable.Drawable);
+    method public abstract deprecated void setNavigationMode(int);
+    method public abstract deprecated void setSelectedNavigationItem(int);
+    method public void setSplitBackgroundDrawable(android.graphics.drawable.Drawable);
+    method public void setStackedBackgroundDrawable(android.graphics.drawable.Drawable);
+    method public abstract void setSubtitle(java.lang.CharSequence);
+    method public abstract void setSubtitle(int);
+    method public abstract void setTitle(java.lang.CharSequence);
+    method public abstract void setTitle(int);
+    method public abstract void show();
+    field public static final int DISPLAY_HOME_AS_UP = 4; // 0x4
+    field public static final int DISPLAY_SHOW_CUSTOM = 16; // 0x10
+    field public static final int DISPLAY_SHOW_HOME = 2; // 0x2
+    field public static final int DISPLAY_SHOW_TITLE = 8; // 0x8
+    field public static final int DISPLAY_USE_LOGO = 1; // 0x1
+    field public static final deprecated int NAVIGATION_MODE_LIST = 1; // 0x1
+    field public static final deprecated int NAVIGATION_MODE_STANDARD = 0; // 0x0
+    field public static final deprecated int NAVIGATION_MODE_TABS = 2; // 0x2
+  }
+
+  public static class ActionBar.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public ActionBar.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public ActionBar.LayoutParams(int, int);
+    ctor public ActionBar.LayoutParams(int, int, int);
+    ctor public ActionBar.LayoutParams(int);
+    ctor public ActionBar.LayoutParams(android.support.v7.app.ActionBar.LayoutParams);
+    ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams);
+    field public int gravity;
+  }
+
+  public static abstract interface ActionBar.OnMenuVisibilityListener {
+    method public abstract void onMenuVisibilityChanged(boolean);
+  }
+
+  public static abstract deprecated interface ActionBar.OnNavigationListener {
+    method public abstract boolean onNavigationItemSelected(int, long);
+  }
+
+  public static abstract deprecated class ActionBar.Tab {
+    ctor public ActionBar.Tab();
+    method public abstract java.lang.CharSequence getContentDescription();
+    method public abstract android.view.View getCustomView();
+    method public abstract android.graphics.drawable.Drawable getIcon();
+    method public abstract int getPosition();
+    method public abstract java.lang.Object getTag();
+    method public abstract java.lang.CharSequence getText();
+    method public abstract void select();
+    method public abstract android.support.v7.app.ActionBar.Tab setContentDescription(int);
+    method public abstract android.support.v7.app.ActionBar.Tab setContentDescription(java.lang.CharSequence);
+    method public abstract android.support.v7.app.ActionBar.Tab setCustomView(android.view.View);
+    method public abstract android.support.v7.app.ActionBar.Tab setCustomView(int);
+    method public abstract android.support.v7.app.ActionBar.Tab setIcon(android.graphics.drawable.Drawable);
+    method public abstract android.support.v7.app.ActionBar.Tab setIcon(int);
+    method public abstract android.support.v7.app.ActionBar.Tab setTabListener(android.support.v7.app.ActionBar.TabListener);
+    method public abstract android.support.v7.app.ActionBar.Tab setTag(java.lang.Object);
+    method public abstract android.support.v7.app.ActionBar.Tab setText(java.lang.CharSequence);
+    method public abstract android.support.v7.app.ActionBar.Tab setText(int);
+    field public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  public static abstract deprecated interface ActionBar.TabListener {
+    method public abstract void onTabReselected(android.support.v7.app.ActionBar.Tab, android.support.v4.app.FragmentTransaction);
+    method public abstract void onTabSelected(android.support.v7.app.ActionBar.Tab, android.support.v4.app.FragmentTransaction);
+    method public abstract void onTabUnselected(android.support.v7.app.ActionBar.Tab, android.support.v4.app.FragmentTransaction);
+  }
+
+  public deprecated class ActionBarActivity extends android.support.v7.app.AppCompatActivity {
+    ctor public ActionBarActivity();
+  }
+
+  public class ActionBarDrawerToggle implements android.support.v4.widget.DrawerLayout.DrawerListener {
+    ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, int, int);
+    ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, android.support.v7.widget.Toolbar, int, int);
+    method public android.support.v7.graphics.drawable.DrawerArrowDrawable getDrawerArrowDrawable();
+    method public android.view.View.OnClickListener getToolbarNavigationClickListener();
+    method public boolean isDrawerIndicatorEnabled();
+    method public void onConfigurationChanged(android.content.res.Configuration);
+    method public void onDrawerClosed(android.view.View);
+    method public void onDrawerOpened(android.view.View);
+    method public void onDrawerSlide(android.view.View, float);
+    method public void onDrawerStateChanged(int);
+    method public boolean onOptionsItemSelected(android.view.MenuItem);
+    method public void setDrawerArrowDrawable(android.support.v7.graphics.drawable.DrawerArrowDrawable);
+    method public void setDrawerIndicatorEnabled(boolean);
+    method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
+    method public void setHomeAsUpIndicator(int);
+    method public void setToolbarNavigationClickListener(android.view.View.OnClickListener);
+    method public void syncState();
+  }
+
+  public static abstract interface ActionBarDrawerToggle.Delegate {
+    method public abstract android.content.Context getActionBarThemedContext();
+    method public abstract android.graphics.drawable.Drawable getThemeUpIndicator();
+    method public abstract boolean isNavigationVisible();
+    method public abstract void setActionBarDescription(int);
+    method public abstract void setActionBarUpIndicator(android.graphics.drawable.Drawable, int);
+  }
+
+  public static abstract interface ActionBarDrawerToggle.DelegateProvider {
+    method public abstract android.support.v7.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+  }
+
+  public class AlertDialog extends android.support.v7.app.AppCompatDialog implements android.content.DialogInterface {
+    ctor protected AlertDialog(android.content.Context);
+    ctor protected AlertDialog(android.content.Context, int);
+    ctor protected AlertDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener);
+    method public android.widget.Button getButton(int);
+    method public android.widget.ListView getListView();
+    method public void setButton(int, java.lang.CharSequence, android.os.Message);
+    method public void setButton(int, java.lang.CharSequence, android.content.DialogInterface.OnClickListener);
+    method public void setCustomTitle(android.view.View);
+    method public void setIcon(int);
+    method public void setIcon(android.graphics.drawable.Drawable);
+    method public void setIconAttribute(int);
+    method public void setMessage(java.lang.CharSequence);
+    method public void setView(android.view.View);
+    method public void setView(android.view.View, int, int, int, int);
+  }
+
+  public static class AlertDialog.Builder {
+    ctor public AlertDialog.Builder(android.content.Context);
+    ctor public AlertDialog.Builder(android.content.Context, int);
+    method public android.support.v7.app.AlertDialog create();
+    method public android.content.Context getContext();
+    method public android.support.v7.app.AlertDialog.Builder setAdapter(android.widget.ListAdapter, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setCancelable(boolean);
+    method public android.support.v7.app.AlertDialog.Builder setCursor(android.database.Cursor, android.content.DialogInterface.OnClickListener, java.lang.String);
+    method public android.support.v7.app.AlertDialog.Builder setCustomTitle(android.view.View);
+    method public android.support.v7.app.AlertDialog.Builder setIcon(int);
+    method public android.support.v7.app.AlertDialog.Builder setIcon(android.graphics.drawable.Drawable);
+    method public android.support.v7.app.AlertDialog.Builder setIconAttribute(int);
+    method public deprecated android.support.v7.app.AlertDialog.Builder setInverseBackgroundForced(boolean);
+    method public android.support.v7.app.AlertDialog.Builder setItems(int, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setItems(java.lang.CharSequence[], android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setMessage(int);
+    method public android.support.v7.app.AlertDialog.Builder setMessage(java.lang.CharSequence);
+    method public android.support.v7.app.AlertDialog.Builder setMultiChoiceItems(int, boolean[], android.content.DialogInterface.OnMultiChoiceClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setMultiChoiceItems(java.lang.CharSequence[], boolean[], android.content.DialogInterface.OnMultiChoiceClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setMultiChoiceItems(android.database.Cursor, java.lang.String, java.lang.String, android.content.DialogInterface.OnMultiChoiceClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setNegativeButton(int, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setNegativeButton(java.lang.CharSequence, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setNeutralButton(int, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setNeutralButton(java.lang.CharSequence, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setOnCancelListener(android.content.DialogInterface.OnCancelListener);
+    method public android.support.v7.app.AlertDialog.Builder setOnDismissListener(android.content.DialogInterface.OnDismissListener);
+    method public android.support.v7.app.AlertDialog.Builder setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener);
+    method public android.support.v7.app.AlertDialog.Builder setOnKeyListener(android.content.DialogInterface.OnKeyListener);
+    method public android.support.v7.app.AlertDialog.Builder setPositiveButton(int, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setPositiveButton(java.lang.CharSequence, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setSingleChoiceItems(int, int, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setSingleChoiceItems(android.database.Cursor, int, java.lang.String, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setSingleChoiceItems(java.lang.CharSequence[], int, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setSingleChoiceItems(android.widget.ListAdapter, int, android.content.DialogInterface.OnClickListener);
+    method public android.support.v7.app.AlertDialog.Builder setTitle(int);
+    method public android.support.v7.app.AlertDialog.Builder setTitle(java.lang.CharSequence);
+    method public android.support.v7.app.AlertDialog.Builder setView(int);
+    method public android.support.v7.app.AlertDialog.Builder setView(android.view.View);
+    method public android.support.v7.app.AlertDialog show();
+  }
+
+  public class AppCompatActivity extends android.support.v4.app.FragmentActivity implements android.support.v7.app.ActionBarDrawerToggle.DelegateProvider android.support.v7.app.AppCompatCallback android.support.v4.app.TaskStackBuilder.SupportParentable {
+    ctor public AppCompatActivity();
+    method public android.support.v7.app.AppCompatDelegate getDelegate();
+    method public android.support.v7.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+    method public android.support.v7.app.ActionBar getSupportActionBar();
+    method public android.content.Intent getSupportParentActivityIntent();
+    method public void onCreateSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder);
+    method public final boolean onMenuItemSelected(int, android.view.MenuItem);
+    method public void onPrepareSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder);
+    method public void onSupportActionModeFinished(android.support.v7.view.ActionMode);
+    method public void onSupportActionModeStarted(android.support.v7.view.ActionMode);
+    method public deprecated void onSupportContentChanged();
+    method public boolean onSupportNavigateUp();
+    method public android.support.v7.view.ActionMode onWindowStartingSupportActionMode(android.support.v7.view.ActionMode.Callback);
+    method public void setSupportActionBar(android.support.v7.widget.Toolbar);
+    method public deprecated void setSupportProgress(int);
+    method public deprecated void setSupportProgressBarIndeterminate(boolean);
+    method public deprecated void setSupportProgressBarIndeterminateVisibility(boolean);
+    method public deprecated void setSupportProgressBarVisibility(boolean);
+    method public android.support.v7.view.ActionMode startSupportActionMode(android.support.v7.view.ActionMode.Callback);
+    method public void supportNavigateUpTo(android.content.Intent);
+    method public boolean supportRequestWindowFeature(int);
+    method public boolean supportShouldUpRecreateTask(android.content.Intent);
+  }
+
+  public abstract interface AppCompatCallback {
+    method public abstract void onSupportActionModeFinished(android.support.v7.view.ActionMode);
+    method public abstract void onSupportActionModeStarted(android.support.v7.view.ActionMode);
+    method public abstract android.support.v7.view.ActionMode onWindowStartingSupportActionMode(android.support.v7.view.ActionMode.Callback);
+  }
+
+  public abstract class AppCompatDelegate {
+    method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
+    method public abstract boolean applyDayNight();
+    method public static android.support.v7.app.AppCompatDelegate create(android.app.Activity, android.support.v7.app.AppCompatCallback);
+    method public static android.support.v7.app.AppCompatDelegate create(android.app.Dialog, android.support.v7.app.AppCompatCallback);
+    method public abstract android.view.View createView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+    method public abstract android.view.View findViewById(int);
+    method public static int getDefaultNightMode();
+    method public abstract android.support.v7.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+    method public abstract android.view.MenuInflater getMenuInflater();
+    method public abstract android.support.v7.app.ActionBar getSupportActionBar();
+    method public abstract boolean hasWindowFeature(int);
+    method public abstract void installViewFactory();
+    method public abstract void invalidateOptionsMenu();
+    method public static boolean isCompatVectorFromResourcesEnabled();
+    method public abstract boolean isHandleNativeActionModesEnabled();
+    method public abstract void onConfigurationChanged(android.content.res.Configuration);
+    method public abstract void onCreate(android.os.Bundle);
+    method public abstract void onDestroy();
+    method public abstract void onPostCreate(android.os.Bundle);
+    method public abstract void onPostResume();
+    method public abstract void onSaveInstanceState(android.os.Bundle);
+    method public abstract void onStart();
+    method public abstract void onStop();
+    method public abstract boolean requestWindowFeature(int);
+    method public static void setCompatVectorFromResourcesEnabled(boolean);
+    method public abstract void setContentView(android.view.View);
+    method public abstract void setContentView(int);
+    method public abstract void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
+    method public static void setDefaultNightMode(int);
+    method public abstract void setHandleNativeActionModesEnabled(boolean);
+    method public abstract void setLocalNightMode(int);
+    method public abstract void setSupportActionBar(android.support.v7.widget.Toolbar);
+    method public abstract void setTitle(java.lang.CharSequence);
+    method public abstract android.support.v7.view.ActionMode startSupportActionMode(android.support.v7.view.ActionMode.Callback);
+    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+    field public static final int FEATURE_SUPPORT_ACTION_BAR = 108; // 0x6c
+    field public static final int FEATURE_SUPPORT_ACTION_BAR_OVERLAY = 109; // 0x6d
+    field public static final int MODE_NIGHT_AUTO = 0; // 0x0
+    field public static final int MODE_NIGHT_FOLLOW_SYSTEM = -1; // 0xffffffff
+    field public static final int MODE_NIGHT_NO = 1; // 0x1
+    field public static final int MODE_NIGHT_YES = 2; // 0x2
+  }
+
+  public class AppCompatDialog extends android.app.Dialog implements android.support.v7.app.AppCompatCallback {
+    ctor public AppCompatDialog(android.content.Context);
+    ctor public AppCompatDialog(android.content.Context, int);
+    ctor protected AppCompatDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener);
+    method public android.support.v7.app.AppCompatDelegate getDelegate();
+    method public android.support.v7.app.ActionBar getSupportActionBar();
+    method public void onSupportActionModeFinished(android.support.v7.view.ActionMode);
+    method public void onSupportActionModeStarted(android.support.v7.view.ActionMode);
+    method public android.support.v7.view.ActionMode onWindowStartingSupportActionMode(android.support.v7.view.ActionMode.Callback);
+    method public boolean supportRequestWindowFeature(int);
+  }
+
+  public class AppCompatDialogFragment extends android.support.v4.app.DialogFragment {
+    ctor public AppCompatDialogFragment();
+  }
+
+  public class MediaRouteActionProvider extends android.support.v4.view.ActionProvider {
+    ctor public MediaRouteActionProvider(android.content.Context);
+    method public android.support.v7.app.MediaRouteDialogFactory getDialogFactory();
+    method public android.support.v7.app.MediaRouteButton getMediaRouteButton();
+    method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+    method public android.view.View onCreateActionView();
+    method public android.support.v7.app.MediaRouteButton onCreateMediaRouteButton();
+    method public void setDialogFactory(android.support.v7.app.MediaRouteDialogFactory);
+    method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+  }
+
+  public class MediaRouteButton extends android.view.View {
+    ctor public MediaRouteButton(android.content.Context);
+    ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet);
+    ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int);
+    method public android.support.v7.app.MediaRouteDialogFactory getDialogFactory();
+    method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
+    method public void setDialogFactory(android.support.v7.app.MediaRouteDialogFactory);
+    method public void setRemoteIndicatorDrawable(android.graphics.drawable.Drawable);
+    method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+    method public boolean showDialog();
+  }
+
+  public class MediaRouteChooserDialog extends android.support.v7.app.AppCompatDialog {
+    ctor public MediaRouteChooserDialog(android.content.Context);
+    ctor public MediaRouteChooserDialog(android.content.Context, int);
+    method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+    method public boolean onFilterRoute(android.support.v7.media.MediaRouter.RouteInfo);
+    method public void onFilterRoutes(java.util.List<android.support.v7.media.MediaRouter.RouteInfo>);
+    method public void refreshRoutes();
+    method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+  }
+
+  public class MediaRouteChooserDialogFragment extends android.support.v4.app.DialogFragment {
+    ctor public MediaRouteChooserDialogFragment();
+    method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+    method public android.support.v7.app.MediaRouteChooserDialog onCreateChooserDialog(android.content.Context, android.os.Bundle);
+    method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+  }
+
+  public class MediaRouteControllerDialog extends android.support.v7.app.AlertDialog {
+    ctor public MediaRouteControllerDialog(android.content.Context);
+    ctor public MediaRouteControllerDialog(android.content.Context, int);
+    method public android.view.View getMediaControlView();
+    method public android.support.v4.media.session.MediaSessionCompat.Token getMediaSession();
+    method public android.support.v7.media.MediaRouter.RouteInfo getRoute();
+    method public boolean isVolumeControlEnabled();
+    method public android.view.View onCreateMediaControlView(android.os.Bundle);
+    method public void setVolumeControlEnabled(boolean);
+  }
+
+  public class MediaRouteControllerDialogFragment extends android.support.v4.app.DialogFragment {
+    ctor public MediaRouteControllerDialogFragment();
+    method public android.support.v7.app.MediaRouteControllerDialog onCreateControllerDialog(android.content.Context, android.os.Bundle);
+  }
+
+  public class MediaRouteDialogFactory {
+    ctor public MediaRouteDialogFactory();
+    method public static android.support.v7.app.MediaRouteDialogFactory getDefault();
+    method public android.support.v7.app.MediaRouteChooserDialogFragment onCreateChooserDialogFragment();
+    method public android.support.v7.app.MediaRouteControllerDialogFragment onCreateControllerDialogFragment();
+  }
+
+  public class MediaRouteDiscoveryFragment extends android.support.v4.app.Fragment {
+    ctor public MediaRouteDiscoveryFragment();
+    method public android.support.v7.media.MediaRouter getMediaRouter();
+    method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+    method public android.support.v7.media.MediaRouter.Callback onCreateCallback();
+    method public int onPrepareCallbackFlags();
+    method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+  }
+
+  public class NotificationCompat extends android.support.v4.app.NotificationCompat {
+    ctor public NotificationCompat();
+    method public static android.support.v4.media.session.MediaSessionCompat.Token getMediaSession(android.app.Notification);
+  }
+
+  public static class NotificationCompat.Builder extends android.support.v4.app.NotificationCompat.Builder {
+    ctor public NotificationCompat.Builder(android.content.Context);
+  }
+
+  public static class NotificationCompat.DecoratedCustomViewStyle extends android.support.v4.app.NotificationCompat.Style {
+    ctor public NotificationCompat.DecoratedCustomViewStyle();
+  }
+
+  public static class NotificationCompat.DecoratedMediaCustomViewStyle extends android.support.v7.app.NotificationCompat.MediaStyle {
+    ctor public NotificationCompat.DecoratedMediaCustomViewStyle();
+  }
+
+  public static class NotificationCompat.MediaStyle extends android.support.v4.app.NotificationCompat.Style {
+    ctor public NotificationCompat.MediaStyle();
+    ctor public NotificationCompat.MediaStyle(android.support.v4.app.NotificationCompat.Builder);
+    method public android.support.v7.app.NotificationCompat.MediaStyle setCancelButtonIntent(android.app.PendingIntent);
+    method public android.support.v7.app.NotificationCompat.MediaStyle setMediaSession(android.support.v4.media.session.MediaSessionCompat.Token);
+    method public android.support.v7.app.NotificationCompat.MediaStyle setShowActionsInCompactView(int...);
+    method public android.support.v7.app.NotificationCompat.MediaStyle setShowCancelButton(boolean);
+  }
+
+}
+
+package android.support.v7.content.res {
+
+  public final class AppCompatResources {
+    method public static android.content.res.ColorStateList getColorStateList(android.content.Context, int);
+    method public static android.graphics.drawable.Drawable getDrawable(android.content.Context, int);
+  }
+
+}
+
+package android.support.v7.graphics {
+
+  public final class Palette {
+    method public static android.support.v7.graphics.Palette.Builder from(android.graphics.Bitmap);
+    method public static android.support.v7.graphics.Palette from(java.util.List<android.support.v7.graphics.Palette.Swatch>);
+    method public static deprecated android.support.v7.graphics.Palette generate(android.graphics.Bitmap);
+    method public static deprecated android.support.v7.graphics.Palette generate(android.graphics.Bitmap, int);
+    method public static deprecated android.os.AsyncTask<android.graphics.Bitmap, java.lang.Void, android.support.v7.graphics.Palette> generateAsync(android.graphics.Bitmap, android.support.v7.graphics.Palette.PaletteAsyncListener);
+    method public static deprecated android.os.AsyncTask<android.graphics.Bitmap, java.lang.Void, android.support.v7.graphics.Palette> generateAsync(android.graphics.Bitmap, int, android.support.v7.graphics.Palette.PaletteAsyncListener);
+    method public int getColorForTarget(android.support.v7.graphics.Target, int);
+    method public int getDarkMutedColor(int);
+    method public android.support.v7.graphics.Palette.Swatch getDarkMutedSwatch();
+    method public int getDarkVibrantColor(int);
+    method public android.support.v7.graphics.Palette.Swatch getDarkVibrantSwatch();
+    method public int getDominantColor(int);
+    method public android.support.v7.graphics.Palette.Swatch getDominantSwatch();
+    method public int getLightMutedColor(int);
+    method public android.support.v7.graphics.Palette.Swatch getLightMutedSwatch();
+    method public int getLightVibrantColor(int);
+    method public android.support.v7.graphics.Palette.Swatch getLightVibrantSwatch();
+    method public int getMutedColor(int);
+    method public android.support.v7.graphics.Palette.Swatch getMutedSwatch();
+    method public android.support.v7.graphics.Palette.Swatch getSwatchForTarget(android.support.v7.graphics.Target);
+    method public java.util.List<android.support.v7.graphics.Palette.Swatch> getSwatches();
+    method public java.util.List<android.support.v7.graphics.Target> getTargets();
+    method public int getVibrantColor(int);
+    method public android.support.v7.graphics.Palette.Swatch getVibrantSwatch();
+  }
+
+  public static final class Palette.Builder {
+    ctor public Palette.Builder(android.graphics.Bitmap);
+    ctor public Palette.Builder(java.util.List<android.support.v7.graphics.Palette.Swatch>);
+    method public android.support.v7.graphics.Palette.Builder addFilter(android.support.v7.graphics.Palette.Filter);
+    method public android.support.v7.graphics.Palette.Builder addTarget(android.support.v7.graphics.Target);
+    method public android.support.v7.graphics.Palette.Builder clearFilters();
+    method public android.support.v7.graphics.Palette.Builder clearRegion();
+    method public android.support.v7.graphics.Palette.Builder clearTargets();
+    method public android.support.v7.graphics.Palette generate();
+    method public android.os.AsyncTask<android.graphics.Bitmap, java.lang.Void, android.support.v7.graphics.Palette> generate(android.support.v7.graphics.Palette.PaletteAsyncListener);
+    method public android.support.v7.graphics.Palette.Builder maximumColorCount(int);
+    method public android.support.v7.graphics.Palette.Builder resizeBitmapArea(int);
+    method public deprecated android.support.v7.graphics.Palette.Builder resizeBitmapSize(int);
+    method public android.support.v7.graphics.Palette.Builder setRegion(int, int, int, int);
+  }
+
+  public static abstract interface Palette.Filter {
+    method public abstract boolean isAllowed(int, float[]);
+  }
+
+  public static abstract interface Palette.PaletteAsyncListener {
+    method public abstract void onGenerated(android.support.v7.graphics.Palette);
+  }
+
+  public static final class Palette.Swatch {
+    ctor public Palette.Swatch(int, int);
+    method public int getBodyTextColor();
+    method public float[] getHsl();
+    method public int getPopulation();
+    method public int getRgb();
+    method public int getTitleTextColor();
+  }
+
+  public final class Target {
+    method public float getLightnessWeight();
+    method public float getMaximumLightness();
+    method public float getMaximumSaturation();
+    method public float getMinimumLightness();
+    method public float getMinimumSaturation();
+    method public float getPopulationWeight();
+    method public float getSaturationWeight();
+    method public float getTargetLightness();
+    method public float getTargetSaturation();
+    method public boolean isExclusive();
+    field public static final android.support.v7.graphics.Target DARK_MUTED;
+    field public static final android.support.v7.graphics.Target DARK_VIBRANT;
+    field public static final android.support.v7.graphics.Target LIGHT_MUTED;
+    field public static final android.support.v7.graphics.Target LIGHT_VIBRANT;
+    field public static final android.support.v7.graphics.Target MUTED;
+    field public static final android.support.v7.graphics.Target VIBRANT;
+  }
+
+  public static final class Target.Builder {
+    ctor public Target.Builder();
+    ctor public Target.Builder(android.support.v7.graphics.Target);
+    method public android.support.v7.graphics.Target build();
+    method public android.support.v7.graphics.Target.Builder setExclusive(boolean);
+    method public android.support.v7.graphics.Target.Builder setLightnessWeight(float);
+    method public android.support.v7.graphics.Target.Builder setMaximumLightness(float);
+    method public android.support.v7.graphics.Target.Builder setMaximumSaturation(float);
+    method public android.support.v7.graphics.Target.Builder setMinimumLightness(float);
+    method public android.support.v7.graphics.Target.Builder setMinimumSaturation(float);
+    method public android.support.v7.graphics.Target.Builder setPopulationWeight(float);
+    method public android.support.v7.graphics.Target.Builder setSaturationWeight(float);
+    method public android.support.v7.graphics.Target.Builder setTargetLightness(float);
+    method public android.support.v7.graphics.Target.Builder setTargetSaturation(float);
+  }
+
+}
+
+package android.support.v7.graphics.drawable {
+
+  public class DrawerArrowDrawable extends android.graphics.drawable.Drawable {
+    ctor public DrawerArrowDrawable(android.content.Context);
+    method public void draw(android.graphics.Canvas);
+    method public float getArrowHeadLength();
+    method public float getArrowShaftLength();
+    method public float getBarLength();
+    method public float getBarThickness();
+    method public int getColor();
+    method public int getDirection();
+    method public float getGapSize();
+    method public int getOpacity();
+    method public final android.graphics.Paint getPaint();
+    method public float getProgress();
+    method public boolean isSpinEnabled();
+    method public void setAlpha(int);
+    method public void setArrowHeadLength(float);
+    method public void setArrowShaftLength(float);
+    method public void setBarLength(float);
+    method public void setBarThickness(float);
+    method public void setColor(int);
+    method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDirection(int);
+    method public void setGapSize(float);
+    method public void setProgress(float);
+    method public void setSpinEnabled(boolean);
+    method public void setVerticalMirror(boolean);
+    field public static final int ARROW_DIRECTION_END = 3; // 0x3
+    field public static final int ARROW_DIRECTION_LEFT = 0; // 0x0
+    field public static final int ARROW_DIRECTION_RIGHT = 1; // 0x1
+    field public static final int ARROW_DIRECTION_START = 2; // 0x2
+  }
+
+}
+
+package android.support.v7.media {
+
+  public final class MediaControlIntent {
+    field public static final java.lang.String ACTION_END_SESSION = "android.media.intent.action.END_SESSION";
+    field public static final java.lang.String ACTION_ENQUEUE = "android.media.intent.action.ENQUEUE";
+    field public static final java.lang.String ACTION_GET_SESSION_STATUS = "android.media.intent.action.GET_SESSION_STATUS";
+    field public static final java.lang.String ACTION_GET_STATUS = "android.media.intent.action.GET_STATUS";
+    field public static final java.lang.String ACTION_PAUSE = "android.media.intent.action.PAUSE";
+    field public static final java.lang.String ACTION_PLAY = "android.media.intent.action.PLAY";
+    field public static final java.lang.String ACTION_REMOVE = "android.media.intent.action.REMOVE";
+    field public static final java.lang.String ACTION_RESUME = "android.media.intent.action.RESUME";
+    field public static final java.lang.String ACTION_SEEK = "android.media.intent.action.SEEK";
+    field public static final java.lang.String ACTION_SEND_MESSAGE = "android.media.intent.action.SEND_MESSAGE";
+    field public static final java.lang.String ACTION_START_SESSION = "android.media.intent.action.START_SESSION";
+    field public static final java.lang.String ACTION_STOP = "android.media.intent.action.STOP";
+    field public static final java.lang.String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
+    field public static final java.lang.String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
+    field public static final java.lang.String CATEGORY_REMOTE_PLAYBACK = "android.media.intent.category.REMOTE_PLAYBACK";
+    field public static final int ERROR_INVALID_ITEM_ID = 3; // 0x3
+    field public static final int ERROR_INVALID_SESSION_ID = 2; // 0x2
+    field public static final int ERROR_UNKNOWN = 0; // 0x0
+    field public static final int ERROR_UNSUPPORTED_OPERATION = 1; // 0x1
+    field public static final java.lang.String EXTRA_ERROR_CODE = "android.media.intent.extra.ERROR_CODE";
+    field public static final java.lang.String EXTRA_ITEM_CONTENT_POSITION = "android.media.intent.extra.ITEM_POSITION";
+    field public static final java.lang.String EXTRA_ITEM_HTTP_HEADERS = "android.media.intent.extra.HTTP_HEADERS";
+    field public static final java.lang.String EXTRA_ITEM_ID = "android.media.intent.extra.ITEM_ID";
+    field public static final java.lang.String EXTRA_ITEM_METADATA = "android.media.intent.extra.ITEM_METADATA";
+    field public static final java.lang.String EXTRA_ITEM_STATUS = "android.media.intent.extra.ITEM_STATUS";
+    field public static final java.lang.String EXTRA_ITEM_STATUS_UPDATE_RECEIVER = "android.media.intent.extra.ITEM_STATUS_UPDATE_RECEIVER";
+    field public static final java.lang.String EXTRA_MESSAGE = "android.media.intent.extra.MESSAGE";
+    field public static final java.lang.String EXTRA_MESSAGE_RECEIVER = "android.media.intent.extra.MESSAGE_RECEIVER";
+    field public static final java.lang.String EXTRA_SESSION_ID = "android.media.intent.extra.SESSION_ID";
+    field public static final java.lang.String EXTRA_SESSION_STATUS = "android.media.intent.extra.SESSION_STATUS";
+    field public static final java.lang.String EXTRA_SESSION_STATUS_UPDATE_RECEIVER = "android.media.intent.extra.SESSION_STATUS_UPDATE_RECEIVER";
+  }
+
+  public final class MediaItemMetadata {
+    field public static final java.lang.String KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+    field public static final java.lang.String KEY_ALBUM_TITLE = "android.media.metadata.ALBUM_TITLE";
+    field public static final java.lang.String KEY_ARTIST = "android.media.metadata.ARTIST";
+    field public static final java.lang.String KEY_ARTWORK_URI = "android.media.metadata.ARTWORK_URI";
+    field public static final java.lang.String KEY_AUTHOR = "android.media.metadata.AUTHOR";
+    field public static final java.lang.String KEY_COMPOSER = "android.media.metadata.COMPOSER";
+    field public static final java.lang.String KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+    field public static final java.lang.String KEY_DURATION = "android.media.metadata.DURATION";
+    field public static final java.lang.String KEY_TITLE = "android.media.metadata.TITLE";
+    field public static final java.lang.String KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+    field public static final java.lang.String KEY_YEAR = "android.media.metadata.YEAR";
+  }
+
+  public final class MediaItemStatus {
+    method public android.os.Bundle asBundle();
+    method public static android.support.v7.media.MediaItemStatus fromBundle(android.os.Bundle);
+    method public long getContentDuration();
+    method public long getContentPosition();
+    method public android.os.Bundle getExtras();
+    method public int getPlaybackState();
+    method public long getTimestamp();
+    field public static final java.lang.String EXTRA_HTTP_RESPONSE_HEADERS = "android.media.status.extra.HTTP_RESPONSE_HEADERS";
+    field public static final java.lang.String EXTRA_HTTP_STATUS_CODE = "android.media.status.extra.HTTP_STATUS_CODE";
+    field public static final int PLAYBACK_STATE_BUFFERING = 3; // 0x3
+    field public static final int PLAYBACK_STATE_CANCELED = 5; // 0x5
+    field public static final int PLAYBACK_STATE_ERROR = 7; // 0x7
+    field public static final int PLAYBACK_STATE_FINISHED = 4; // 0x4
+    field public static final int PLAYBACK_STATE_INVALIDATED = 6; // 0x6
+    field public static final int PLAYBACK_STATE_PAUSED = 2; // 0x2
+    field public static final int PLAYBACK_STATE_PENDING = 0; // 0x0
+    field public static final int PLAYBACK_STATE_PLAYING = 1; // 0x1
+  }
+
+  public static final class MediaItemStatus.Builder {
+    ctor public MediaItemStatus.Builder(int);
+    ctor public MediaItemStatus.Builder(android.support.v7.media.MediaItemStatus);
+    method public android.support.v7.media.MediaItemStatus build();
+    method public android.support.v7.media.MediaItemStatus.Builder setContentDuration(long);
+    method public android.support.v7.media.MediaItemStatus.Builder setContentPosition(long);
+    method public android.support.v7.media.MediaItemStatus.Builder setExtras(android.os.Bundle);
+    method public android.support.v7.media.MediaItemStatus.Builder setPlaybackState(int);
+    method public android.support.v7.media.MediaItemStatus.Builder setTimestamp(long);
+  }
+
+  public final class MediaRouteDescriptor {
+    method public android.os.Bundle asBundle();
+    method public boolean canDisconnectAndKeepPlaying();
+    method public static android.support.v7.media.MediaRouteDescriptor fromBundle(android.os.Bundle);
+    method public int getConnectionState();
+    method public java.util.List<android.content.IntentFilter> getControlFilters();
+    method public java.lang.String getDescription();
+    method public int getDeviceType();
+    method public android.os.Bundle getExtras();
+    method public android.net.Uri getIconUri();
+    method public java.lang.String getId();
+    method public java.lang.String getName();
+    method public int getPlaybackStream();
+    method public int getPlaybackType();
+    method public int getPresentationDisplayId();
+    method public android.content.IntentSender getSettingsActivity();
+    method public int getVolume();
+    method public int getVolumeHandling();
+    method public int getVolumeMax();
+    method public deprecated boolean isConnecting();
+    method public boolean isEnabled();
+    method public boolean isValid();
+  }
+
+  public static final class MediaRouteDescriptor.Builder {
+    ctor public MediaRouteDescriptor.Builder(java.lang.String, java.lang.String);
+    ctor public MediaRouteDescriptor.Builder(android.support.v7.media.MediaRouteDescriptor);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder addControlFilter(android.content.IntentFilter);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder addControlFilters(java.util.Collection<android.content.IntentFilter>);
+    method public android.support.v7.media.MediaRouteDescriptor build();
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setCanDisconnect(boolean);
+    method public deprecated android.support.v7.media.MediaRouteDescriptor.Builder setConnecting(boolean);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setConnectionState(int);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setDescription(java.lang.String);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setDeviceType(int);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setEnabled(boolean);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setExtras(android.os.Bundle);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setIconUri(android.net.Uri);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setId(java.lang.String);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setName(java.lang.String);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setPlaybackStream(int);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setPlaybackType(int);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setPresentationDisplayId(int);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setSettingsActivity(android.content.IntentSender);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setVolume(int);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setVolumeHandling(int);
+    method public android.support.v7.media.MediaRouteDescriptor.Builder setVolumeMax(int);
+  }
+
+  public final class MediaRouteDiscoveryRequest {
+    ctor public MediaRouteDiscoveryRequest(android.support.v7.media.MediaRouteSelector, boolean);
+    method public android.os.Bundle asBundle();
+    method public static android.support.v7.media.MediaRouteDiscoveryRequest fromBundle(android.os.Bundle);
+    method public android.support.v7.media.MediaRouteSelector getSelector();
+    method public boolean isActiveScan();
+    method public boolean isValid();
+  }
+
+  public abstract class MediaRouteProvider {
+    ctor public MediaRouteProvider(android.content.Context);
+    method public final android.content.Context getContext();
+    method public final android.support.v7.media.MediaRouteProviderDescriptor getDescriptor();
+    method public final android.support.v7.media.MediaRouteDiscoveryRequest getDiscoveryRequest();
+    method public final android.os.Handler getHandler();
+    method public final android.support.v7.media.MediaRouteProvider.ProviderMetadata getMetadata();
+    method public android.support.v7.media.MediaRouteProvider.RouteController onCreateRouteController(java.lang.String);
+    method public void onDiscoveryRequestChanged(android.support.v7.media.MediaRouteDiscoveryRequest);
+    method public final void setCallback(android.support.v7.media.MediaRouteProvider.Callback);
+    method public final void setDescriptor(android.support.v7.media.MediaRouteProviderDescriptor);
+    method public final void setDiscoveryRequest(android.support.v7.media.MediaRouteDiscoveryRequest);
+  }
+
+  public static abstract class MediaRouteProvider.Callback {
+    ctor public MediaRouteProvider.Callback();
+    method public void onDescriptorChanged(android.support.v7.media.MediaRouteProvider, android.support.v7.media.MediaRouteProviderDescriptor);
+  }
+
+  public static final class MediaRouteProvider.ProviderMetadata {
+    method public android.content.ComponentName getComponentName();
+    method public java.lang.String getPackageName();
+  }
+
+  public static abstract class MediaRouteProvider.RouteController {
+    ctor public MediaRouteProvider.RouteController();
+    method public boolean onControlRequest(android.content.Intent, android.support.v7.media.MediaRouter.ControlRequestCallback);
+    method public void onRelease();
+    method public void onSelect();
+    method public void onSetVolume(int);
+    method public void onUnselect();
+    method public void onUnselect(int);
+    method public void onUpdateVolume(int);
+  }
+
+  public final class MediaRouteProviderDescriptor {
+    method public android.os.Bundle asBundle();
+    method public static android.support.v7.media.MediaRouteProviderDescriptor fromBundle(android.os.Bundle);
+    method public java.util.List<android.support.v7.media.MediaRouteDescriptor> getRoutes();
+    method public boolean isValid();
+  }
+
+  public static final class MediaRouteProviderDescriptor.Builder {
+    ctor public MediaRouteProviderDescriptor.Builder();
+    ctor public MediaRouteProviderDescriptor.Builder(android.support.v7.media.MediaRouteProviderDescriptor);
+    method public android.support.v7.media.MediaRouteProviderDescriptor.Builder addRoute(android.support.v7.media.MediaRouteDescriptor);
+    method public android.support.v7.media.MediaRouteProviderDescriptor.Builder addRoutes(java.util.Collection<android.support.v7.media.MediaRouteDescriptor>);
+    method public android.support.v7.media.MediaRouteProviderDescriptor build();
+  }
+
+  public abstract class MediaRouteProviderService extends android.app.Service {
+    ctor public MediaRouteProviderService();
+    method public android.support.v7.media.MediaRouteProvider getMediaRouteProvider();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract android.support.v7.media.MediaRouteProvider onCreateMediaRouteProvider();
+    field public static final java.lang.String SERVICE_INTERFACE = "android.media.MediaRouteProviderService";
+  }
+
+  public final class MediaRouteSelector {
+    method public android.os.Bundle asBundle();
+    method public boolean contains(android.support.v7.media.MediaRouteSelector);
+    method public static android.support.v7.media.MediaRouteSelector fromBundle(android.os.Bundle);
+    method public java.util.List<java.lang.String> getControlCategories();
+    method public boolean hasControlCategory(java.lang.String);
+    method public boolean isEmpty();
+    method public boolean isValid();
+    method public boolean matchesControlFilters(java.util.List<android.content.IntentFilter>);
+    field public static final android.support.v7.media.MediaRouteSelector EMPTY;
+  }
+
+  public static final class MediaRouteSelector.Builder {
+    ctor public MediaRouteSelector.Builder();
+    ctor public MediaRouteSelector.Builder(android.support.v7.media.MediaRouteSelector);
+    method public android.support.v7.media.MediaRouteSelector.Builder addControlCategories(java.util.Collection<java.lang.String>);
+    method public android.support.v7.media.MediaRouteSelector.Builder addControlCategory(java.lang.String);
+    method public android.support.v7.media.MediaRouteSelector.Builder addSelector(android.support.v7.media.MediaRouteSelector);
+    method public android.support.v7.media.MediaRouteSelector build();
+  }
+
+  public final class MediaRouter {
+    method public void addCallback(android.support.v7.media.MediaRouteSelector, android.support.v7.media.MediaRouter.Callback);
+    method public void addCallback(android.support.v7.media.MediaRouteSelector, android.support.v7.media.MediaRouter.Callback, int);
+    method public void addProvider(android.support.v7.media.MediaRouteProvider);
+    method public void addRemoteControlClient(java.lang.Object);
+    method public android.support.v7.media.MediaRouter.RouteInfo getBluetoothRoute();
+    method public android.support.v7.media.MediaRouter.RouteInfo getDefaultRoute();
+    method public static android.support.v7.media.MediaRouter getInstance(android.content.Context);
+    method public android.support.v4.media.session.MediaSessionCompat.Token getMediaSessionToken();
+    method public java.util.List<android.support.v7.media.MediaRouter.ProviderInfo> getProviders();
+    method public java.util.List<android.support.v7.media.MediaRouter.RouteInfo> getRoutes();
+    method public android.support.v7.media.MediaRouter.RouteInfo getSelectedRoute();
+    method public boolean isRouteAvailable(android.support.v7.media.MediaRouteSelector, int);
+    method public void removeCallback(android.support.v7.media.MediaRouter.Callback);
+    method public void removeProvider(android.support.v7.media.MediaRouteProvider);
+    method public void removeRemoteControlClient(java.lang.Object);
+    method public void selectRoute(android.support.v7.media.MediaRouter.RouteInfo);
+    method public void setMediaSession(java.lang.Object);
+    method public void setMediaSessionCompat(android.support.v4.media.session.MediaSessionCompat);
+    method public void unselect(int);
+    method public android.support.v7.media.MediaRouter.RouteInfo updateSelectedRoute(android.support.v7.media.MediaRouteSelector);
+    field public static final int AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE = 1; // 0x1
+    field public static final int AVAILABILITY_FLAG_REQUIRE_MATCH = 2; // 0x2
+    field public static final int CALLBACK_FLAG_FORCE_DISCOVERY = 8; // 0x8
+    field public static final int CALLBACK_FLAG_PERFORM_ACTIVE_SCAN = 1; // 0x1
+    field public static final int CALLBACK_FLAG_REQUEST_DISCOVERY = 4; // 0x4
+    field public static final int CALLBACK_FLAG_UNFILTERED_EVENTS = 2; // 0x2
+    field public static final int UNSELECT_REASON_DISCONNECTED = 1; // 0x1
+    field public static final int UNSELECT_REASON_ROUTE_CHANGED = 3; // 0x3
+    field public static final int UNSELECT_REASON_STOPPED = 2; // 0x2
+    field public static final int UNSELECT_REASON_UNKNOWN = 0; // 0x0
+  }
+
+  public static abstract class MediaRouter.Callback {
+    ctor public MediaRouter.Callback();
+    method public void onProviderAdded(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.ProviderInfo);
+    method public void onProviderChanged(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.ProviderInfo);
+    method public void onProviderRemoved(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.ProviderInfo);
+    method public void onRouteAdded(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+    method public void onRouteChanged(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+    method public void onRoutePresentationDisplayChanged(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+    method public void onRouteRemoved(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+    method public void onRouteSelected(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+    method public void onRouteUnselected(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+    method public void onRouteUnselected(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo, int);
+    method public void onRouteVolumeChanged(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+  }
+
+  public static abstract class MediaRouter.ControlRequestCallback {
+    ctor public MediaRouter.ControlRequestCallback();
+    method public void onError(java.lang.String, android.os.Bundle);
+    method public void onResult(android.os.Bundle);
+  }
+
+  public static final class MediaRouter.ProviderInfo {
+    method public android.content.ComponentName getComponentName();
+    method public java.lang.String getPackageName();
+    method public android.support.v7.media.MediaRouteProvider getProviderInstance();
+    method public java.util.List<android.support.v7.media.MediaRouter.RouteInfo> getRoutes();
+  }
+
+  public static class MediaRouter.RouteInfo {
+    method public boolean canDisconnect();
+    method public int getConnectionState();
+    method public java.util.List<android.content.IntentFilter> getControlFilters();
+    method public java.lang.String getDescription();
+    method public int getDeviceType();
+    method public android.os.Bundle getExtras();
+    method public android.net.Uri getIconUri();
+    method public java.lang.String getId();
+    method public java.lang.String getName();
+    method public int getPlaybackStream();
+    method public int getPlaybackType();
+    method public android.view.Display getPresentationDisplay();
+    method public android.support.v7.media.MediaRouter.ProviderInfo getProvider();
+    method public android.content.IntentSender getSettingsIntent();
+    method public int getVolume();
+    method public int getVolumeHandling();
+    method public int getVolumeMax();
+    method public boolean isBluetooth();
+    method public boolean isConnecting();
+    method public boolean isDefault();
+    method public boolean isDeviceSpeaker();
+    method public boolean isEnabled();
+    method public boolean isSelected();
+    method public boolean matchesSelector(android.support.v7.media.MediaRouteSelector);
+    method public void requestSetVolume(int);
+    method public void requestUpdateVolume(int);
+    method public void select();
+    method public void sendControlRequest(android.content.Intent, android.support.v7.media.MediaRouter.ControlRequestCallback);
+    method public boolean supportsControlAction(java.lang.String, java.lang.String);
+    method public boolean supportsControlCategory(java.lang.String);
+    method public boolean supportsControlRequest(android.content.Intent);
+    field public static final int CONNECTION_STATE_CONNECTED = 2; // 0x2
+    field public static final int CONNECTION_STATE_CONNECTING = 1; // 0x1
+    field public static final int CONNECTION_STATE_DISCONNECTED = 0; // 0x0
+    field public static final int DEVICE_TYPE_SPEAKER = 2; // 0x2
+    field public static final int DEVICE_TYPE_TV = 1; // 0x1
+    field public static final int PLAYBACK_TYPE_LOCAL = 0; // 0x0
+    field public static final int PLAYBACK_TYPE_REMOTE = 1; // 0x1
+    field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
+    field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
+  }
+
+  public final class MediaSessionStatus {
+    method public android.os.Bundle asBundle();
+    method public static android.support.v7.media.MediaSessionStatus fromBundle(android.os.Bundle);
+    method public android.os.Bundle getExtras();
+    method public int getSessionState();
+    method public long getTimestamp();
+    method public boolean isQueuePaused();
+    field public static final int SESSION_STATE_ACTIVE = 0; // 0x0
+    field public static final int SESSION_STATE_ENDED = 1; // 0x1
+    field public static final int SESSION_STATE_INVALIDATED = 2; // 0x2
+  }
+
+  public static final class MediaSessionStatus.Builder {
+    ctor public MediaSessionStatus.Builder(int);
+    ctor public MediaSessionStatus.Builder(android.support.v7.media.MediaSessionStatus);
+    method public android.support.v7.media.MediaSessionStatus build();
+    method public android.support.v7.media.MediaSessionStatus.Builder setExtras(android.os.Bundle);
+    method public android.support.v7.media.MediaSessionStatus.Builder setQueuePaused(boolean);
+    method public android.support.v7.media.MediaSessionStatus.Builder setSessionState(int);
+    method public android.support.v7.media.MediaSessionStatus.Builder setTimestamp(long);
+  }
+
+  public class RemotePlaybackClient {
+    ctor public RemotePlaybackClient(android.content.Context, android.support.v7.media.MediaRouter.RouteInfo);
+    method public void endSession(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+    method public void enqueue(android.net.Uri, java.lang.String, android.os.Bundle, long, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+    method public java.lang.String getSessionId();
+    method public void getSessionStatus(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+    method public void getStatus(java.lang.String, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+    method public boolean hasSession();
+    method public boolean isMessagingSupported();
+    method public boolean isQueuingSupported();
+    method public boolean isRemotePlaybackSupported();
+    method public boolean isSessionManagementSupported();
+    method public void pause(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+    method public void play(android.net.Uri, java.lang.String, android.os.Bundle, long, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+    method public void release();
+    method public void remove(java.lang.String, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+    method public void resume(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+    method public void seek(java.lang.String, long, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+    method public void sendMessage(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+    method public void setOnMessageReceivedListener(android.support.v7.media.RemotePlaybackClient.OnMessageReceivedListener);
+    method public void setSessionId(java.lang.String);
+    method public void setStatusCallback(android.support.v7.media.RemotePlaybackClient.StatusCallback);
+    method public void startSession(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+    method public void stop(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+  }
+
+  public static abstract class RemotePlaybackClient.ActionCallback {
+    ctor public RemotePlaybackClient.ActionCallback();
+    method public void onError(java.lang.String, int, android.os.Bundle);
+  }
+
+  public static abstract class RemotePlaybackClient.ItemActionCallback extends android.support.v7.media.RemotePlaybackClient.ActionCallback {
+    ctor public RemotePlaybackClient.ItemActionCallback();
+    method public void onResult(android.os.Bundle, java.lang.String, android.support.v7.media.MediaSessionStatus, java.lang.String, android.support.v7.media.MediaItemStatus);
+  }
+
+  public static abstract interface RemotePlaybackClient.OnMessageReceivedListener {
+    method public abstract void onMessageReceived(java.lang.String, android.os.Bundle);
+  }
+
+  public static abstract class RemotePlaybackClient.SessionActionCallback extends android.support.v7.media.RemotePlaybackClient.ActionCallback {
+    ctor public RemotePlaybackClient.SessionActionCallback();
+    method public void onResult(android.os.Bundle, java.lang.String, android.support.v7.media.MediaSessionStatus);
+  }
+
+  public static abstract class RemotePlaybackClient.StatusCallback {
+    ctor public RemotePlaybackClient.StatusCallback();
+    method public void onItemStatusChanged(android.os.Bundle, java.lang.String, android.support.v7.media.MediaSessionStatus, java.lang.String, android.support.v7.media.MediaItemStatus);
+    method public void onSessionChanged(java.lang.String);
+    method public void onSessionStatusChanged(android.os.Bundle, java.lang.String, android.support.v7.media.MediaSessionStatus);
+  }
+
+}
+
+package android.support.v7.preference {
+
+  public class CheckBoxPreference extends android.support.v7.preference.TwoStatePreference {
+    ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet);
+    ctor public CheckBoxPreference(android.content.Context);
+  }
+
+  public abstract class DialogPreference extends android.support.v7.preference.Preference {
+    ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public DialogPreference(android.content.Context, android.util.AttributeSet);
+    ctor public DialogPreference(android.content.Context);
+    method public android.graphics.drawable.Drawable getDialogIcon();
+    method public int getDialogLayoutResource();
+    method public java.lang.CharSequence getDialogMessage();
+    method public java.lang.CharSequence getDialogTitle();
+    method public java.lang.CharSequence getNegativeButtonText();
+    method public java.lang.CharSequence getPositiveButtonText();
+    method public void setDialogIcon(android.graphics.drawable.Drawable);
+    method public void setDialogIcon(int);
+    method public void setDialogLayoutResource(int);
+    method public void setDialogMessage(java.lang.CharSequence);
+    method public void setDialogMessage(int);
+    method public void setDialogTitle(java.lang.CharSequence);
+    method public void setDialogTitle(int);
+    method public void setNegativeButtonText(java.lang.CharSequence);
+    method public void setNegativeButtonText(int);
+    method public void setPositiveButtonText(java.lang.CharSequence);
+    method public void setPositiveButtonText(int);
+  }
+
+  public static abstract interface DialogPreference.TargetFragment {
+    method public abstract android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+  }
+
+  public class DropDownPreference extends android.support.v7.preference.ListPreference {
+    ctor public DropDownPreference(android.content.Context);
+    ctor public DropDownPreference(android.content.Context, android.util.AttributeSet);
+    ctor public DropDownPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public DropDownPreference(android.content.Context, android.util.AttributeSet, int, int);
+    method protected android.widget.ArrayAdapter createAdapter();
+  }
+
+  public class EditTextPreference extends android.support.v7.preference.DialogPreference {
+    ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public EditTextPreference(android.content.Context, android.util.AttributeSet);
+    ctor public EditTextPreference(android.content.Context);
+    method public java.lang.String getText();
+    method public void setText(java.lang.String);
+  }
+
+  public class EditTextPreferenceDialogFragmentCompat extends android.support.v7.preference.PreferenceDialogFragmentCompat {
+    ctor public EditTextPreferenceDialogFragmentCompat();
+    method public static android.support.v7.preference.EditTextPreferenceDialogFragmentCompat newInstance(java.lang.String);
+    method public void onDialogClosed(boolean);
+  }
+
+  public class ListPreference extends android.support.v7.preference.DialogPreference {
+    ctor public ListPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public ListPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public ListPreference(android.content.Context, android.util.AttributeSet);
+    ctor public ListPreference(android.content.Context);
+    method public int findIndexOfValue(java.lang.String);
+    method public java.lang.CharSequence[] getEntries();
+    method public java.lang.CharSequence getEntry();
+    method public java.lang.CharSequence[] getEntryValues();
+    method public java.lang.String getValue();
+    method public void setEntries(java.lang.CharSequence[]);
+    method public void setEntries(int);
+    method public void setEntryValues(java.lang.CharSequence[]);
+    method public void setEntryValues(int);
+    method public void setValue(java.lang.String);
+    method public void setValueIndex(int);
+  }
+
+  public class ListPreferenceDialogFragmentCompat extends android.support.v7.preference.PreferenceDialogFragmentCompat {
+    ctor public ListPreferenceDialogFragmentCompat();
+    method public static android.support.v7.preference.ListPreferenceDialogFragmentCompat newInstance(java.lang.String);
+    method public void onDialogClosed(boolean);
+  }
+
+  public class MultiSelectListPreferenceDialogFragmentCompat extends android.support.v7.preference.PreferenceDialogFragmentCompat {
+    ctor public MultiSelectListPreferenceDialogFragmentCompat();
+    method public static android.support.v7.preference.MultiSelectListPreferenceDialogFragmentCompat newInstance(java.lang.String);
+    method public void onDialogClosed(boolean);
+  }
+
+  public class Preference implements java.lang.Comparable {
+    ctor public Preference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public Preference(android.content.Context, android.util.AttributeSet, int);
+    ctor public Preference(android.content.Context, android.util.AttributeSet);
+    ctor public Preference(android.content.Context);
+    method public boolean callChangeListener(java.lang.Object);
+    method public int compareTo(android.support.v7.preference.Preference);
+    method protected android.support.v7.preference.Preference findPreferenceInHierarchy(java.lang.String);
+    method public android.content.Context getContext();
+    method public java.lang.String getDependency();
+    method public android.os.Bundle getExtras();
+    method public java.lang.String getFragment();
+    method public android.graphics.drawable.Drawable getIcon();
+    method public android.content.Intent getIntent();
+    method public java.lang.String getKey();
+    method public final int getLayoutResource();
+    method public android.support.v7.preference.Preference.OnPreferenceChangeListener getOnPreferenceChangeListener();
+    method public android.support.v7.preference.Preference.OnPreferenceClickListener getOnPreferenceClickListener();
+    method public int getOrder();
+    method protected boolean getPersistedBoolean(boolean);
+    method protected float getPersistedFloat(float);
+    method protected int getPersistedInt(int);
+    method protected long getPersistedLong(long);
+    method protected java.lang.String getPersistedString(java.lang.String);
+    method public android.support.v7.preference.PreferenceManager getPreferenceManager();
+    method public android.content.SharedPreferences getSharedPreferences();
+    method public boolean getShouldDisableView();
+    method public java.lang.CharSequence getSummary();
+    method public java.lang.CharSequence getTitle();
+    method public final int getWidgetLayoutResource();
+    method public boolean hasKey();
+    method public boolean isEnabled();
+    method public boolean isPersistent();
+    method public boolean isSelectable();
+    method public final boolean isVisible();
+    method protected void notifyChanged();
+    method public void notifyDependencyChange(boolean);
+    method protected void notifyHierarchyChanged();
+    method public void onAttached();
+    method protected void onAttachedToHierarchy(android.support.v7.preference.PreferenceManager);
+    method public void onBindViewHolder(android.support.v7.preference.PreferenceViewHolder);
+    method protected void onClick();
+    method public void onDependencyChanged(android.support.v7.preference.Preference, boolean);
+    method public void onDetached();
+    method protected java.lang.Object onGetDefaultValue(android.content.res.TypedArray, int);
+    method public void onInitializeAccessibilityNodeInfo(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onParentChanged(android.support.v7.preference.Preference, boolean);
+    method protected void onPrepareForRemoval();
+    method protected void onRestoreInstanceState(android.os.Parcelable);
+    method protected android.os.Parcelable onSaveInstanceState();
+    method protected void onSetInitialValue(boolean, java.lang.Object);
+    method public android.os.Bundle peekExtras();
+    method protected boolean persistBoolean(boolean);
+    method protected boolean persistFloat(float);
+    method protected boolean persistInt(int);
+    method protected boolean persistLong(long);
+    method protected boolean persistString(java.lang.String);
+    method public void restoreHierarchyState(android.os.Bundle);
+    method public void saveHierarchyState(android.os.Bundle);
+    method public void setDefaultValue(java.lang.Object);
+    method public void setDependency(java.lang.String);
+    method public void setEnabled(boolean);
+    method public void setFragment(java.lang.String);
+    method public void setIcon(android.graphics.drawable.Drawable);
+    method public void setIcon(int);
+    method public void setIntent(android.content.Intent);
+    method public void setKey(java.lang.String);
+    method public void setLayoutResource(int);
+    method public void setOnPreferenceChangeListener(android.support.v7.preference.Preference.OnPreferenceChangeListener);
+    method public void setOnPreferenceClickListener(android.support.v7.preference.Preference.OnPreferenceClickListener);
+    method public void setOrder(int);
+    method public void setPersistent(boolean);
+    method public void setSelectable(boolean);
+    method public void setShouldDisableView(boolean);
+    method public void setSummary(java.lang.CharSequence);
+    method public void setSummary(int);
+    method public void setTitle(java.lang.CharSequence);
+    method public void setTitle(int);
+    method public void setViewId(int);
+    method public final void setVisible(boolean);
+    method public void setWidgetLayoutResource(int);
+    method public boolean shouldDisableDependents();
+    method protected boolean shouldPersist();
+    field public static final int DEFAULT_ORDER = 2147483647; // 0x7fffffff
+  }
+
+  public static class Preference.BaseSavedState extends android.view.AbsSavedState {
+    ctor public Preference.BaseSavedState(android.os.Parcel);
+    ctor public Preference.BaseSavedState(android.os.Parcelable);
+    field public static final android.os.Parcelable.Creator<android.support.v7.preference.Preference.BaseSavedState> CREATOR;
+  }
+
+  public static abstract interface Preference.OnPreferenceChangeListener {
+    method public abstract boolean onPreferenceChange(android.support.v7.preference.Preference, java.lang.Object);
+  }
+
+  public static abstract interface Preference.OnPreferenceClickListener {
+    method public abstract boolean onPreferenceClick(android.support.v7.preference.Preference);
+  }
+
+  public class PreferenceCategory extends android.support.v7.preference.PreferenceGroup {
+    ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int);
+    ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet);
+    ctor public PreferenceCategory(android.content.Context);
+  }
+
+  public abstract class PreferenceDialogFragmentCompat extends android.support.v4.app.DialogFragment implements android.content.DialogInterface.OnClickListener {
+    ctor public PreferenceDialogFragmentCompat();
+    method public android.support.v7.preference.DialogPreference getPreference();
+    method protected void onBindDialogView(android.view.View);
+    method public void onClick(android.content.DialogInterface, int);
+    method protected android.view.View onCreateDialogView(android.content.Context);
+    method public abstract void onDialogClosed(boolean);
+    method protected void onPrepareDialogBuilder(android.support.v7.app.AlertDialog.Builder);
+    field protected static final java.lang.String ARG_KEY = "key";
+  }
+
+  public abstract class PreferenceFragmentCompat extends android.support.v4.app.Fragment implements android.support.v7.preference.DialogPreference.TargetFragment android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener {
+    ctor public PreferenceFragmentCompat();
+    method public void addPreferencesFromResource(int);
+    method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+    method public final android.support.v7.widget.RecyclerView getListView();
+    method public android.support.v7.preference.PreferenceManager getPreferenceManager();
+    method public android.support.v7.preference.PreferenceScreen getPreferenceScreen();
+    method protected android.support.v7.widget.RecyclerView.Adapter onCreateAdapter(android.support.v7.preference.PreferenceScreen);
+    method public android.support.v7.widget.RecyclerView.LayoutManager onCreateLayoutManager();
+    method public abstract void onCreatePreferences(android.os.Bundle, java.lang.String);
+    method public android.support.v7.widget.RecyclerView onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+    method public void onDisplayPreferenceDialog(android.support.v7.preference.Preference);
+    method public void onNavigateToScreen(android.support.v7.preference.PreferenceScreen);
+    method public boolean onPreferenceTreeClick(android.support.v7.preference.Preference);
+    method public void scrollToPreference(java.lang.String);
+    method public void scrollToPreference(android.support.v7.preference.Preference);
+    method public void setDivider(android.graphics.drawable.Drawable);
+    method public void setDividerHeight(int);
+    method public void setPreferenceScreen(android.support.v7.preference.PreferenceScreen);
+    method public void setPreferencesFromResource(int, java.lang.String);
+    field public static final java.lang.String ARG_PREFERENCE_ROOT = "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT";
+  }
+
+  public static abstract interface PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {
+    method public abstract boolean onPreferenceDisplayDialog(android.support.v7.preference.PreferenceFragmentCompat, android.support.v7.preference.Preference);
+  }
+
+  public static abstract interface PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
+    method public abstract boolean onPreferenceStartFragment(android.support.v7.preference.PreferenceFragmentCompat, android.support.v7.preference.Preference);
+  }
+
+  public static abstract interface PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
+    method public abstract boolean onPreferenceStartScreen(android.support.v7.preference.PreferenceFragmentCompat, android.support.v7.preference.PreferenceScreen);
+  }
+
+  public abstract class PreferenceGroup extends android.support.v7.preference.Preference {
+    ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int);
+    ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet);
+    method public void addItemFromInflater(android.support.v7.preference.Preference);
+    method public boolean addPreference(android.support.v7.preference.Preference);
+    method protected void dispatchRestoreInstanceState(android.os.Bundle);
+    method protected void dispatchSaveInstanceState(android.os.Bundle);
+    method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+    method public android.support.v7.preference.Preference getPreference(int);
+    method public int getPreferenceCount();
+    method protected boolean isOnSameScreenAsChildren();
+    method public boolean isOrderingAsAdded();
+    method protected boolean onPrepareAddPreference(android.support.v7.preference.Preference);
+    method public void removeAll();
+    method public boolean removePreference(android.support.v7.preference.Preference);
+    method public void setOrderingAsAdded(boolean);
+  }
+
+  public static abstract interface PreferenceGroup.PreferencePositionCallback {
+    method public abstract int getPreferenceAdapterPosition(java.lang.String);
+    method public abstract int getPreferenceAdapterPosition(android.support.v7.preference.Preference);
+  }
+
+  public class PreferenceManager {
+    method public android.support.v7.preference.PreferenceScreen createPreferenceScreen(android.content.Context);
+    method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+    method public android.content.Context getContext();
+    method public static android.content.SharedPreferences getDefaultSharedPreferences(android.content.Context);
+    method public android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener getOnDisplayPreferenceDialogListener();
+    method public android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener getOnNavigateToScreenListener();
+    method public android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener getOnPreferenceTreeClickListener();
+    method public android.support.v7.preference.PreferenceManager.PreferenceComparisonCallback getPreferenceComparisonCallback();
+    method public android.support.v7.preference.PreferenceScreen getPreferenceScreen();
+    method public android.content.SharedPreferences getSharedPreferences();
+    method public int getSharedPreferencesMode();
+    method public java.lang.String getSharedPreferencesName();
+    method public boolean isStorageDefault();
+    method public boolean isStorageDeviceProtected();
+    method public static void setDefaultValues(android.content.Context, int, boolean);
+    method public static void setDefaultValues(android.content.Context, java.lang.String, int, int, boolean);
+    method public void setOnDisplayPreferenceDialogListener(android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener);
+    method public void setOnNavigateToScreenListener(android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener);
+    method public void setOnPreferenceTreeClickListener(android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener);
+    method public void setPreferenceComparisonCallback(android.support.v7.preference.PreferenceManager.PreferenceComparisonCallback);
+    method public boolean setPreferences(android.support.v7.preference.PreferenceScreen);
+    method public void setSharedPreferencesMode(int);
+    method public void setSharedPreferencesName(java.lang.String);
+    method public void setStorageDefault();
+    method public void setStorageDeviceProtected();
+    method public void showDialog(android.support.v7.preference.Preference);
+    field public static final java.lang.String KEY_HAS_SET_DEFAULT_VALUES = "_has_set_default_values";
+  }
+
+  public static abstract interface PreferenceManager.OnDisplayPreferenceDialogListener {
+    method public abstract void onDisplayPreferenceDialog(android.support.v7.preference.Preference);
+  }
+
+  public static abstract interface PreferenceManager.OnNavigateToScreenListener {
+    method public abstract void onNavigateToScreen(android.support.v7.preference.PreferenceScreen);
+  }
+
+  public static abstract interface PreferenceManager.OnPreferenceTreeClickListener {
+    method public abstract boolean onPreferenceTreeClick(android.support.v7.preference.Preference);
+  }
+
+  public static abstract class PreferenceManager.PreferenceComparisonCallback {
+    ctor public PreferenceManager.PreferenceComparisonCallback();
+    method public abstract boolean arePreferenceContentsTheSame(android.support.v7.preference.Preference, android.support.v7.preference.Preference);
+    method public abstract boolean arePreferenceItemsTheSame(android.support.v7.preference.Preference, android.support.v7.preference.Preference);
+  }
+
+  public static class PreferenceManager.SimplePreferenceComparisonCallback extends android.support.v7.preference.PreferenceManager.PreferenceComparisonCallback {
+    ctor public PreferenceManager.SimplePreferenceComparisonCallback();
+    method public boolean arePreferenceContentsTheSame(android.support.v7.preference.Preference, android.support.v7.preference.Preference);
+    method public boolean arePreferenceItemsTheSame(android.support.v7.preference.Preference, android.support.v7.preference.Preference);
+  }
+
+  public final class PreferenceScreen extends android.support.v7.preference.PreferenceGroup {
+    method public void setShouldUseGeneratedIds(boolean);
+    method public boolean shouldUseGeneratedIds();
+  }
+
+  public class PreferenceViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder {
+    method public android.view.View findViewById(int);
+    method public boolean isDividerAllowedAbove();
+    method public boolean isDividerAllowedBelow();
+    method public void setDividerAllowedAbove(boolean);
+    method public void setDividerAllowedBelow(boolean);
+  }
+
+  public class SeekBarPreference extends android.support.v7.preference.Preference {
+    ctor public SeekBarPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public SeekBarPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public SeekBarPreference(android.content.Context, android.util.AttributeSet);
+    ctor public SeekBarPreference(android.content.Context);
+    method public int getMax();
+    method public int getMin();
+    method public final int getSeekBarIncrement();
+    method public int getValue();
+    method public boolean isAdjustable();
+    method public void setAdjustable(boolean);
+    method public final void setMax(int);
+    method public void setMin(int);
+    method public final void setSeekBarIncrement(int);
+    method public void setValue(int);
+  }
+
+  public class SwitchPreferenceCompat extends android.support.v7.preference.TwoStatePreference {
+    ctor public SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int);
+    ctor public SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet);
+    ctor public SwitchPreferenceCompat(android.content.Context);
+    method public java.lang.CharSequence getSwitchTextOff();
+    method public java.lang.CharSequence getSwitchTextOn();
+    method public void setSwitchTextOff(java.lang.CharSequence);
+    method public void setSwitchTextOff(int);
+    method public void setSwitchTextOn(java.lang.CharSequence);
+    method public void setSwitchTextOn(int);
+  }
+
+  public abstract class TwoStatePreference extends android.support.v7.preference.Preference {
+    ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet);
+    ctor public TwoStatePreference(android.content.Context);
+    method public boolean getDisableDependentsState();
+    method public java.lang.CharSequence getSummaryOff();
+    method public java.lang.CharSequence getSummaryOn();
+    method public boolean isChecked();
+    method public void setChecked(boolean);
+    method public void setDisableDependentsState(boolean);
+    method public void setSummaryOff(java.lang.CharSequence);
+    method public void setSummaryOff(int);
+    method public void setSummaryOn(java.lang.CharSequence);
+    method public void setSummaryOn(int);
+    method protected void syncSummaryView(android.support.v7.preference.PreferenceViewHolder);
+    field protected boolean mChecked;
+  }
+
+}
+
+package android.support.v7.util {
+
+  public class AsyncListUtil<T> {
+    ctor public AsyncListUtil(java.lang.Class<T>, int, android.support.v7.util.AsyncListUtil.DataCallback<T>, android.support.v7.util.AsyncListUtil.ViewCallback);
+    method public T getItem(int);
+    method public int getItemCount();
+    method public void onRangeChanged();
+    method public void refresh();
+  }
+
+  public static abstract class AsyncListUtil.DataCallback<T> {
+    ctor public AsyncListUtil.DataCallback();
+    method public abstract void fillData(T[], int, int);
+    method public int getMaxCachedTiles();
+    method public void recycleData(T[], int);
+    method public abstract int refreshData();
+  }
+
+  public static abstract class AsyncListUtil.ViewCallback {
+    ctor public AsyncListUtil.ViewCallback();
+    method public void extendRangeInto(int[], int[], int);
+    method public abstract void getItemRangeInto(int[]);
+    method public abstract void onDataRefresh();
+    method public abstract void onItemLoaded(int);
+    field public static final int HINT_SCROLL_ASC = 2; // 0x2
+    field public static final int HINT_SCROLL_DESC = 1; // 0x1
+    field public static final int HINT_SCROLL_NONE = 0; // 0x0
+  }
+
+  public class BatchingListUpdateCallback implements android.support.v7.util.ListUpdateCallback {
+    ctor public BatchingListUpdateCallback(android.support.v7.util.ListUpdateCallback);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int, java.lang.Object);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public class DiffUtil {
+    method public static android.support.v7.util.DiffUtil.DiffResult calculateDiff(android.support.v7.util.DiffUtil.Callback);
+    method public static android.support.v7.util.DiffUtil.DiffResult calculateDiff(android.support.v7.util.DiffUtil.Callback, boolean);
+  }
+
+  public static abstract class DiffUtil.Callback {
+    ctor public DiffUtil.Callback();
+    method public abstract boolean areContentsTheSame(int, int);
+    method public abstract boolean areItemsTheSame(int, int);
+    method public java.lang.Object getChangePayload(int, int);
+    method public abstract int getNewListSize();
+    method public abstract int getOldListSize();
+  }
+
+  public static class DiffUtil.DiffResult {
+    method public void dispatchUpdatesTo(android.support.v7.widget.RecyclerView.Adapter);
+    method public void dispatchUpdatesTo(android.support.v7.util.ListUpdateCallback);
+  }
+
+  public abstract interface ListUpdateCallback {
+    method public abstract void onChanged(int, int, java.lang.Object);
+    method public abstract void onInserted(int, int);
+    method public abstract void onMoved(int, int);
+    method public abstract void onRemoved(int, int);
+  }
+
+  public class SortedList<T> {
+    ctor public SortedList(java.lang.Class<T>, android.support.v7.util.SortedList.Callback<T>);
+    ctor public SortedList(java.lang.Class<T>, android.support.v7.util.SortedList.Callback<T>, int);
+    method public int add(T);
+    method public void addAll(T[], boolean);
+    method public void addAll(T...);
+    method public void addAll(java.util.Collection<T>);
+    method public void beginBatchedUpdates();
+    method public void clear();
+    method public void endBatchedUpdates();
+    method public T get(int) throws java.lang.IndexOutOfBoundsException;
+    method public int indexOf(T);
+    method public void recalculatePositionOfItemAt(int);
+    method public boolean remove(T);
+    method public T removeItemAt(int);
+    method public int size();
+    method public void updateItemAt(int, T);
+    field public static final int INVALID_POSITION = -1; // 0xffffffff
+  }
+
+  public static class SortedList.BatchedCallback<T2> extends android.support.v7.util.SortedList.Callback {
+    ctor public SortedList.BatchedCallback(android.support.v7.util.SortedList.Callback<T2>);
+    method public boolean areContentsTheSame(T2, T2);
+    method public boolean areItemsTheSame(T2, T2);
+    method public int compare(T2, T2);
+    method public void dispatchLastEvent();
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+  public static abstract class SortedList.Callback<T2> implements java.util.Comparator android.support.v7.util.ListUpdateCallback {
+    ctor public SortedList.Callback();
+    method public abstract boolean areContentsTheSame(T2, T2);
+    method public abstract boolean areItemsTheSame(T2, T2);
+    method public abstract int compare(T2, T2);
+    method public abstract void onChanged(int, int);
+    method public void onChanged(int, int, java.lang.Object);
+  }
+
+}
+
+package android.support.v7.view {
+
+  public abstract class ActionMode {
+    ctor public ActionMode();
+    method public abstract void finish();
+    method public abstract android.view.View getCustomView();
+    method public abstract android.view.Menu getMenu();
+    method public abstract android.view.MenuInflater getMenuInflater();
+    method public abstract java.lang.CharSequence getSubtitle();
+    method public java.lang.Object getTag();
+    method public abstract java.lang.CharSequence getTitle();
+    method public boolean getTitleOptionalHint();
+    method public abstract void invalidate();
+    method public boolean isTitleOptional();
+    method public abstract void setCustomView(android.view.View);
+    method public abstract void setSubtitle(java.lang.CharSequence);
+    method public abstract void setSubtitle(int);
+    method public void setTag(java.lang.Object);
+    method public abstract void setTitle(java.lang.CharSequence);
+    method public abstract void setTitle(int);
+    method public void setTitleOptionalHint(boolean);
+  }
+
+  public static abstract interface ActionMode.Callback {
+    method public abstract boolean onActionItemClicked(android.support.v7.view.ActionMode, android.view.MenuItem);
+    method public abstract boolean onCreateActionMode(android.support.v7.view.ActionMode, android.view.Menu);
+    method public abstract void onDestroyActionMode(android.support.v7.view.ActionMode);
+    method public abstract boolean onPrepareActionMode(android.support.v7.view.ActionMode, android.view.Menu);
+  }
+
+  public abstract interface CollapsibleActionView {
+    method public abstract void onActionViewCollapsed();
+    method public abstract void onActionViewExpanded();
+  }
+
+}
+
+package android.support.v7.widget {
+
+  public class ActionMenuView extends android.support.v7.widget.LinearLayoutCompat {
+    ctor public ActionMenuView(android.content.Context);
+    ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
+    method public void dismissPopupMenus();
+    method public android.view.Menu getMenu();
+    method public android.graphics.drawable.Drawable getOverflowIcon();
+    method public int getPopupTheme();
+    method public boolean hideOverflowMenu();
+    method public boolean isOverflowMenuShowing();
+    method public void onConfigurationChanged(android.content.res.Configuration);
+    method public void onDetachedFromWindow();
+    method public void setOnMenuItemClickListener(android.support.v7.widget.ActionMenuView.OnMenuItemClickListener);
+    method public void setOverflowIcon(android.graphics.drawable.Drawable);
+    method public void setPopupTheme(int);
+    method public boolean showOverflowMenu();
+  }
+
+  public static class ActionMenuView.LayoutParams extends android.support.v7.widget.LinearLayoutCompat.LayoutParams {
+    ctor public ActionMenuView.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public ActionMenuView.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public ActionMenuView.LayoutParams(android.support.v7.widget.ActionMenuView.LayoutParams);
+    ctor public ActionMenuView.LayoutParams(int, int);
+    field public int cellsUsed;
+    field public boolean expandable;
+    field public int extraPixels;
+    field public boolean isOverflowButton;
+    field public boolean preventEdgeOffset;
+  }
+
+  public static abstract interface ActionMenuView.OnMenuItemClickListener {
+    method public abstract boolean onMenuItemClick(android.view.MenuItem);
+  }
+
+  public class AppCompatAutoCompleteTextView extends android.widget.AutoCompleteTextView implements android.support.v4.view.TintableBackgroundView {
+    ctor public AppCompatAutoCompleteTextView(android.content.Context);
+    ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatButton extends android.widget.Button implements android.support.v4.view.TintableBackgroundView {
+    ctor public AppCompatButton(android.content.Context);
+    ctor public AppCompatButton(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatButton(android.content.Context, android.util.AttributeSet, int);
+    method public void setSupportAllCaps(boolean);
+  }
+
+  public class AppCompatCheckBox extends android.widget.CheckBox implements android.support.v4.widget.TintableCompoundButton {
+    ctor public AppCompatCheckBox(android.content.Context);
+    ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatCheckedTextView extends android.widget.CheckedTextView {
+    ctor public AppCompatCheckedTextView(android.content.Context);
+    ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatEditText extends android.widget.EditText implements android.support.v4.view.TintableBackgroundView {
+    ctor public AppCompatEditText(android.content.Context);
+    ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatImageButton extends android.widget.ImageButton implements android.support.v4.view.TintableBackgroundView {
+    ctor public AppCompatImageButton(android.content.Context);
+    ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatImageView extends android.widget.ImageView implements android.support.v4.view.TintableBackgroundView {
+    ctor public AppCompatImageView(android.content.Context);
+    ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatMultiAutoCompleteTextView extends android.widget.MultiAutoCompleteTextView implements android.support.v4.view.TintableBackgroundView {
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context);
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatRadioButton extends android.widget.RadioButton implements android.support.v4.widget.TintableCompoundButton {
+    ctor public AppCompatRadioButton(android.content.Context);
+    ctor public AppCompatRadioButton(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatRadioButton(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatRatingBar extends android.widget.RatingBar {
+    ctor public AppCompatRatingBar(android.content.Context);
+    ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatSeekBar extends android.widget.SeekBar {
+    ctor public AppCompatSeekBar(android.content.Context);
+    ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class AppCompatSpinner extends android.widget.Spinner implements android.support.v4.view.TintableBackgroundView {
+    ctor public AppCompatSpinner(android.content.Context);
+    ctor public AppCompatSpinner(android.content.Context, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet, int, int, android.content.res.Resources.Theme);
+  }
+
+  public class AppCompatTextView extends android.widget.TextView implements android.support.v4.view.TintableBackgroundView {
+    ctor public AppCompatTextView(android.content.Context);
+    ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet);
+    ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet, int);
+  }
+
+  public class CardView extends android.widget.FrameLayout {
+    ctor public CardView(android.content.Context);
+    ctor public CardView(android.content.Context, android.util.AttributeSet);
+    ctor public CardView(android.content.Context, android.util.AttributeSet, int);
+    method public android.content.res.ColorStateList getCardBackgroundColor();
+    method public float getCardElevation();
+    method public int getContentPaddingBottom();
+    method public int getContentPaddingLeft();
+    method public int getContentPaddingRight();
+    method public int getContentPaddingTop();
+    method public float getMaxCardElevation();
+    method public boolean getPreventCornerOverlap();
+    method public float getRadius();
+    method public boolean getUseCompatPadding();
+    method public void setCardBackgroundColor(int);
+    method public void setCardBackgroundColor(android.content.res.ColorStateList);
+    method public void setCardElevation(float);
+    method public void setContentPadding(int, int, int, int);
+    method public void setMaxCardElevation(float);
+    method public void setPreventCornerOverlap(boolean);
+    method public void setRadius(float);
+    method public void setUseCompatPadding(boolean);
+  }
+
+  public class DefaultItemAnimator extends android.support.v7.widget.SimpleItemAnimator {
+    ctor public DefaultItemAnimator();
+    method public boolean animateAdd(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public boolean animateChange(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder, int, int, int, int);
+    method public boolean animateMove(android.support.v7.widget.RecyclerView.ViewHolder, int, int, int, int);
+    method public boolean animateRemove(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void endAnimation(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void endAnimations();
+    method public boolean isRunning();
+    method public void runPendingAnimations();
+  }
+
+  public class DividerItemDecoration extends android.support.v7.widget.RecyclerView.ItemDecoration {
+    ctor public DividerItemDecoration(android.content.Context, int);
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setOrientation(int);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public class GridLayout extends android.view.ViewGroup {
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet);
+    ctor public GridLayout(android.content.Context);
+    method public int getAlignmentMode();
+    method public int getColumnCount();
+    method public int getOrientation();
+    method public android.util.Printer getPrinter();
+    method public int getRowCount();
+    method public boolean getUseDefaultMargins();
+    method public boolean isColumnOrderPreserved();
+    method public boolean isRowOrderPreserved();
+    method protected void onLayout(boolean, int, int, int, int);
+    method public void setAlignmentMode(int);
+    method public void setColumnCount(int);
+    method public void setColumnOrderPreserved(boolean);
+    method public void setOrientation(int);
+    method public void setPrinter(android.util.Printer);
+    method public void setRowCount(int);
+    method public void setRowOrderPreserved(boolean);
+    method public void setUseDefaultMargins(boolean);
+    method public static android.support.v7.widget.GridLayout.Spec spec(int, int, android.support.v7.widget.GridLayout.Alignment, float);
+    method public static android.support.v7.widget.GridLayout.Spec spec(int, android.support.v7.widget.GridLayout.Alignment, float);
+    method public static android.support.v7.widget.GridLayout.Spec spec(int, int, float);
+    method public static android.support.v7.widget.GridLayout.Spec spec(int, float);
+    method public static android.support.v7.widget.GridLayout.Spec spec(int, int, android.support.v7.widget.GridLayout.Alignment);
+    method public static android.support.v7.widget.GridLayout.Spec spec(int, android.support.v7.widget.GridLayout.Alignment);
+    method public static android.support.v7.widget.GridLayout.Spec spec(int, int);
+    method public static android.support.v7.widget.GridLayout.Spec spec(int);
+    field public static final int ALIGN_BOUNDS = 0; // 0x0
+    field public static final int ALIGN_MARGINS = 1; // 0x1
+    field public static final android.support.v7.widget.GridLayout.Alignment BASELINE;
+    field public static final android.support.v7.widget.GridLayout.Alignment BOTTOM;
+    field public static final android.support.v7.widget.GridLayout.Alignment CENTER;
+    field public static final android.support.v7.widget.GridLayout.Alignment END;
+    field public static final android.support.v7.widget.GridLayout.Alignment FILL;
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final android.support.v7.widget.GridLayout.Alignment LEFT;
+    field public static final android.support.v7.widget.GridLayout.Alignment RIGHT;
+    field public static final android.support.v7.widget.GridLayout.Alignment START;
+    field public static final android.support.v7.widget.GridLayout.Alignment TOP;
+    field public static final int UNDEFINED = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static abstract class GridLayout.Alignment {
+  }
+
+  public static class GridLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public GridLayout.LayoutParams(android.support.v7.widget.GridLayout.Spec, android.support.v7.widget.GridLayout.Spec);
+    ctor public GridLayout.LayoutParams();
+    ctor public GridLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public GridLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public GridLayout.LayoutParams(android.support.v7.widget.GridLayout.LayoutParams);
+    ctor public GridLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+    method public void setGravity(int);
+    field public android.support.v7.widget.GridLayout.Spec columnSpec;
+    field public android.support.v7.widget.GridLayout.Spec rowSpec;
+  }
+
+  public static class GridLayout.Spec {
+    method public android.support.v7.widget.GridLayout.Alignment getAbsoluteAlignment(boolean);
+  }
+
+  public class GridLayoutManager extends android.support.v7.widget.LinearLayoutManager {
+    ctor public GridLayoutManager(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public GridLayoutManager(android.content.Context, int);
+    ctor public GridLayoutManager(android.content.Context, int, int, boolean);
+    method public int getSpanCount();
+    method public android.support.v7.widget.GridLayoutManager.SpanSizeLookup getSpanSizeLookup();
+    method public void setSpanCount(int);
+    method public void setSpanSizeLookup(android.support.v7.widget.GridLayoutManager.SpanSizeLookup);
+    field public static final int DEFAULT_SPAN_COUNT = -1; // 0xffffffff
+  }
+
+  public static final class GridLayoutManager.DefaultSpanSizeLookup extends android.support.v7.widget.GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.DefaultSpanSizeLookup();
+    method public int getSpanSize(int);
+  }
+
+  public static class GridLayoutManager.LayoutParams extends android.support.v7.widget.RecyclerView.LayoutParams {
+    ctor public GridLayoutManager.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public GridLayoutManager.LayoutParams(int, int);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public GridLayoutManager.LayoutParams(android.support.v7.widget.RecyclerView.LayoutParams);
+    method public int getSpanIndex();
+    method public int getSpanSize();
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+  public static abstract class GridLayoutManager.SpanSizeLookup {
+    ctor public GridLayoutManager.SpanSizeLookup();
+    method public int getSpanGroupIndex(int, int);
+    method public int getSpanIndex(int, int);
+    method public abstract int getSpanSize(int);
+    method public void invalidateSpanIndexCache();
+    method public boolean isSpanIndexCacheEnabled();
+    method public void setSpanIndexCacheEnabled(boolean);
+  }
+
+  public class LinearLayoutCompat extends android.view.ViewGroup {
+    ctor public LinearLayoutCompat(android.content.Context);
+    ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet);
+    ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet, int);
+    method public int getBaselineAlignedChildIndex();
+    method public android.graphics.drawable.Drawable getDividerDrawable();
+    method public int getDividerPadding();
+    method public int getGravity();
+    method public int getOrientation();
+    method public int getShowDividers();
+    method public float getWeightSum();
+    method public boolean isBaselineAligned();
+    method public boolean isMeasureWithLargestChildEnabled();
+    method protected void onLayout(boolean, int, int, int, int);
+    method public void setBaselineAligned(boolean);
+    method public void setBaselineAlignedChildIndex(int);
+    method public void setDividerDrawable(android.graphics.drawable.Drawable);
+    method public void setDividerPadding(int);
+    method public void setGravity(int);
+    method public void setHorizontalGravity(int);
+    method public void setMeasureWithLargestChildEnabled(boolean);
+    method public void setOrientation(int);
+    method public void setShowDividers(int);
+    method public void setVerticalGravity(int);
+    method public void setWeightSum(float);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int SHOW_DIVIDER_BEGINNING = 1; // 0x1
+    field public static final int SHOW_DIVIDER_END = 4; // 0x4
+    field public static final int SHOW_DIVIDER_MIDDLE = 2; // 0x2
+    field public static final int SHOW_DIVIDER_NONE = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static class LinearLayoutCompat.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public LinearLayoutCompat.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public LinearLayoutCompat.LayoutParams(int, int);
+    ctor public LinearLayoutCompat.LayoutParams(int, int, float);
+    ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public LinearLayoutCompat.LayoutParams(android.support.v7.widget.LinearLayoutCompat.LayoutParams);
+    field public int gravity;
+    field public float weight;
+  }
+
+  public class LinearLayoutManager extends android.support.v7.widget.RecyclerView.LayoutManager implements android.support.v7.widget.helper.ItemTouchHelper.ViewDropHandler android.support.v7.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public LinearLayoutManager(android.content.Context);
+    ctor public LinearLayoutManager(android.content.Context, int, boolean);
+    ctor public LinearLayoutManager(android.content.Context, android.util.AttributeSet, int, int);
+    method public android.graphics.PointF computeScrollVectorForPosition(int);
+    method public int findFirstCompletelyVisibleItemPosition();
+    method public int findFirstVisibleItemPosition();
+    method public int findLastCompletelyVisibleItemPosition();
+    method public int findLastVisibleItemPosition();
+    method public android.support.v7.widget.RecyclerView.LayoutParams generateDefaultLayoutParams();
+    method protected int getExtraLayoutSpace(android.support.v7.widget.RecyclerView.State);
+    method public int getInitialItemPrefetchCount();
+    method public int getOrientation();
+    method public boolean getRecycleChildrenOnDetach();
+    method public boolean getReverseLayout();
+    method public boolean getStackFromEnd();
+    method protected boolean isLayoutRTL();
+    method public boolean isSmoothScrollbarEnabled();
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setInitialPrefetchItemCount(int);
+    method public void setOrientation(int);
+    method public void setRecycleChildrenOnDetach(boolean);
+    method public void setReverseLayout(boolean);
+    method public void setSmoothScrollbarEnabled(boolean);
+    method public void setStackFromEnd(boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_OFFSET = -2147483648; // 0x80000000
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  protected static class LinearLayoutManager.LayoutChunkResult {
+    ctor protected LinearLayoutManager.LayoutChunkResult();
+    field public int mConsumed;
+    field public boolean mFinished;
+    field public boolean mFocusable;
+    field public boolean mIgnoreConsumed;
+  }
+
+  public class LinearSmoothScroller extends android.support.v7.widget.RecyclerView.SmoothScroller {
+    ctor public LinearSmoothScroller(android.content.Context);
+    method public int calculateDtToFit(int, int, int, int, int);
+    method public int calculateDxToMakeVisible(android.view.View, int);
+    method public int calculateDyToMakeVisible(android.view.View, int);
+    method protected float calculateSpeedPerPixel(android.util.DisplayMetrics);
+    method protected int calculateTimeForDeceleration(int);
+    method protected int calculateTimeForScrolling(int);
+    method public android.graphics.PointF computeScrollVectorForPosition(int);
+    method protected int getHorizontalSnapPreference();
+    method protected int getVerticalSnapPreference();
+    method protected void onSeekTargetStep(int, int, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+    method protected void onStart();
+    method protected void onStop();
+    method protected void onTargetFound(android.view.View, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+    method protected void updateActionForInterimTarget(android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+    field public static final int SNAP_TO_ANY = 0; // 0x0
+    field public static final int SNAP_TO_END = 1; // 0x1
+    field public static final int SNAP_TO_START = -1; // 0xffffffff
+    field protected final android.view.animation.DecelerateInterpolator mDecelerateInterpolator;
+    field protected int mInterimTargetDx;
+    field protected int mInterimTargetDy;
+    field protected final android.view.animation.LinearInterpolator mLinearInterpolator;
+    field protected android.graphics.PointF mTargetVector;
+  }
+
+  public class LinearSnapHelper extends android.support.v7.widget.SnapHelper {
+    ctor public LinearSnapHelper();
+    method public int[] calculateDistanceToFinalSnap(android.support.v7.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View findSnapView(android.support.v7.widget.RecyclerView.LayoutManager);
+    method public int findTargetSnapPosition(android.support.v7.widget.RecyclerView.LayoutManager, int, int);
+  }
+
+  public class ListPopupWindow {
+    ctor public ListPopupWindow(android.content.Context);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet, int);
+    ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet, int, int);
+    method public void clearListSelection();
+    method public android.view.View.OnTouchListener createDragToOpenListener(android.view.View);
+    method public void dismiss();
+    method public android.view.View getAnchorView();
+    method public int getAnimationStyle();
+    method public android.graphics.drawable.Drawable getBackground();
+    method public int getHeight();
+    method public int getHorizontalOffset();
+    method public int getInputMethodMode();
+    method public android.widget.ListView getListView();
+    method public int getPromptPosition();
+    method public java.lang.Object getSelectedItem();
+    method public long getSelectedItemId();
+    method public int getSelectedItemPosition();
+    method public android.view.View getSelectedView();
+    method public int getSoftInputMode();
+    method public int getVerticalOffset();
+    method public int getWidth();
+    method public boolean isInputMethodNotNeeded();
+    method public boolean isModal();
+    method public boolean isShowing();
+    method public boolean onKeyDown(int, android.view.KeyEvent);
+    method public boolean onKeyPreIme(int, android.view.KeyEvent);
+    method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public boolean performItemClick(int);
+    method public void postShow();
+    method public void setAdapter(android.widget.ListAdapter);
+    method public void setAnchorView(android.view.View);
+    method public void setAnimationStyle(int);
+    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
+    method public void setContentWidth(int);
+    method public void setDropDownGravity(int);
+    method public void setHeight(int);
+    method public void setHorizontalOffset(int);
+    method public void setInputMethodMode(int);
+    method public void setListSelector(android.graphics.drawable.Drawable);
+    method public void setModal(boolean);
+    method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener);
+    method public void setOnItemClickListener(android.widget.AdapterView.OnItemClickListener);
+    method public void setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener);
+    method public void setPromptPosition(int);
+    method public void setPromptView(android.view.View);
+    method public void setSelection(int);
+    method public void setSoftInputMode(int);
+    method public void setVerticalOffset(int);
+    method public void setWidth(int);
+    method public void setWindowLayoutType(int);
+    method public void show();
+    field public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; // 0x0
+    field public static final int INPUT_METHOD_NEEDED = 1; // 0x1
+    field public static final int INPUT_METHOD_NOT_NEEDED = 2; // 0x2
+    field public static final int MATCH_PARENT = -1; // 0xffffffff
+    field public static final int POSITION_PROMPT_ABOVE = 0; // 0x0
+    field public static final int POSITION_PROMPT_BELOW = 1; // 0x1
+    field public static final int WRAP_CONTENT = -2; // 0xfffffffe
+  }
+
+  public abstract class OrientationHelper {
+    method public static android.support.v7.widget.OrientationHelper createHorizontalHelper(android.support.v7.widget.RecyclerView.LayoutManager);
+    method public static android.support.v7.widget.OrientationHelper createOrientationHelper(android.support.v7.widget.RecyclerView.LayoutManager, int);
+    method public static android.support.v7.widget.OrientationHelper createVerticalHelper(android.support.v7.widget.RecyclerView.LayoutManager);
+    method public abstract int getDecoratedEnd(android.view.View);
+    method public abstract int getDecoratedMeasurement(android.view.View);
+    method public abstract int getDecoratedMeasurementInOther(android.view.View);
+    method public abstract int getDecoratedStart(android.view.View);
+    method public abstract int getEnd();
+    method public abstract int getEndAfterPadding();
+    method public abstract int getEndPadding();
+    method public abstract int getMode();
+    method public abstract int getModeInOther();
+    method public abstract int getStartAfterPadding();
+    method public abstract int getTotalSpace();
+    method public int getTotalSpaceChange();
+    method public abstract int getTransformedEndWithDecoration(android.view.View);
+    method public abstract int getTransformedStartWithDecoration(android.view.View);
+    method public abstract void offsetChild(android.view.View, int);
+    method public abstract void offsetChildren(int);
+    method public void onLayoutComplete();
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+    field protected final android.support.v7.widget.RecyclerView.LayoutManager mLayoutManager;
+  }
+
+  public class PagerSnapHelper extends android.support.v7.widget.SnapHelper {
+    ctor public PagerSnapHelper();
+    method public int[] calculateDistanceToFinalSnap(android.support.v7.widget.RecyclerView.LayoutManager, android.view.View);
+    method public android.view.View findSnapView(android.support.v7.widget.RecyclerView.LayoutManager);
+    method public int findTargetSnapPosition(android.support.v7.widget.RecyclerView.LayoutManager, int, int);
+  }
+
+  public class PopupMenu {
+    ctor public PopupMenu(android.content.Context, android.view.View);
+    ctor public PopupMenu(android.content.Context, android.view.View, int);
+    ctor public PopupMenu(android.content.Context, android.view.View, int, int, int);
+    method public void dismiss();
+    method public android.view.View.OnTouchListener getDragToOpenListener();
+    method public int getGravity();
+    method public android.view.Menu getMenu();
+    method public android.view.MenuInflater getMenuInflater();
+    method public void inflate(int);
+    method public void setGravity(int);
+    method public void setOnDismissListener(android.support.v7.widget.PopupMenu.OnDismissListener);
+    method public void setOnMenuItemClickListener(android.support.v7.widget.PopupMenu.OnMenuItemClickListener);
+    method public void show();
+  }
+
+  public static abstract interface PopupMenu.OnDismissListener {
+    method public abstract void onDismiss(android.support.v7.widget.PopupMenu);
+  }
+
+  public static abstract interface PopupMenu.OnMenuItemClickListener {
+    method public abstract boolean onMenuItemClick(android.view.MenuItem);
+  }
+
+  public class RecyclerView extends android.view.ViewGroup implements android.support.v4.view.NestedScrollingChild android.support.v4.view.ScrollingView {
+    ctor public RecyclerView(android.content.Context);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet);
+    ctor public RecyclerView(android.content.Context, android.util.AttributeSet, int);
+    method public void addItemDecoration(android.support.v7.widget.RecyclerView.ItemDecoration, int);
+    method public void addItemDecoration(android.support.v7.widget.RecyclerView.ItemDecoration);
+    method public void addOnChildAttachStateChangeListener(android.support.v7.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void addOnItemTouchListener(android.support.v7.widget.RecyclerView.OnItemTouchListener);
+    method public void addOnScrollListener(android.support.v7.widget.RecyclerView.OnScrollListener);
+    method public void clearOnChildAttachStateChangeListeners();
+    method public void clearOnScrollListeners();
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+    method public boolean drawChild(android.graphics.Canvas, android.view.View, long);
+    method public android.view.View findChildViewUnder(float, float);
+    method public android.view.View findContainingItemView(android.view.View);
+    method public android.support.v7.widget.RecyclerView.ViewHolder findContainingViewHolder(android.view.View);
+    method public android.support.v7.widget.RecyclerView.ViewHolder findViewHolderForAdapterPosition(int);
+    method public android.support.v7.widget.RecyclerView.ViewHolder findViewHolderForItemId(long);
+    method public android.support.v7.widget.RecyclerView.ViewHolder findViewHolderForLayoutPosition(int);
+    method public deprecated android.support.v7.widget.RecyclerView.ViewHolder findViewHolderForPosition(int);
+    method public boolean fling(int, int);
+    method public android.support.v7.widget.RecyclerView.Adapter getAdapter();
+    method public int getChildAdapterPosition(android.view.View);
+    method public long getChildItemId(android.view.View);
+    method public int getChildLayoutPosition(android.view.View);
+    method public deprecated int getChildPosition(android.view.View);
+    method public android.support.v7.widget.RecyclerView.ViewHolder getChildViewHolder(android.view.View);
+    method public android.support.v7.widget.RecyclerViewAccessibilityDelegate getCompatAccessibilityDelegate();
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public android.support.v7.widget.RecyclerView.ItemAnimator getItemAnimator();
+    method public android.support.v7.widget.RecyclerView.LayoutManager getLayoutManager();
+    method public int getMaxFlingVelocity();
+    method public int getMinFlingVelocity();
+    method public android.support.v7.widget.RecyclerView.OnFlingListener getOnFlingListener();
+    method public boolean getPreserveFocusAfterLayout();
+    method public android.support.v7.widget.RecyclerView.RecycledViewPool getRecycledViewPool();
+    method public int getScrollState();
+    method public boolean hasFixedSize();
+    method public boolean hasPendingAdapterUpdates();
+    method public void invalidateItemDecorations();
+    method public boolean isAnimating();
+    method public boolean isComputingLayout();
+    method public boolean isLayoutFrozen();
+    method public void offsetChildrenHorizontal(int);
+    method public void offsetChildrenVertical(int);
+    method public void onChildAttachedToWindow(android.view.View);
+    method public void onChildDetachedFromWindow(android.view.View);
+    method public void onDraw(android.graphics.Canvas);
+    method protected void onLayout(boolean, int, int, int, int);
+    method public void onScrollStateChanged(int);
+    method public void onScrolled(int, int);
+    method public void removeItemDecoration(android.support.v7.widget.RecyclerView.ItemDecoration);
+    method public void removeOnChildAttachStateChangeListener(android.support.v7.widget.RecyclerView.OnChildAttachStateChangeListener);
+    method public void removeOnItemTouchListener(android.support.v7.widget.RecyclerView.OnItemTouchListener);
+    method public void removeOnScrollListener(android.support.v7.widget.RecyclerView.OnScrollListener);
+    method public void scrollToPosition(int);
+    method public void setAccessibilityDelegateCompat(android.support.v7.widget.RecyclerViewAccessibilityDelegate);
+    method public void setAdapter(android.support.v7.widget.RecyclerView.Adapter);
+    method public void setChildDrawingOrderCallback(android.support.v7.widget.RecyclerView.ChildDrawingOrderCallback);
+    method public void setHasFixedSize(boolean);
+    method public void setItemAnimator(android.support.v7.widget.RecyclerView.ItemAnimator);
+    method public void setItemViewCacheSize(int);
+    method public void setLayoutFrozen(boolean);
+    method public void setLayoutManager(android.support.v7.widget.RecyclerView.LayoutManager);
+    method public void setOnFlingListener(android.support.v7.widget.RecyclerView.OnFlingListener);
+    method public deprecated void setOnScrollListener(android.support.v7.widget.RecyclerView.OnScrollListener);
+    method public void setPreserveFocusAfterLayout(boolean);
+    method public void setRecycledViewPool(android.support.v7.widget.RecyclerView.RecycledViewPool);
+    method public void setRecyclerListener(android.support.v7.widget.RecyclerView.RecyclerListener);
+    method public void setScrollingTouchSlop(int);
+    method public void setViewCacheExtension(android.support.v7.widget.RecyclerView.ViewCacheExtension);
+    method public void smoothScrollBy(int, int);
+    method public void smoothScrollBy(int, int, android.view.animation.Interpolator);
+    method public void smoothScrollToPosition(int);
+    method public void stopScroll();
+    method public void swapAdapter(android.support.v7.widget.RecyclerView.Adapter, boolean);
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int INVALID_TYPE = -1; // 0xffffffff
+    field public static final long NO_ID = -1L; // 0xffffffffffffffffL
+    field public static final int NO_POSITION = -1; // 0xffffffff
+    field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+    field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+    field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+    field public static final int TOUCH_SLOP_DEFAULT = 0; // 0x0
+    field public static final int TOUCH_SLOP_PAGING = 1; // 0x1
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static abstract class RecyclerView.Adapter<VH extends android.support.v7.widget.RecyclerView.ViewHolder> {
+    ctor public RecyclerView.Adapter();
+    method public final void bindViewHolder(VH, int);
+    method public final VH createViewHolder(android.view.ViewGroup, int);
+    method public abstract int getItemCount();
+    method public long getItemId(int);
+    method public int getItemViewType(int);
+    method public final boolean hasObservers();
+    method public final boolean hasStableIds();
+    method public final void notifyDataSetChanged();
+    method public final void notifyItemChanged(int);
+    method public final void notifyItemChanged(int, java.lang.Object);
+    method public final void notifyItemInserted(int);
+    method public final void notifyItemMoved(int, int);
+    method public final void notifyItemRangeChanged(int, int);
+    method public final void notifyItemRangeChanged(int, int, java.lang.Object);
+    method public final void notifyItemRangeInserted(int, int);
+    method public final void notifyItemRangeRemoved(int, int);
+    method public final void notifyItemRemoved(int);
+    method public void onAttachedToRecyclerView(android.support.v7.widget.RecyclerView);
+    method public abstract void onBindViewHolder(VH, int);
+    method public void onBindViewHolder(VH, int, java.util.List<java.lang.Object>);
+    method public abstract VH onCreateViewHolder(android.view.ViewGroup, int);
+    method public void onDetachedFromRecyclerView(android.support.v7.widget.RecyclerView);
+    method public boolean onFailedToRecycleView(VH);
+    method public void onViewAttachedToWindow(VH);
+    method public void onViewDetachedFromWindow(VH);
+    method public void onViewRecycled(VH);
+    method public void registerAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver);
+    method public void setHasStableIds(boolean);
+    method public void unregisterAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver);
+  }
+
+  public static abstract class RecyclerView.AdapterDataObserver {
+    ctor public RecyclerView.AdapterDataObserver();
+    method public void onChanged();
+    method public void onItemRangeChanged(int, int);
+    method public void onItemRangeChanged(int, int, java.lang.Object);
+    method public void onItemRangeInserted(int, int);
+    method public void onItemRangeMoved(int, int, int);
+    method public void onItemRangeRemoved(int, int);
+  }
+
+  public static abstract interface RecyclerView.ChildDrawingOrderCallback {
+    method public abstract int onGetChildDrawingOrder(int, int);
+  }
+
+  public static abstract class RecyclerView.ItemAnimator {
+    ctor public RecyclerView.ItemAnimator();
+    method public abstract boolean animateAppearance(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateDisappearance(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animatePersistence(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean canReuseUpdatedViewHolder(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public boolean canReuseUpdatedViewHolder(android.support.v7.widget.RecyclerView.ViewHolder, java.util.List<java.lang.Object>);
+    method public final void dispatchAnimationFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationStarted(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAnimationsFinished();
+    method public abstract void endAnimation(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public abstract void endAnimations();
+    method public long getAddDuration();
+    method public long getChangeDuration();
+    method public long getMoveDuration();
+    method public long getRemoveDuration();
+    method public abstract boolean isRunning();
+    method public final boolean isRunning(android.support.v7.widget.RecyclerView.ItemAnimator.ItemAnimatorFinishedListener);
+    method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo obtainHolderInfo();
+    method public void onAnimationFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void onAnimationStarted(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPostLayoutInformation(android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.ViewHolder);
+    method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPreLayoutInformation(android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.ViewHolder, int, java.util.List<java.lang.Object>);
+    method public abstract void runPendingAnimations();
+    method public void setAddDuration(long);
+    method public void setChangeDuration(long);
+    method public void setMoveDuration(long);
+    method public void setRemoveDuration(long);
+    field public static final int FLAG_APPEARED_IN_PRE_LAYOUT = 4096; // 0x1000
+    field public static final int FLAG_CHANGED = 2; // 0x2
+    field public static final int FLAG_INVALIDATED = 4; // 0x4
+    field public static final int FLAG_MOVED = 2048; // 0x800
+    field public static final int FLAG_REMOVED = 8; // 0x8
+  }
+
+  public static abstract class RecyclerView.ItemAnimator.AdapterChanges implements java.lang.annotation.Annotation {
+  }
+
+  public static abstract interface RecyclerView.ItemAnimator.ItemAnimatorFinishedListener {
+    method public abstract void onAnimationsFinished();
+  }
+
+  public static class RecyclerView.ItemAnimator.ItemHolderInfo {
+    ctor public RecyclerView.ItemAnimator.ItemHolderInfo();
+    method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(android.support.v7.widget.RecyclerView.ViewHolder, int);
+    field public int bottom;
+    field public int changeFlags;
+    field public int left;
+    field public int right;
+    field public int top;
+  }
+
+  public static abstract class RecyclerView.ItemDecoration {
+    ctor public RecyclerView.ItemDecoration();
+    method public deprecated void getItemOffsets(android.graphics.Rect, int, android.support.v7.widget.RecyclerView);
+    method public void getItemOffsets(android.graphics.Rect, android.view.View, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State);
+    method public void onDraw(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State);
+    method public deprecated void onDraw(android.graphics.Canvas, android.support.v7.widget.RecyclerView);
+    method public void onDrawOver(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State);
+    method public deprecated void onDrawOver(android.graphics.Canvas, android.support.v7.widget.RecyclerView);
+  }
+
+  public static abstract class RecyclerView.LayoutManager {
+    ctor public RecyclerView.LayoutManager();
+    method public void addDisappearingView(android.view.View);
+    method public void addDisappearingView(android.view.View, int);
+    method public void addView(android.view.View);
+    method public void addView(android.view.View, int);
+    method public void assertInLayoutOrScroll(java.lang.String);
+    method public void assertNotInLayoutOrScroll(java.lang.String);
+    method public void attachView(android.view.View, int, android.support.v7.widget.RecyclerView.LayoutParams);
+    method public void attachView(android.view.View, int);
+    method public void attachView(android.view.View);
+    method public void calculateItemDecorationsForChild(android.view.View, android.graphics.Rect);
+    method public boolean canScrollHorizontally();
+    method public boolean canScrollVertically();
+    method public boolean checkLayoutParams(android.support.v7.widget.RecyclerView.LayoutParams);
+    method public static int chooseSize(int, int, int);
+    method public void collectAdjacentPrefetchPositions(int, int, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry);
+    method public void collectInitialPrefetchPositions(int, android.support.v7.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry);
+    method public int computeHorizontalScrollExtent(android.support.v7.widget.RecyclerView.State);
+    method public int computeHorizontalScrollOffset(android.support.v7.widget.RecyclerView.State);
+    method public int computeHorizontalScrollRange(android.support.v7.widget.RecyclerView.State);
+    method public int computeVerticalScrollExtent(android.support.v7.widget.RecyclerView.State);
+    method public int computeVerticalScrollOffset(android.support.v7.widget.RecyclerView.State);
+    method public int computeVerticalScrollRange(android.support.v7.widget.RecyclerView.State);
+    method public void detachAndScrapAttachedViews(android.support.v7.widget.RecyclerView.Recycler);
+    method public void detachAndScrapView(android.view.View, android.support.v7.widget.RecyclerView.Recycler);
+    method public void detachAndScrapViewAt(int, android.support.v7.widget.RecyclerView.Recycler);
+    method public void detachView(android.view.View);
+    method public void detachViewAt(int);
+    method public void endAnimation(android.view.View);
+    method public android.view.View findContainingItemView(android.view.View);
+    method public android.view.View findViewByPosition(int);
+    method public abstract android.support.v7.widget.RecyclerView.LayoutParams generateDefaultLayoutParams();
+    method public android.support.v7.widget.RecyclerView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
+    method public android.support.v7.widget.RecyclerView.LayoutParams generateLayoutParams(android.content.Context, android.util.AttributeSet);
+    method public int getBaseline();
+    method public int getBottomDecorationHeight(android.view.View);
+    method public android.view.View getChildAt(int);
+    method public int getChildCount();
+    method public static deprecated int getChildMeasureSpec(int, int, int, boolean);
+    method public static int getChildMeasureSpec(int, int, int, int, boolean);
+    method public boolean getClipToPadding();
+    method public int getColumnCountForAccessibility(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+    method public int getDecoratedBottom(android.view.View);
+    method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+    method public int getDecoratedLeft(android.view.View);
+    method public int getDecoratedMeasuredHeight(android.view.View);
+    method public int getDecoratedMeasuredWidth(android.view.View);
+    method public int getDecoratedRight(android.view.View);
+    method public int getDecoratedTop(android.view.View);
+    method public android.view.View getFocusedChild();
+    method public int getHeight();
+    method public int getHeightMode();
+    method public int getItemCount();
+    method public int getItemViewType(android.view.View);
+    method public int getLayoutDirection();
+    method public int getLeftDecorationWidth(android.view.View);
+    method public int getMinimumHeight();
+    method public int getMinimumWidth();
+    method public int getPaddingBottom();
+    method public int getPaddingEnd();
+    method public int getPaddingLeft();
+    method public int getPaddingRight();
+    method public int getPaddingStart();
+    method public int getPaddingTop();
+    method public int getPosition(android.view.View);
+    method public static android.support.v7.widget.RecyclerView.LayoutManager.Properties getProperties(android.content.Context, android.util.AttributeSet, int, int);
+    method public int getRightDecorationWidth(android.view.View);
+    method public int getRowCountForAccessibility(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+    method public int getSelectionModeForAccessibility(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+    method public int getTopDecorationHeight(android.view.View);
+    method public void getTransformedBoundingBox(android.view.View, boolean, android.graphics.Rect);
+    method public int getWidth();
+    method public int getWidthMode();
+    method public boolean hasFocus();
+    method public void ignoreView(android.view.View);
+    method public boolean isAttachedToWindow();
+    method public boolean isAutoMeasureEnabled();
+    method public boolean isFocused();
+    method public final boolean isItemPrefetchEnabled();
+    method public boolean isLayoutHierarchical(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+    method public boolean isMeasurementCacheEnabled();
+    method public boolean isSmoothScrolling();
+    method public void layoutDecorated(android.view.View, int, int, int, int);
+    method public void layoutDecoratedWithMargins(android.view.View, int, int, int, int);
+    method public void measureChild(android.view.View, int, int);
+    method public void measureChildWithMargins(android.view.View, int, int);
+    method public void moveView(int, int);
+    method public void offsetChildrenHorizontal(int);
+    method public void offsetChildrenVertical(int);
+    method public void onAdapterChanged(android.support.v7.widget.RecyclerView.Adapter, android.support.v7.widget.RecyclerView.Adapter);
+    method public boolean onAddFocusables(android.support.v7.widget.RecyclerView, java.util.ArrayList<android.view.View>, int, int);
+    method public void onAttachedToWindow(android.support.v7.widget.RecyclerView);
+    method public deprecated void onDetachedFromWindow(android.support.v7.widget.RecyclerView);
+    method public void onDetachedFromWindow(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.Recycler);
+    method public android.view.View onFocusSearchFailed(android.view.View, int, android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+    method public void onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityEvent(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onInitializeAccessibilityNodeInfoForItem(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, android.view.View, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+    method public android.view.View onInterceptFocusSearch(android.view.View, int);
+    method public void onItemsAdded(android.support.v7.widget.RecyclerView, int, int);
+    method public void onItemsChanged(android.support.v7.widget.RecyclerView);
+    method public void onItemsMoved(android.support.v7.widget.RecyclerView, int, int, int);
+    method public void onItemsRemoved(android.support.v7.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(android.support.v7.widget.RecyclerView, int, int);
+    method public void onItemsUpdated(android.support.v7.widget.RecyclerView, int, int, java.lang.Object);
+    method public void onLayoutChildren(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+    method public void onLayoutCompleted(android.support.v7.widget.RecyclerView.State);
+    method public void onMeasure(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, int, int);
+    method public deprecated boolean onRequestChildFocus(android.support.v7.widget.RecyclerView, android.view.View, android.view.View);
+    method public boolean onRequestChildFocus(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State, android.view.View, android.view.View);
+    method public void onRestoreInstanceState(android.os.Parcelable);
+    method public android.os.Parcelable onSaveInstanceState();
+    method public void onScrollStateChanged(int);
+    method public boolean performAccessibilityAction(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, int, android.os.Bundle);
+    method public boolean performAccessibilityActionForItem(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, android.view.View, int, android.os.Bundle);
+    method public void postOnAnimation(java.lang.Runnable);
+    method public void removeAllViews();
+    method public void removeAndRecycleAllViews(android.support.v7.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleView(android.view.View, android.support.v7.widget.RecyclerView.Recycler);
+    method public void removeAndRecycleViewAt(int, android.support.v7.widget.RecyclerView.Recycler);
+    method public boolean removeCallbacks(java.lang.Runnable);
+    method public void removeDetachedView(android.view.View);
+    method public void removeView(android.view.View);
+    method public void removeViewAt(int);
+    method public boolean requestChildRectangleOnScreen(android.support.v7.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean);
+    method public void requestLayout();
+    method public void requestSimpleAnimationsInNextLayout();
+    method public int scrollHorizontallyBy(int, android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+    method public void scrollToPosition(int);
+    method public int scrollVerticallyBy(int, android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+    method public void setAutoMeasureEnabled(boolean);
+    method public final void setItemPrefetchEnabled(boolean);
+    method public void setMeasuredDimension(android.graphics.Rect, int, int);
+    method public void setMeasuredDimension(int, int);
+    method public void setMeasurementCacheEnabled(boolean);
+    method public void smoothScrollToPosition(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State, int);
+    method public void startSmoothScroll(android.support.v7.widget.RecyclerView.SmoothScroller);
+    method public void stopIgnoringView(android.view.View);
+    method public boolean supportsPredictiveItemAnimations();
+  }
+
+  public static abstract interface RecyclerView.LayoutManager.LayoutPrefetchRegistry {
+    method public abstract void addPosition(int, int);
+  }
+
+  public static class RecyclerView.LayoutManager.Properties {
+    ctor public RecyclerView.LayoutManager.Properties();
+    field public int orientation;
+    field public boolean reverseLayout;
+    field public int spanCount;
+    field public boolean stackFromEnd;
+  }
+
+  public static class RecyclerView.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+    ctor public RecyclerView.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public RecyclerView.LayoutParams(int, int);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public RecyclerView.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public RecyclerView.LayoutParams(android.support.v7.widget.RecyclerView.LayoutParams);
+    method public int getViewAdapterPosition();
+    method public int getViewLayoutPosition();
+    method public deprecated int getViewPosition();
+    method public boolean isItemChanged();
+    method public boolean isItemRemoved();
+    method public boolean isViewInvalid();
+    method public boolean viewNeedsUpdate();
+  }
+
+  public static abstract interface RecyclerView.OnChildAttachStateChangeListener {
+    method public abstract void onChildViewAttachedToWindow(android.view.View);
+    method public abstract void onChildViewDetachedFromWindow(android.view.View);
+  }
+
+  public static abstract class RecyclerView.OnFlingListener {
+    ctor public RecyclerView.OnFlingListener();
+    method public abstract boolean onFling(int, int);
+  }
+
+  public static abstract interface RecyclerView.OnItemTouchListener {
+    method public abstract boolean onInterceptTouchEvent(android.support.v7.widget.RecyclerView, android.view.MotionEvent);
+    method public abstract void onRequestDisallowInterceptTouchEvent(boolean);
+    method public abstract void onTouchEvent(android.support.v7.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public static abstract class RecyclerView.OnScrollListener {
+    ctor public RecyclerView.OnScrollListener();
+    method public void onScrollStateChanged(android.support.v7.widget.RecyclerView, int);
+    method public void onScrolled(android.support.v7.widget.RecyclerView, int, int);
+  }
+
+  public static class RecyclerView.RecycledViewPool {
+    ctor public RecyclerView.RecycledViewPool();
+    method public void clear();
+    method public android.support.v7.widget.RecyclerView.ViewHolder getRecycledView(int);
+    method public int getRecycledViewCount(int);
+    method public void putRecycledView(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void setMaxRecycledViews(int, int);
+  }
+
+  public final class RecyclerView.Recycler {
+    ctor public RecyclerView.Recycler();
+    method public void bindViewToPosition(android.view.View, int);
+    method public void clear();
+    method public int convertPreLayoutPositionToPostLayout(int);
+    method public java.util.List<android.support.v7.widget.RecyclerView.ViewHolder> getScrapList();
+    method public android.view.View getViewForPosition(int);
+    method public void recycleView(android.view.View);
+    method public void setViewCacheSize(int);
+  }
+
+  public static abstract interface RecyclerView.RecyclerListener {
+    method public abstract void onViewRecycled(android.support.v7.widget.RecyclerView.ViewHolder);
+  }
+
+  public static class RecyclerView.SimpleOnItemTouchListener implements android.support.v7.widget.RecyclerView.OnItemTouchListener {
+    ctor public RecyclerView.SimpleOnItemTouchListener();
+    method public boolean onInterceptTouchEvent(android.support.v7.widget.RecyclerView, android.view.MotionEvent);
+    method public void onRequestDisallowInterceptTouchEvent(boolean);
+    method public void onTouchEvent(android.support.v7.widget.RecyclerView, android.view.MotionEvent);
+  }
+
+  public static abstract class RecyclerView.SmoothScroller {
+    ctor public RecyclerView.SmoothScroller();
+    method public android.view.View findViewByPosition(int);
+    method public int getChildCount();
+    method public int getChildPosition(android.view.View);
+    method public android.support.v7.widget.RecyclerView.LayoutManager getLayoutManager();
+    method public int getTargetPosition();
+    method public deprecated void instantScrollToPosition(int);
+    method public boolean isPendingInitialRun();
+    method public boolean isRunning();
+    method protected void normalize(android.graphics.PointF);
+    method protected void onChildAttachedToWindow(android.view.View);
+    method protected abstract void onSeekTargetStep(int, int, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+    method protected abstract void onStart();
+    method protected abstract void onStop();
+    method protected abstract void onTargetFound(android.view.View, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+    method public void setTargetPosition(int);
+    method protected final void stop();
+  }
+
+  public static class RecyclerView.SmoothScroller.Action {
+    ctor public RecyclerView.SmoothScroller.Action(int, int);
+    ctor public RecyclerView.SmoothScroller.Action(int, int, int);
+    ctor public RecyclerView.SmoothScroller.Action(int, int, int, android.view.animation.Interpolator);
+    method public int getDuration();
+    method public int getDx();
+    method public int getDy();
+    method public android.view.animation.Interpolator getInterpolator();
+    method public void jumpTo(int);
+    method public void setDuration(int);
+    method public void setDx(int);
+    method public void setDy(int);
+    method public void setInterpolator(android.view.animation.Interpolator);
+    method public void update(int, int, int, android.view.animation.Interpolator);
+    field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+  }
+
+  public static abstract interface RecyclerView.SmoothScroller.ScrollVectorProvider {
+    method public abstract android.graphics.PointF computeScrollVectorForPosition(int);
+  }
+
+  public static class RecyclerView.State {
+    ctor public RecyclerView.State();
+    method public boolean didStructureChange();
+    method public <T> T get(int);
+    method public int getItemCount();
+    method public int getTargetScrollPosition();
+    method public boolean hasTargetScrollPosition();
+    method public boolean isMeasuring();
+    method public boolean isPreLayout();
+    method public void put(int, java.lang.Object);
+    method public void remove(int);
+    method public boolean willRunPredictiveAnimations();
+    method public boolean willRunSimpleAnimations();
+  }
+
+  public static abstract class RecyclerView.ViewCacheExtension {
+    ctor public RecyclerView.ViewCacheExtension();
+    method public abstract android.view.View getViewForPositionAndType(android.support.v7.widget.RecyclerView.Recycler, int, int);
+  }
+
+  public static abstract class RecyclerView.ViewHolder {
+    ctor public RecyclerView.ViewHolder(android.view.View);
+    method public final int getAdapterPosition();
+    method public final long getItemId();
+    method public final int getItemViewType();
+    method public final int getLayoutPosition();
+    method public final int getOldPosition();
+    method public final deprecated int getPosition();
+    method public final boolean isRecyclable();
+    method public final void setIsRecyclable(boolean);
+    field public final android.view.View itemView;
+  }
+
+  public class RecyclerViewAccessibilityDelegate extends android.support.v4.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate(android.support.v7.widget.RecyclerView);
+    method public android.support.v4.view.AccessibilityDelegateCompat getItemDelegate();
+  }
+
+  public class SearchView extends android.support.v7.widget.LinearLayoutCompat implements android.support.v7.view.CollapsibleActionView {
+    ctor public SearchView(android.content.Context);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet, int);
+    method public int getImeOptions();
+    method public int getInputType();
+    method public int getMaxWidth();
+    method public java.lang.CharSequence getQuery();
+    method public java.lang.CharSequence getQueryHint();
+    method public android.support.v4.widget.CursorAdapter getSuggestionsAdapter();
+    method public boolean isIconfiedByDefault();
+    method public boolean isIconified();
+    method public boolean isQueryRefinementEnabled();
+    method public boolean isSubmitButtonEnabled();
+    method public void onActionViewCollapsed();
+    method public void onActionViewExpanded();
+    method public void setIconified(boolean);
+    method public void setIconifiedByDefault(boolean);
+    method public void setImeOptions(int);
+    method public void setInputType(int);
+    method public void setMaxWidth(int);
+    method public void setOnCloseListener(android.support.v7.widget.SearchView.OnCloseListener);
+    method public void setOnQueryTextFocusChangeListener(android.view.View.OnFocusChangeListener);
+    method public void setOnQueryTextListener(android.support.v7.widget.SearchView.OnQueryTextListener);
+    method public void setOnSearchClickListener(android.view.View.OnClickListener);
+    method public void setOnSuggestionListener(android.support.v7.widget.SearchView.OnSuggestionListener);
+    method public void setQuery(java.lang.CharSequence, boolean);
+    method public void setQueryHint(java.lang.CharSequence);
+    method public void setQueryRefinementEnabled(boolean);
+    method public void setSearchableInfo(android.app.SearchableInfo);
+    method public void setSubmitButtonEnabled(boolean);
+    method public void setSuggestionsAdapter(android.support.v4.widget.CursorAdapter);
+  }
+
+  public static abstract interface SearchView.OnCloseListener {
+    method public abstract boolean onClose();
+  }
+
+  public static abstract interface SearchView.OnQueryTextListener {
+    method public abstract boolean onQueryTextChange(java.lang.String);
+    method public abstract boolean onQueryTextSubmit(java.lang.String);
+  }
+
+  public static abstract interface SearchView.OnSuggestionListener {
+    method public abstract boolean onSuggestionClick(int);
+    method public abstract boolean onSuggestionSelect(int);
+  }
+
+  public class ShareActionProvider extends android.support.v4.view.ActionProvider {
+    ctor public ShareActionProvider(android.content.Context);
+    method public android.view.View onCreateActionView();
+    method public void setOnShareTargetSelectedListener(android.support.v7.widget.ShareActionProvider.OnShareTargetSelectedListener);
+    method public void setShareHistoryFileName(java.lang.String);
+    method public void setShareIntent(android.content.Intent);
+    field public static final java.lang.String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml";
+  }
+
+  public static abstract interface ShareActionProvider.OnShareTargetSelectedListener {
+    method public abstract boolean onShareTargetSelected(android.support.v7.widget.ShareActionProvider, android.content.Intent);
+  }
+
+  public abstract class SimpleItemAnimator extends android.support.v7.widget.RecyclerView.ItemAnimator {
+    ctor public SimpleItemAnimator();
+    method public abstract boolean animateAdd(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public boolean animateAppearance(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public boolean animateChange(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateChange(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder, int, int, int, int);
+    method public boolean animateDisappearance(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateMove(android.support.v7.widget.RecyclerView.ViewHolder, int, int, int, int);
+    method public boolean animatePersistence(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+    method public abstract boolean animateRemove(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAddFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void dispatchAddStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void dispatchChangeFinished(android.support.v7.widget.RecyclerView.ViewHolder, boolean);
+    method public final void dispatchChangeStarting(android.support.v7.widget.RecyclerView.ViewHolder, boolean);
+    method public final void dispatchMoveFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void dispatchMoveStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void dispatchRemoveFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public final void dispatchRemoveStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public boolean getSupportsChangeAnimations();
+    method public void onAddFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void onAddStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void onChangeFinished(android.support.v7.widget.RecyclerView.ViewHolder, boolean);
+    method public void onChangeStarting(android.support.v7.widget.RecyclerView.ViewHolder, boolean);
+    method public void onMoveFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void onMoveStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void onRemoveFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void onRemoveStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void setSupportsChangeAnimations(boolean);
+  }
+
+  public abstract class SnapHelper extends android.support.v7.widget.RecyclerView.OnFlingListener {
+    ctor public SnapHelper();
+    method public void attachToRecyclerView(android.support.v7.widget.RecyclerView) throws java.lang.IllegalStateException;
+    method public abstract int[] calculateDistanceToFinalSnap(android.support.v7.widget.RecyclerView.LayoutManager, android.view.View);
+    method public int[] calculateScrollDistance(int, int);
+    method protected android.support.v7.widget.LinearSmoothScroller createSnapScroller(android.support.v7.widget.RecyclerView.LayoutManager);
+    method public abstract android.view.View findSnapView(android.support.v7.widget.RecyclerView.LayoutManager);
+    method public abstract int findTargetSnapPosition(android.support.v7.widget.RecyclerView.LayoutManager, int, int);
+    method public boolean onFling(int, int);
+  }
+
+  public class StaggeredGridLayoutManager extends android.support.v7.widget.RecyclerView.LayoutManager implements android.support.v7.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+    ctor public StaggeredGridLayoutManager(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public StaggeredGridLayoutManager(int, int);
+    method public android.graphics.PointF computeScrollVectorForPosition(int);
+    method public int[] findFirstCompletelyVisibleItemPositions(int[]);
+    method public int[] findFirstVisibleItemPositions(int[]);
+    method public int[] findLastCompletelyVisibleItemPositions(int[]);
+    method public int[] findLastVisibleItemPositions(int[]);
+    method public android.support.v7.widget.RecyclerView.LayoutParams generateDefaultLayoutParams();
+    method public int getGapStrategy();
+    method public int getOrientation();
+    method public boolean getReverseLayout();
+    method public int getSpanCount();
+    method public void invalidateSpanAssignments();
+    method public void scrollToPositionWithOffset(int, int);
+    method public void setGapStrategy(int);
+    method public void setOrientation(int);
+    method public void setReverseLayout(boolean);
+    method public void setSpanCount(int);
+    field public static final deprecated int GAP_HANDLING_LAZY = 1; // 0x1
+    field public static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS = 2; // 0x2
+    field public static final int GAP_HANDLING_NONE = 0; // 0x0
+    field public static final int HORIZONTAL = 0; // 0x0
+    field public static final int VERTICAL = 1; // 0x1
+  }
+
+  public static class StaggeredGridLayoutManager.LayoutParams extends android.support.v7.widget.RecyclerView.LayoutParams {
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public StaggeredGridLayoutManager.LayoutParams(int, int);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public StaggeredGridLayoutManager.LayoutParams(android.support.v7.widget.RecyclerView.LayoutParams);
+    method public final int getSpanIndex();
+    method public boolean isFullSpan();
+    method public void setFullSpan(boolean);
+    field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+  }
+
+  public class SwitchCompat extends android.widget.CompoundButton {
+    ctor public SwitchCompat(android.content.Context);
+    ctor public SwitchCompat(android.content.Context, android.util.AttributeSet);
+    ctor public SwitchCompat(android.content.Context, android.util.AttributeSet, int);
+    method public boolean getShowText();
+    method public boolean getSplitTrack();
+    method public int getSwitchMinWidth();
+    method public int getSwitchPadding();
+    method public java.lang.CharSequence getTextOff();
+    method public java.lang.CharSequence getTextOn();
+    method public android.graphics.drawable.Drawable getThumbDrawable();
+    method public int getThumbTextPadding();
+    method public android.content.res.ColorStateList getThumbTintList();
+    method public android.graphics.PorterDuff.Mode getThumbTintMode();
+    method public android.graphics.drawable.Drawable getTrackDrawable();
+    method public android.content.res.ColorStateList getTrackTintList();
+    method public android.graphics.PorterDuff.Mode getTrackTintMode();
+    method public void onMeasure(int, int);
+    method public void setShowText(boolean);
+    method public void setSplitTrack(boolean);
+    method public void setSwitchMinWidth(int);
+    method public void setSwitchPadding(int);
+    method public void setSwitchTextAppearance(android.content.Context, int);
+    method public void setSwitchTypeface(android.graphics.Typeface, int);
+    method public void setSwitchTypeface(android.graphics.Typeface);
+    method public void setTextOff(java.lang.CharSequence);
+    method public void setTextOn(java.lang.CharSequence);
+    method public void setThumbDrawable(android.graphics.drawable.Drawable);
+    method public void setThumbResource(int);
+    method public void setThumbTextPadding(int);
+    method public void setThumbTintList(android.content.res.ColorStateList);
+    method public void setThumbTintMode(android.graphics.PorterDuff.Mode);
+    method public void setTrackDrawable(android.graphics.drawable.Drawable);
+    method public void setTrackResource(int);
+    method public void setTrackTintList(android.content.res.ColorStateList);
+    method public void setTrackTintMode(android.graphics.PorterDuff.Mode);
+  }
+
+  public abstract interface ThemedSpinnerAdapter implements android.widget.SpinnerAdapter {
+    method public abstract android.content.res.Resources.Theme getDropDownViewTheme();
+    method public abstract void setDropDownViewTheme(android.content.res.Resources.Theme);
+  }
+
+  public static final class ThemedSpinnerAdapter.Helper {
+    ctor public ThemedSpinnerAdapter.Helper(android.content.Context);
+    method public android.view.LayoutInflater getDropDownViewInflater();
+    method public android.content.res.Resources.Theme getDropDownViewTheme();
+    method public void setDropDownViewTheme(android.content.res.Resources.Theme);
+  }
+
+  public class Toolbar extends android.view.ViewGroup {
+    ctor public Toolbar(android.content.Context);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet, int);
+    method public void collapseActionView();
+    method public void dismissPopupMenus();
+    method public int getContentInsetEnd();
+    method public int getContentInsetEndWithActions();
+    method public int getContentInsetLeft();
+    method public int getContentInsetRight();
+    method public int getContentInsetStart();
+    method public int getContentInsetStartWithNavigation();
+    method public int getCurrentContentInsetEnd();
+    method public int getCurrentContentInsetLeft();
+    method public int getCurrentContentInsetRight();
+    method public int getCurrentContentInsetStart();
+    method public android.graphics.drawable.Drawable getLogo();
+    method public java.lang.CharSequence getLogoDescription();
+    method public android.view.Menu getMenu();
+    method public java.lang.CharSequence getNavigationContentDescription();
+    method public android.graphics.drawable.Drawable getNavigationIcon();
+    method public android.graphics.drawable.Drawable getOverflowIcon();
+    method public int getPopupTheme();
+    method public java.lang.CharSequence getSubtitle();
+    method public java.lang.CharSequence getTitle();
+    method public int getTitleMarginBottom();
+    method public int getTitleMarginEnd();
+    method public int getTitleMarginStart();
+    method public int getTitleMarginTop();
+    method public boolean hasExpandedActionView();
+    method public boolean hideOverflowMenu();
+    method public void inflateMenu(int);
+    method public boolean isOverflowMenuShowing();
+    method protected void onLayout(boolean, int, int, int, int);
+    method public void setContentInsetEndWithActions(int);
+    method public void setContentInsetStartWithNavigation(int);
+    method public void setContentInsetsAbsolute(int, int);
+    method public void setContentInsetsRelative(int, int);
+    method public void setLogo(int);
+    method public void setLogo(android.graphics.drawable.Drawable);
+    method public void setLogoDescription(int);
+    method public void setLogoDescription(java.lang.CharSequence);
+    method public void setNavigationContentDescription(int);
+    method public void setNavigationContentDescription(java.lang.CharSequence);
+    method public void setNavigationIcon(int);
+    method public void setNavigationIcon(android.graphics.drawable.Drawable);
+    method public void setNavigationOnClickListener(android.view.View.OnClickListener);
+    method public void setOnMenuItemClickListener(android.support.v7.widget.Toolbar.OnMenuItemClickListener);
+    method public void setOverflowIcon(android.graphics.drawable.Drawable);
+    method public void setPopupTheme(int);
+    method public void setSubtitle(int);
+    method public void setSubtitle(java.lang.CharSequence);
+    method public void setSubtitleTextAppearance(android.content.Context, int);
+    method public void setSubtitleTextColor(int);
+    method public void setTitle(int);
+    method public void setTitle(java.lang.CharSequence);
+    method public void setTitleMargin(int, int, int, int);
+    method public void setTitleMarginBottom(int);
+    method public void setTitleMarginEnd(int);
+    method public void setTitleMarginStart(int);
+    method public void setTitleMarginTop(int);
+    method public void setTitleTextAppearance(android.content.Context, int);
+    method public void setTitleTextColor(int);
+    method public boolean showOverflowMenu();
+  }
+
+  public static class Toolbar.LayoutParams extends android.support.v7.app.ActionBar.LayoutParams {
+    ctor public Toolbar.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public Toolbar.LayoutParams(int, int);
+    ctor public Toolbar.LayoutParams(int, int, int);
+    ctor public Toolbar.LayoutParams(int);
+    ctor public Toolbar.LayoutParams(android.support.v7.widget.Toolbar.LayoutParams);
+    ctor public Toolbar.LayoutParams(android.support.v7.app.ActionBar.LayoutParams);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.LayoutParams);
+  }
+
+  public static abstract interface Toolbar.OnMenuItemClickListener {
+    method public abstract boolean onMenuItemClick(android.view.MenuItem);
+  }
+
+  public static class Toolbar.SavedState extends android.support.v4.view.AbsSavedState {
+    ctor public Toolbar.SavedState(android.os.Parcel);
+    ctor public Toolbar.SavedState(android.os.Parcel, java.lang.ClassLoader);
+    ctor public Toolbar.SavedState(android.os.Parcelable);
+    field public static final android.os.Parcelable.Creator<android.support.v7.widget.Toolbar.SavedState> CREATOR;
+  }
+
+}
+
+package android.support.v7.widget.helper {
+
+  public class ItemTouchHelper extends android.support.v7.widget.RecyclerView.ItemDecoration implements android.support.v7.widget.RecyclerView.OnChildAttachStateChangeListener {
+    ctor public ItemTouchHelper(android.support.v7.widget.helper.ItemTouchHelper.Callback);
+    method public void attachToRecyclerView(android.support.v7.widget.RecyclerView);
+    method public void onChildViewAttachedToWindow(android.view.View);
+    method public void onChildViewDetachedFromWindow(android.view.View);
+    method public void startDrag(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void startSwipe(android.support.v7.widget.RecyclerView.ViewHolder);
+    field public static final int ACTION_STATE_DRAG = 2; // 0x2
+    field public static final int ACTION_STATE_IDLE = 0; // 0x0
+    field public static final int ACTION_STATE_SWIPE = 1; // 0x1
+    field public static final int ANIMATION_TYPE_DRAG = 8; // 0x8
+    field public static final int ANIMATION_TYPE_SWIPE_CANCEL = 4; // 0x4
+    field public static final int ANIMATION_TYPE_SWIPE_SUCCESS = 2; // 0x2
+    field public static final int DOWN = 2; // 0x2
+    field public static final int END = 32; // 0x20
+    field public static final int LEFT = 4; // 0x4
+    field public static final int RIGHT = 8; // 0x8
+    field public static final int START = 16; // 0x10
+    field public static final int UP = 1; // 0x1
+  }
+
+  public static abstract class ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.Callback();
+    method public boolean canDropOver(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder);
+    method public android.support.v7.widget.RecyclerView.ViewHolder chooseDropTarget(android.support.v7.widget.RecyclerView.ViewHolder, java.util.List<android.support.v7.widget.RecyclerView.ViewHolder>, int, int);
+    method public void clearView(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+    method public int convertToAbsoluteDirection(int, int);
+    method public static int convertToRelativeDirection(int, int);
+    method public long getAnimationDuration(android.support.v7.widget.RecyclerView, int, float, float);
+    method public int getBoundingBoxMargin();
+    method public static android.support.v7.widget.helper.ItemTouchUIUtil getDefaultUIUtil();
+    method public float getMoveThreshold(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public abstract int getMovementFlags(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+    method public float getSwipeEscapeVelocity(float);
+    method public float getSwipeThreshold(android.support.v7.widget.RecyclerView.ViewHolder);
+    method public float getSwipeVelocityThreshold(float);
+    method public int interpolateOutOfBoundsScroll(android.support.v7.widget.RecyclerView, int, int, int, long);
+    method public boolean isItemViewSwipeEnabled();
+    method public boolean isLongPressDragEnabled();
+    method public static int makeFlag(int, int);
+    method public static int makeMovementFlags(int, int);
+    method public void onChildDraw(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, float, float, int, boolean);
+    method public void onChildDrawOver(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, float, float, int, boolean);
+    method public abstract boolean onMove(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void onMoved(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, int, android.support.v7.widget.RecyclerView.ViewHolder, int, int, int);
+    method public void onSelectedChanged(android.support.v7.widget.RecyclerView.ViewHolder, int);
+    method public abstract void onSwiped(android.support.v7.widget.RecyclerView.ViewHolder, int);
+    field public static final int DEFAULT_DRAG_ANIMATION_DURATION = 200; // 0xc8
+    field public static final int DEFAULT_SWIPE_ANIMATION_DURATION = 250; // 0xfa
+  }
+
+  public static abstract class ItemTouchHelper.SimpleCallback extends android.support.v7.widget.helper.ItemTouchHelper.Callback {
+    ctor public ItemTouchHelper.SimpleCallback(int, int);
+    method public int getDragDirs(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+    method public int getMovementFlags(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+    method public int getSwipeDirs(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+    method public void setDefaultDragDirs(int);
+    method public void setDefaultSwipeDirs(int);
+  }
+
+  public static abstract interface ItemTouchHelper.ViewDropHandler {
+    method public abstract void prepareForDrop(android.view.View, android.view.View, int, int);
+  }
+
+  public abstract interface ItemTouchUIUtil {
+    method public abstract void clearView(android.view.View);
+    method public abstract void onDraw(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.view.View, float, float, int, boolean);
+    method public abstract void onDrawOver(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.view.View, float, float, int, boolean);
+    method public abstract void onSelected(android.view.View);
+  }
+
+}
+
+package android.support.v7.widget.util {
+
+  public abstract class SortedListAdapterCallback<T2> extends android.support.v7.util.SortedList.Callback {
+    ctor public SortedListAdapterCallback(android.support.v7.widget.RecyclerView.Adapter);
+    method public void onChanged(int, int);
+    method public void onInserted(int, int);
+    method public void onMoved(int, int);
+    method public void onRemoved(int, int);
+  }
+
+}
+
diff --git a/api/current.txt b/api/current.txt
index 24fb7c4..28d5677 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -508,7 +508,6 @@
     method public int getScrimColor(android.support.design.widget.CoordinatorLayout, V);
     method public float getScrimOpacity(android.support.design.widget.CoordinatorLayout, V);
     method public static java.lang.Object getTag(android.view.View);
-    method public deprecated boolean isDirty(android.support.design.widget.CoordinatorLayout, V);
     method public boolean layoutDependsOn(android.support.design.widget.CoordinatorLayout, V, android.view.View);
     method public android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.support.design.widget.CoordinatorLayout, V, android.support.v4.view.WindowInsetsCompat);
     method public void onAttachedToLayoutParams(android.support.design.widget.CoordinatorLayout.LayoutParams);
@@ -1032,6 +1031,463 @@
 
 }
 
+package android.support.media.instantvideo.preload {
+
+  public class InstantVideoPreloadManager {
+    method public void clearCache();
+    method public static synchronized android.support.media.instantvideo.preload.InstantVideoPreloadManager getInstance(android.content.Context);
+    method public void preload(android.net.Uri);
+    method public void setMaxCacheSize(int);
+    method public void setMaxPreloadVideoCount(int);
+  }
+
+}
+
+package android.support.media.instantvideo.widget {
+
+  public class InstantVideoView extends android.widget.FrameLayout {
+    ctor public InstantVideoView(android.content.Context);
+    ctor public InstantVideoView(android.content.Context, android.util.AttributeSet);
+    ctor public InstantVideoView(android.content.Context, android.util.AttributeSet, int);
+    method public int getCurrentPosition();
+    method public void seekTo(int);
+    method public void setImageDrawable(android.graphics.drawable.Drawable);
+    method public void setVideoUri(android.net.Uri);
+    method public void start();
+    method public void stop();
+  }
+
+}
+
+package android.support.media.tv {
+
+  public final class Channel {
+    method public static android.support.media.tv.Channel fromCursor(android.database.Cursor);
+    method public int getAppLinkColor();
+    method public android.net.Uri getAppLinkIconUri();
+    method public android.content.Intent getAppLinkIntent() throws java.net.URISyntaxException;
+    method public android.net.Uri getAppLinkIntentUri();
+    method public android.net.Uri getAppLinkPosterArtUri();
+    method public java.lang.String getAppLinkText();
+    method public java.lang.String getChannelLogo();
+    method public java.lang.String getDescription();
+    method public java.lang.String getDisplayName();
+    method public java.lang.String getDisplayNumber();
+    method public long getId();
+    method public java.lang.String getInputId();
+    method public byte[] getInternalProviderDataByteArray();
+    method public java.lang.Long getInternalProviderFlag1();
+    method public java.lang.Long getInternalProviderFlag2();
+    method public java.lang.Long getInternalProviderFlag3();
+    method public java.lang.Long getInternalProviderFlag4();
+    method public java.lang.String getNetworkAffiliation();
+    method public int getOriginalNetworkId();
+    method public java.lang.String getPackageName();
+    method public int getServiceId();
+    method public java.lang.String getServiceType();
+    method public int getTransportStreamId();
+    method public java.lang.String getType();
+    method public java.lang.String getVideoFormat();
+    method public boolean isSearchable();
+    method public android.content.ContentValues toContentValues();
+  }
+
+  public static final class Channel.Builder {
+    ctor public Channel.Builder();
+    ctor public Channel.Builder(android.support.media.tv.Channel);
+    method public android.support.media.tv.Channel build();
+    method public android.support.media.tv.Channel.Builder setAppLinkColor(int);
+    method public android.support.media.tv.Channel.Builder setAppLinkIconUri(android.net.Uri);
+    method public android.support.media.tv.Channel.Builder setAppLinkIntent(android.content.Intent);
+    method public android.support.media.tv.Channel.Builder setAppLinkIntentUri(android.net.Uri);
+    method public android.support.media.tv.Channel.Builder setAppLinkPosterArtUri(android.net.Uri);
+    method public android.support.media.tv.Channel.Builder setAppLinkText(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setChannelLogo(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setDescription(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setDisplayName(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setDisplayNumber(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setInputId(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setInternalProviderData(byte[]);
+    method public android.support.media.tv.Channel.Builder setInternalProviderData(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setInternalProviderFlag1(long);
+    method public android.support.media.tv.Channel.Builder setInternalProviderFlag2(long);
+    method public android.support.media.tv.Channel.Builder setInternalProviderFlag3(long);
+    method public android.support.media.tv.Channel.Builder setInternalProviderFlag4(long);
+    method public android.support.media.tv.Channel.Builder setNetworkAffiliation(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setOriginalNetworkId(int);
+    method public android.support.media.tv.Channel.Builder setPackageName(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setSearchable(boolean);
+    method public android.support.media.tv.Channel.Builder setServiceId(int);
+    method public android.support.media.tv.Channel.Builder setServiceType(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setTransportStreamId(int);
+    method public android.support.media.tv.Channel.Builder setType(java.lang.String);
+    method public android.support.media.tv.Channel.Builder setVideoFormat(java.lang.String);
+  }
+
+  public final class Program implements java.lang.Comparable {
+    method public int compareTo(android.support.media.tv.Program);
+    method public static android.support.media.tv.Program fromCursor(android.database.Cursor);
+    method public android.content.Intent getAppLinkIntent() throws java.net.URISyntaxException;
+    method public android.net.Uri getAppLinkIntentUri();
+    method public java.lang.String[] getAudioLanguages();
+    method public java.lang.String getAuthor();
+    method public java.lang.String getAvailability();
+    method public java.lang.String[] getBroadcastGenres();
+    method public java.lang.String[] getCanonicalGenres();
+    method public long getChannelId();
+    method public android.media.tv.TvContentRating[] getContentRatings();
+    method public java.lang.String getDescription();
+    method public int getDurationMillis();
+    method public long getEndTimeUtcMillis();
+    method public java.lang.String getEpisodeNumber();
+    method public java.lang.String getEpisodeTitle();
+    method public long getId();
+    method public int getInteractionCount();
+    method public java.lang.String getInteractionType();
+    method public byte[] getInternalProviderDataByteArray();
+    method public java.lang.Long getInternalProviderFlag1();
+    method public java.lang.Long getInternalProviderFlag2();
+    method public java.lang.Long getInternalProviderFlag3();
+    method public java.lang.Long getInternalProviderFlag4();
+    method public java.lang.String getInternalProviderId();
+    method public int getItemCount();
+    method public int getLastPlaybackPositionMillis();
+    method public android.net.Uri getLogoUri();
+    method public java.lang.String getLongDescription();
+    method public java.lang.String getOfferPrice();
+    method public java.lang.String getPosterArtAspectRatio();
+    method public android.net.Uri getPosterArtUri();
+    method public android.net.Uri getPreviewVideoUri();
+    method public java.lang.String getReleaseDate();
+    method public java.lang.String getReviewRating();
+    method public java.lang.String getReviewRatingStyle();
+    method public java.lang.String getSeasonNumber();
+    method public java.lang.String getSeasonTitle();
+    method public long getStartTimeUtcMillis();
+    method public java.lang.String getStartingPrice();
+    method public java.lang.String getThumbnailAspectRatio();
+    method public android.net.Uri getThumbnailUri();
+    method public java.lang.String getTitle();
+    method public java.lang.String getType();
+    method public int getVideoHeight();
+    method public int getVideoWidth();
+    method public java.lang.String getWatchNextType();
+    method public int getWeight();
+    method public boolean isLive();
+    method public boolean isRecordingProhibited();
+    method public boolean isSearchable();
+    method public android.content.ContentValues toContentValues();
+  }
+
+  public static final class Program.Builder {
+    ctor public Program.Builder();
+    ctor public Program.Builder(android.support.media.tv.Program);
+    method public android.support.media.tv.Program build();
+    method public android.support.media.tv.Program.Builder setAppLinkIntent(android.content.Intent);
+    method public android.support.media.tv.Program.Builder setAppLinkIntentUri(android.net.Uri);
+    method public android.support.media.tv.Program.Builder setAudioLanguages(java.lang.String[]);
+    method public android.support.media.tv.Program.Builder setAuthor(java.lang.String);
+    method public android.support.media.tv.Program.Builder setAvailability(java.lang.String);
+    method public android.support.media.tv.Program.Builder setBroadcastGenres(java.lang.String[]);
+    method public android.support.media.tv.Program.Builder setCanonicalGenres(java.lang.String[]);
+    method public android.support.media.tv.Program.Builder setChannelId(long);
+    method public android.support.media.tv.Program.Builder setContentRatings(android.media.tv.TvContentRating[]);
+    method public android.support.media.tv.Program.Builder setDescription(java.lang.String);
+    method public android.support.media.tv.Program.Builder setDurationMillis(int);
+    method public android.support.media.tv.Program.Builder setEndTimeUtcMillis(long);
+    method public android.support.media.tv.Program.Builder setEpisodeNumber(int);
+    method public android.support.media.tv.Program.Builder setEpisodeNumber(java.lang.String, int);
+    method public android.support.media.tv.Program.Builder setEpisodeTitle(java.lang.String);
+    method public android.support.media.tv.Program.Builder setId(long);
+    method public android.support.media.tv.Program.Builder setInteractionCount(int);
+    method public android.support.media.tv.Program.Builder setInteractionType(java.lang.String);
+    method public android.support.media.tv.Program.Builder setInternalProviderData(byte[]);
+    method public android.support.media.tv.Program.Builder setInternalProviderFlag1(long);
+    method public android.support.media.tv.Program.Builder setInternalProviderFlag2(long);
+    method public android.support.media.tv.Program.Builder setInternalProviderFlag3(long);
+    method public android.support.media.tv.Program.Builder setInternalProviderFlag4(long);
+    method public android.support.media.tv.Program.Builder setInternalProviderId(java.lang.String);
+    method public android.support.media.tv.Program.Builder setItemCount(int);
+    method public android.support.media.tv.Program.Builder setLastPlaybackPositionMillis(int);
+    method public android.support.media.tv.Program.Builder setLive(boolean);
+    method public android.support.media.tv.Program.Builder setLogoUri(android.net.Uri);
+    method public android.support.media.tv.Program.Builder setLongDescription(java.lang.String);
+    method public android.support.media.tv.Program.Builder setOfferPrice(java.lang.String);
+    method public android.support.media.tv.Program.Builder setPosterArtAspectRatio(java.lang.String);
+    method public android.support.media.tv.Program.Builder setPosterArtUri(android.net.Uri);
+    method public android.support.media.tv.Program.Builder setPreviewVideoUri(android.net.Uri);
+    method public android.support.media.tv.Program.Builder setRecordingProhibited(boolean);
+    method public android.support.media.tv.Program.Builder setReleaseDate(java.lang.String);
+    method public android.support.media.tv.Program.Builder setReleaseDate(java.util.Date);
+    method public android.support.media.tv.Program.Builder setReviewRating(java.lang.String);
+    method public android.support.media.tv.Program.Builder setReviewRatingStyle(java.lang.String);
+    method public android.support.media.tv.Program.Builder setSearchable(boolean);
+    method public android.support.media.tv.Program.Builder setSeasonNumber(int);
+    method public android.support.media.tv.Program.Builder setSeasonNumber(java.lang.String, int);
+    method public android.support.media.tv.Program.Builder setSeasonTitle(java.lang.String);
+    method public android.support.media.tv.Program.Builder setStartTimeUtcMillis(long);
+    method public android.support.media.tv.Program.Builder setStartingPrice(java.lang.String);
+    method public android.support.media.tv.Program.Builder setThumbnailAspectRatio(java.lang.String);
+    method public android.support.media.tv.Program.Builder setThumbnailUri(android.net.Uri);
+    method public android.support.media.tv.Program.Builder setTitle(java.lang.String);
+    method public android.support.media.tv.Program.Builder setType(java.lang.String);
+    method public android.support.media.tv.Program.Builder setVideoHeight(int);
+    method public android.support.media.tv.Program.Builder setVideoWidth(int);
+    method public android.support.media.tv.Program.Builder setWatchNextType(java.lang.String);
+    method public android.support.media.tv.Program.Builder setWeight(int);
+  }
+
+  public final class TvContractCompat {
+    method public static android.net.Uri buildChannelLogoUri(long);
+    method public static android.net.Uri buildChannelLogoUri(android.net.Uri);
+    method public static android.net.Uri buildChannelUri(long);
+    method public static android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
+    method public static android.net.Uri buildChannelsUriForInput(java.lang.String);
+    method public static java.lang.String buildInputId(android.content.ComponentName);
+    method public static android.net.Uri buildProgramUri(long);
+    method public static android.net.Uri buildProgramsUriForChannel(long);
+    method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+    method public static android.net.Uri buildProgramsUriForChannel(long, long, long);
+    method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+    method public static android.net.Uri buildRecordedProgramUri(long);
+    method public static boolean isChannelUri(android.net.Uri);
+    method public static boolean isChannelUriForPassthroughInput(android.net.Uri);
+    method public static boolean isChannelUriForTunerInput(android.net.Uri);
+    method public static boolean isProgramUri(android.net.Uri);
+    field public static final java.lang.String AUTHORITY = "android.media.tv";
+  }
+
+  public static abstract interface TvContractCompat.BaseTvColumns {
+    field public static final java.lang.String COLUMN_PACKAGE_NAME = "package_name";
+  }
+
+  public static final class TvContractCompat.Channels implements android.support.media.tv.TvContractCompat.BaseTvColumns {
+    method public static java.lang.String getVideoResolution(java.lang.String);
+    field public static final java.lang.String COLUMN_APP_LINK_COLOR = "app_link_color";
+    field public static final java.lang.String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri";
+    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+    field public static final java.lang.String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
+    field public static final java.lang.String COLUMN_APP_LINK_TEXT = "app_link_text";
+    field public static final java.lang.String COLUMN_DESCRIPTION = "description";
+    field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
+    field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
+    field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_NETWORK_AFFILIATION = "network_affiliation";
+    field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
+    field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
+    field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
+    field public static final java.lang.String COLUMN_TYPE = "type";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_FORMAT = "video_format";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/channel";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
+    field public static final java.lang.String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO";
+    field public static final java.lang.String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
+    field public static final java.lang.String TYPE_1SEG = "TYPE_1SEG";
+    field public static final java.lang.String TYPE_ATSC_C = "TYPE_ATSC_C";
+    field public static final java.lang.String TYPE_ATSC_M_H = "TYPE_ATSC_M_H";
+    field public static final java.lang.String TYPE_ATSC_T = "TYPE_ATSC_T";
+    field public static final java.lang.String TYPE_CMMB = "TYPE_CMMB";
+    field public static final java.lang.String TYPE_DTMB = "TYPE_DTMB";
+    field public static final java.lang.String TYPE_DVB_C = "TYPE_DVB_C";
+    field public static final java.lang.String TYPE_DVB_C2 = "TYPE_DVB_C2";
+    field public static final java.lang.String TYPE_DVB_H = "TYPE_DVB_H";
+    field public static final java.lang.String TYPE_DVB_S = "TYPE_DVB_S";
+    field public static final java.lang.String TYPE_DVB_S2 = "TYPE_DVB_S2";
+    field public static final java.lang.String TYPE_DVB_SH = "TYPE_DVB_SH";
+    field public static final java.lang.String TYPE_DVB_T = "TYPE_DVB_T";
+    field public static final java.lang.String TYPE_DVB_T2 = "TYPE_DVB_T2";
+    field public static final java.lang.String TYPE_ISDB_C = "TYPE_ISDB_C";
+    field public static final java.lang.String TYPE_ISDB_S = "TYPE_ISDB_S";
+    field public static final java.lang.String TYPE_ISDB_T = "TYPE_ISDB_T";
+    field public static final java.lang.String TYPE_ISDB_TB = "TYPE_ISDB_TB";
+    field public static final java.lang.String TYPE_NTSC = "TYPE_NTSC";
+    field public static final java.lang.String TYPE_OTHER = "TYPE_OTHER";
+    field public static final java.lang.String TYPE_PAL = "TYPE_PAL";
+    field public static final java.lang.String TYPE_PREVIEW = "TYPE_PREVIEW";
+    field public static final java.lang.String TYPE_SECAM = "TYPE_SECAM";
+    field public static final java.lang.String TYPE_S_DMB = "TYPE_S_DMB";
+    field public static final java.lang.String TYPE_T_DMB = "TYPE_T_DMB";
+    field public static final java.lang.String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I";
+    field public static final java.lang.String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P";
+    field public static final java.lang.String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P";
+    field public static final java.lang.String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P";
+    field public static final java.lang.String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P";
+    field public static final java.lang.String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P";
+    field public static final java.lang.String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I";
+    field public static final java.lang.String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P";
+    field public static final java.lang.String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I";
+    field public static final java.lang.String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P";
+    field public static final java.lang.String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P";
+    field public static final java.lang.String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED";
+    field public static final java.lang.String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD";
+    field public static final java.lang.String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD";
+    field public static final java.lang.String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD";
+    field public static final java.lang.String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD";
+  }
+
+  public static final class TvContractCompat.Channels.Logo {
+    field public static final java.lang.String CONTENT_DIRECTORY = "logo";
+  }
+
+  public static final class TvContractCompat.Programs implements android.support.media.tv.TvContractCompat.BaseTvColumns {
+    field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+    field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+    field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+    field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+    field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+    field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+    field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    field public static final java.lang.String COLUMN_AUTHOR = "author";
+    field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
+    field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+    field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
+    field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
+    field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+    field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
+    field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+    field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
+    field public static final java.lang.String COLUMN_LIVE = "live";
+    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
+    field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+    field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+    field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+    field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
+    field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+    field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
+    field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_TYPE = "type";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+    field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+    field public static final java.lang.String COLUMN_WEIGHT = "weight";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
+    field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
+    field public static final java.lang.String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
+    field public static final java.lang.String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
+    field public static final java.lang.String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
+    field public static final java.lang.String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+    field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
+    field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
+    field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
+    field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+    field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
+    field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
+    field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
+    field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
+    field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
+    field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
+    field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+    field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
+    field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
+    field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+    field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+    field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+    field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+    field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+    field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
+  }
+
+  public static final class TvContractCompat.Programs.Genres {
+    method public static java.lang.String[] decode(java.lang.String);
+    method public static java.lang.String encode(java.lang.String...);
+    method public static boolean isCanonical(java.lang.String);
+    field public static final java.lang.String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE";
+    field public static final java.lang.String ARTS = "ARTS";
+    field public static final java.lang.String COMEDY = "COMEDY";
+    field public static final java.lang.String DRAMA = "DRAMA";
+    field public static final java.lang.String EDUCATION = "EDUCATION";
+    field public static final java.lang.String ENTERTAINMENT = "ENTERTAINMENT";
+    field public static final java.lang.String FAMILY_KIDS = "FAMILY_KIDS";
+    field public static final java.lang.String GAMING = "GAMING";
+    field public static final java.lang.String LIFE_STYLE = "LIFE_STYLE";
+    field public static final java.lang.String MOVIES = "MOVIES";
+    field public static final java.lang.String MUSIC = "MUSIC";
+    field public static final java.lang.String NEWS = "NEWS";
+    field public static final java.lang.String PREMIER = "PREMIER";
+    field public static final java.lang.String SHOPPING = "SHOPPING";
+    field public static final java.lang.String SPORTS = "SPORTS";
+    field public static final java.lang.String TECH_SCIENCE = "TECH_SCIENCE";
+    field public static final java.lang.String TRAVEL = "TRAVEL";
+  }
+
+  public static final class TvContractCompat.RecordedPrograms implements android.support.media.tv.TvContractCompat.BaseTvColumns {
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+    field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
+    field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+    field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+    field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
+    field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
+    field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
+    field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
+    field public static final android.net.Uri CONTENT_URI;
+  }
+
+}
+
 package android.support.percent {
 
   public class PercentFrameLayout extends android.widget.FrameLayout {
@@ -1134,29 +1590,42 @@
     method public android.support.transition.Transition addListener(android.support.transition.Transition.TransitionListener);
     method public android.support.transition.Transition addTarget(android.view.View);
     method public android.support.transition.Transition addTarget(int);
+    method public android.support.transition.Transition addTarget(java.lang.String);
+    method public android.support.transition.Transition addTarget(java.lang.Class);
     method public abstract void captureEndValues(android.support.transition.TransitionValues);
     method public abstract void captureStartValues(android.support.transition.TransitionValues);
+    method public android.support.transition.Transition clone();
     method public android.animation.Animator createAnimator(android.view.ViewGroup, android.support.transition.TransitionValues, android.support.transition.TransitionValues);
     method public android.support.transition.Transition excludeChildren(android.view.View, boolean);
     method public android.support.transition.Transition excludeChildren(int, boolean);
     method public android.support.transition.Transition excludeChildren(java.lang.Class, boolean);
     method public android.support.transition.Transition excludeTarget(android.view.View, boolean);
     method public android.support.transition.Transition excludeTarget(int, boolean);
+    method public android.support.transition.Transition excludeTarget(java.lang.String, boolean);
     method public android.support.transition.Transition excludeTarget(java.lang.Class, boolean);
     method public long getDuration();
     method public android.animation.TimeInterpolator getInterpolator();
     method public java.lang.String getName();
     method public long getStartDelay();
     method public java.util.List<java.lang.Integer> getTargetIds();
+    method public java.util.List<java.lang.String> getTargetNames();
+    method public java.util.List<java.lang.Class> getTargetTypes();
     method public java.util.List<android.view.View> getTargets();
     method public java.lang.String[] getTransitionProperties();
     method public android.support.transition.TransitionValues getTransitionValues(android.view.View, boolean);
     method public android.support.transition.Transition removeListener(android.support.transition.Transition.TransitionListener);
     method public android.support.transition.Transition removeTarget(android.view.View);
     method public android.support.transition.Transition removeTarget(int);
+    method public android.support.transition.Transition removeTarget(java.lang.String);
+    method public android.support.transition.Transition removeTarget(java.lang.Class);
     method public android.support.transition.Transition setDuration(long);
     method public android.support.transition.Transition setInterpolator(android.animation.TimeInterpolator);
+    method public void setMatchOrder(int...);
     method public android.support.transition.Transition setStartDelay(long);
+    field public static final int MATCH_ID = 3; // 0x3
+    field public static final int MATCH_INSTANCE = 1; // 0x1
+    field public static final int MATCH_ITEM_ID = 4; // 0x4
+    field public static final int MATCH_NAME = 2; // 0x2
   }
 
   public static abstract interface Transition.TransitionListener {
@@ -1184,6 +1653,8 @@
     method public void captureEndValues(android.support.transition.TransitionValues);
     method public void captureStartValues(android.support.transition.TransitionValues);
     method public int getOrdering();
+    method public android.support.transition.Transition getTransitionAt(int);
+    method public int getTransitionCount();
     method public android.support.transition.TransitionSet removeTransition(android.support.transition.Transition);
     method public android.support.transition.TransitionSet setOrdering(int);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
@@ -1283,6 +1754,8 @@
     ctor public EditorInfoCompat();
     method public static java.lang.String[] getContentMimeTypes(android.view.inputmethod.EditorInfo);
     method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, java.lang.String[]);
+    field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
+    field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
   }
 
   public final class InputConnectionCompat {
@@ -1995,36 +2468,44 @@
   public abstract class OnboardingFragment extends android.app.Fragment {
     ctor public OnboardingFragment();
     method protected final int getCurrentPageIndex();
+    method public final int getIconResourceId();
     method public final int getLogoResourceId();
     method protected abstract int getPageCount();
     method protected abstract java.lang.CharSequence getPageDescription(int);
     method protected abstract java.lang.CharSequence getPageTitle(int);
     method protected abstract android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup);
     method protected abstract android.view.View onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateDescriptionAnimator();
     method protected android.animation.Animator onCreateEnterAnimation();
     method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
     method protected android.animation.Animator onCreateLogoAnimation();
+    method protected android.animation.Animator onCreateTitleAnimator();
     method protected void onFinishFragment();
     method protected void onPageChanged(int, int);
     method public int onProvideTheme();
+    method public final void setIconResouceId(int);
     method public final void setLogoResourceId(int);
   }
 
   public abstract class OnboardingSupportFragment extends android.support.v4.app.Fragment {
     ctor public OnboardingSupportFragment();
     method protected final int getCurrentPageIndex();
+    method public final int getIconResourceId();
     method public final int getLogoResourceId();
     method protected abstract int getPageCount();
     method protected abstract java.lang.CharSequence getPageDescription(int);
     method protected abstract java.lang.CharSequence getPageTitle(int);
     method protected abstract android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup);
     method protected abstract android.view.View onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateDescriptionAnimator();
     method protected android.animation.Animator onCreateEnterAnimation();
     method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
     method protected android.animation.Animator onCreateLogoAnimation();
+    method protected android.animation.Animator onCreateTitleAnimator();
     method protected void onFinishFragment();
     method protected void onPageChanged(int, int);
     method public int onProvideTheme();
+    method public final void setIconResouceId(int);
     method public final void setLogoResourceId(int);
   }
 
@@ -4398,6 +4879,13 @@
     field public static final java.lang.String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
   }
 
+  public final class AlarmManagerCompat {
+    method public static void setAlarmClock(android.app.AlarmManager, long, android.app.PendingIntent, android.app.PendingIntent);
+    method public static void setAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExact(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExactAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+  }
+
   public class AppLaunchChecker {
     ctor public AppLaunchChecker();
     method public static boolean hasStartedFromLauncher(android.content.Context);
@@ -4480,6 +4968,7 @@
     method public final boolean isInLayout();
     method public final boolean isRemoving();
     method public final boolean isResumed();
+    method public final boolean isStateSaved();
     method public final boolean isVisible();
     method public void onActivityCreated(android.os.Bundle);
     method public void onActivityResult(int, int, android.content.Intent);
@@ -4559,14 +5048,12 @@
     method public java.lang.Object getLastCustomNonConfigurationInstance();
     method public android.support.v4.app.FragmentManager getSupportFragmentManager();
     method public android.support.v4.app.LoaderManager getSupportLoaderManager();
-    method public final deprecated android.support.v4.media.session.MediaControllerCompat getSupportMediaController();
     method public void onAttachFragment(android.support.v4.app.Fragment);
     method protected void onResumeFragments();
     method public java.lang.Object onRetainCustomNonConfigurationInstance();
     method public final java.lang.Object onRetainNonConfigurationInstance();
     method public void setEnterSharedElementCallback(android.support.v4.app.SharedElementCallback);
     method public void setExitSharedElementCallback(android.support.v4.app.SharedElementCallback);
-    method public final deprecated void setSupportMediaController(android.support.v4.media.session.MediaControllerCompat);
     method public void startActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int);
     method public void startActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int, android.os.Bundle);
     method public void startIntentSenderFromFragment(android.support.v4.app.Fragment, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -4579,6 +5066,7 @@
 
   public abstract class FragmentContainer {
     ctor public FragmentContainer();
+    method public android.support.v4.app.Fragment instantiate(android.content.Context, java.lang.String, android.os.Bundle);
     method public abstract android.view.View onFindViewById(int);
     method public abstract boolean onHasView();
   }
@@ -4657,6 +5145,7 @@
     method public abstract android.support.v4.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
     method public abstract int getBackStackEntryCount();
     method public abstract android.support.v4.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+    method public abstract android.support.v4.app.Fragment getPrimaryNavigationFragment();
     method public abstract boolean isDestroyed();
     method public abstract void popBackStack();
     method public abstract void popBackStack(java.lang.String, int);
@@ -4744,6 +5233,7 @@
     method public abstract android.support.v4.app.FragmentTransaction hide(android.support.v4.app.Fragment);
     method public abstract boolean isAddToBackStackAllowed();
     method public abstract boolean isEmpty();
+    method public abstract android.support.v4.app.FragmentTransaction postOnCommit(java.lang.Runnable);
     method public abstract android.support.v4.app.FragmentTransaction remove(android.support.v4.app.Fragment);
     method public abstract android.support.v4.app.FragmentTransaction replace(int, android.support.v4.app.Fragment);
     method public abstract android.support.v4.app.FragmentTransaction replace(int, android.support.v4.app.Fragment, java.lang.String);
@@ -4754,6 +5244,7 @@
     method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
     method public abstract android.support.v4.app.FragmentTransaction setCustomAnimations(int, int);
     method public abstract android.support.v4.app.FragmentTransaction setCustomAnimations(int, int, int, int);
+    method public abstract android.support.v4.app.FragmentTransaction setPrimaryNavigationFragment(android.support.v4.app.Fragment);
     method public abstract android.support.v4.app.FragmentTransaction setTransition(int);
     method public abstract android.support.v4.app.FragmentTransaction setTransitionStyle(int);
     method public abstract android.support.v4.app.FragmentTransaction show(android.support.v4.app.Fragment);
@@ -4814,6 +5305,7 @@
     method public static android.support.v4.app.NotificationCompat.Action getAction(android.app.Notification, int);
     method public static int getActionCount(android.app.Notification);
     method public static java.lang.String getCategory(android.app.Notification);
+    method public static java.lang.String getChannel(android.app.Notification);
     method public static android.os.Bundle getExtras(android.app.Notification);
     method public static java.lang.String getGroup(android.app.Notification);
     method public static boolean getLocalOnly(android.app.Notification);
@@ -4839,6 +5331,7 @@
     field public static final int DEFAULT_LIGHTS = 4; // 0x4
     field public static final int DEFAULT_SOUND = 1; // 0x1
     field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final java.lang.String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
     field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
     field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
     field public static final java.lang.String EXTRA_COMPACT_ACTIONS = "android.compactActions";
@@ -4890,6 +5383,7 @@
     ctor public NotificationCompat.Action(int, java.lang.CharSequence, android.app.PendingIntent);
     method public android.app.PendingIntent getActionIntent();
     method public boolean getAllowGeneratedReplies();
+    method public android.support.v4.app.RemoteInput[] getDataOnlyRemoteInputs();
     method public android.os.Bundle getExtras();
     method public int getIcon();
     method public android.support.v4.app.RemoteInput[] getRemoteInputs();
@@ -4963,6 +5457,7 @@
     method protected static java.lang.CharSequence limitCharSequenceLength(java.lang.CharSequence);
     method public android.support.v4.app.NotificationCompat.Builder setAutoCancel(boolean);
     method public android.support.v4.app.NotificationCompat.Builder setCategory(java.lang.String);
+    method public android.support.v4.app.NotificationCompat.Builder setChannel(java.lang.String);
     method public android.support.v4.app.NotificationCompat.Builder setColor(int);
     method public android.support.v4.app.NotificationCompat.Builder setContent(android.widget.RemoteViews);
     method public android.support.v4.app.NotificationCompat.Builder setContentInfo(java.lang.CharSequence);
@@ -5176,13 +5671,17 @@
   }
 
   public final class RemoteInput extends android.support.v4.app.RemoteInputCompatBase.RemoteInput {
+    method public static void addDataResultToIntent(android.support.v4.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String, android.net.Uri>);
     method public static void addResultsToIntent(android.support.v4.app.RemoteInput[], android.content.Intent, android.os.Bundle);
     method public boolean getAllowFreeFormInput();
+    method public java.util.Set<java.lang.String> getAllowedDataTypes();
     method public java.lang.CharSequence[] getChoices();
+    method public static java.util.Map<java.lang.String, android.net.Uri> getDataResultsFromIntent(android.content.Intent, java.lang.String);
     method public android.os.Bundle getExtras();
     method public java.lang.CharSequence getLabel();
     method public java.lang.String getResultKey();
     method public static android.os.Bundle getResultsFromIntent(android.content.Intent);
+    method public boolean isDataOnly();
     field public static final java.lang.String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
     field public static final java.lang.String RESULTS_CLIP_LABEL = "android.remoteinput.results";
   }
@@ -5192,6 +5691,7 @@
     method public android.support.v4.app.RemoteInput.Builder addExtras(android.os.Bundle);
     method public android.support.v4.app.RemoteInput build();
     method public android.os.Bundle getExtras();
+    method public android.support.v4.app.RemoteInput.Builder setAllowDataType(java.lang.String, boolean);
     method public android.support.v4.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
     method public android.support.v4.app.RemoteInput.Builder setChoices(java.lang.CharSequence[]);
     method public android.support.v4.app.RemoteInput.Builder setLabel(java.lang.CharSequence);
@@ -5203,6 +5703,7 @@
   public static abstract class RemoteInputCompatBase.RemoteInput {
     ctor public RemoteInputCompatBase.RemoteInput();
     method protected abstract boolean getAllowFreeFormInput();
+    method protected abstract java.util.Set<java.lang.String> getAllowedDataTypes();
     method protected abstract java.lang.CharSequence[] getChoices();
     method protected abstract android.os.Bundle getExtras();
     method protected abstract java.lang.CharSequence getLabel();
@@ -5442,6 +5943,13 @@
     method public void unregisterReceiver(android.content.BroadcastReceiver);
   }
 
+  public final class MimeTypeFilter {
+    method public static boolean matches(java.lang.String, java.lang.String);
+    method public static java.lang.String matches(java.lang.String, java.lang.String[]);
+    method public static java.lang.String matches(java.lang.String[], java.lang.String);
+    method public static java.lang.String[] matchesMany(java.lang.String[], java.lang.String);
+  }
+
   public final class ParallelExecutorCompat {
     method public static java.util.concurrent.Executor getParallelExecutor();
   }
@@ -5481,6 +5989,29 @@
     field public static final int CONFIG_UI_MODE = 512; // 0x200
   }
 
+  public class ShortcutInfoCompat {
+  }
+
+  public static class ShortcutInfoCompat.Builder {
+    ctor public ShortcutInfoCompat.Builder(android.content.Context, java.lang.String);
+    method public android.support.v4.content.pm.ShortcutInfoCompat build();
+    method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setActivity(android.content.ComponentName);
+    method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setDisabledMessage(java.lang.CharSequence);
+    method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setIcon(android.graphics.Bitmap);
+    method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setIcon(int);
+    method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setIntent(android.content.Intent);
+    method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setIntents(android.content.Intent[]);
+    method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setLongLabel(java.lang.CharSequence);
+    method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setShortLabel(java.lang.CharSequence);
+  }
+
+  public class ShortcutManagerCompat {
+    ctor public ShortcutManagerCompat();
+    method public static android.content.Intent createShortcutResultIntent(android.content.Context, android.support.v4.content.pm.ShortcutInfoCompat);
+    method public static boolean isRequestPinShortcutSupported(android.content.Context);
+    method public static boolean requestPinShortcut(android.content.Context, android.support.v4.content.pm.ShortcutInfoCompat, android.content.IntentSender);
+  }
+
 }
 
 package android.support.v4.content.res {
@@ -5645,6 +6176,17 @@
 
 }
 
+package android.support.v4.math {
+
+  public class MathUtils {
+    ctor public MathUtils();
+    method public static float clamp(float, int, int);
+    method public static double clamp(double, double, double);
+    method public static int clamp(int, int, int);
+  }
+
+}
+
 package android.support.v4.media {
 
   public final class MediaBrowserCompat {
@@ -5971,9 +6513,11 @@
     method public java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem> getQueue();
     method public java.lang.CharSequence getQueueTitle();
     method public int getRatingType();
+    method public int getRepeatMode();
     method public android.app.PendingIntent getSessionActivity();
     method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
     method public android.support.v4.media.session.MediaControllerCompat.TransportControls getTransportControls();
+    method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback);
     method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback, android.os.Handler);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
@@ -5991,8 +6535,10 @@
     method public void onPlaybackStateChanged(android.support.v4.media.session.PlaybackStateCompat);
     method public void onQueueChanged(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>);
     method public void onQueueTitleChanged(java.lang.CharSequence);
+    method public void onRepeatModeChanged(int);
     method public void onSessionDestroyed();
     method public void onSessionEvent(java.lang.String, android.os.Bundle);
+    method public void onShuffleModeChanged(boolean);
   }
 
   public static final class MediaControllerCompat.PlaybackInfo {
@@ -6021,6 +6567,8 @@
     method public abstract void sendCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction, android.os.Bundle);
     method public abstract void sendCustomAction(java.lang.String, android.os.Bundle);
     method public abstract void setRating(android.support.v4.media.RatingCompat);
+    method public abstract void setRepeatMode(int);
+    method public abstract void setShuffleModeEnabled(boolean);
     method public abstract void skipToNext();
     method public abstract void skipToPrevious();
     method public abstract void skipToQueueItem(long);
@@ -6054,7 +6602,9 @@
     method public void setQueue(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>);
     method public void setQueueTitle(java.lang.CharSequence);
     method public void setRatingType(int);
+    method public void setRepeatMode(int);
     method public void setSessionActivity(android.app.PendingIntent);
+    method public void setShuffleModeEnabled(boolean);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
@@ -6077,6 +6627,8 @@
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.support.v4.media.RatingCompat);
+    method public void onSetRepeatMode(int);
+    method public void onSetShuffleModeEnabled(boolean);
     method public void onSkipToNext();
     method public void onSkipToPrevious();
     method public void onSkipToQueueItem(long);
@@ -6153,6 +6705,8 @@
     field public static final long ACTION_REWIND = 8L; // 0x8L
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
+    field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
+    field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
     field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
     field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
@@ -6171,6 +6725,9 @@
     field public static final int ERROR_CODE_SKIP_LIMIT_REACHED = 9; // 0x9
     field public static final int ERROR_CODE_UNKNOWN_ERROR = 0; // 0x0
     field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
+    field public static final int REPEAT_MODE_ALL = 2; // 0x2
+    field public static final int REPEAT_MODE_NONE = 0; // 0x0
+    field public static final int REPEAT_MODE_ONE = 1; // 0x1
     field public static final int STATE_BUFFERING = 6; // 0x6
     field public static final int STATE_CONNECTING = 8; // 0x8
     field public static final int STATE_ERROR = 7; // 0x7
@@ -6248,8 +6805,8 @@
 
 package android.support.v4.os {
 
-  public final class AsyncTaskCompat {
-    method public static <Params, Progress, Result> android.os.AsyncTask<Params, Progress, Result> executeParallel(android.os.AsyncTask<Params, Progress, Result>, Params...);
+  public final deprecated class AsyncTaskCompat {
+    method public static deprecated <Params, Progress, Result> android.os.AsyncTask<Params, Progress, Result> executeParallel(android.os.AsyncTask<Params, Progress, Result>, Params...);
   }
 
   public class BuildCompat {
@@ -6773,12 +7330,16 @@
     method public static boolean expandActionView(android.view.MenuItem);
     method public static android.support.v4.view.ActionProvider getActionProvider(android.view.MenuItem);
     method public static android.view.View getActionView(android.view.MenuItem);
+    method public static java.lang.CharSequence getContentDescription(android.view.MenuItem);
+    method public static java.lang.CharSequence getTooltipText(android.view.MenuItem);
     method public static boolean isActionViewExpanded(android.view.MenuItem);
     method public static android.view.MenuItem setActionProvider(android.view.MenuItem, android.support.v4.view.ActionProvider);
     method public static android.view.MenuItem setActionView(android.view.MenuItem, android.view.View);
     method public static android.view.MenuItem setActionView(android.view.MenuItem, int);
+    method public static void setContentDescription(android.view.MenuItem, java.lang.CharSequence);
     method public static android.view.MenuItem setOnActionExpandListener(android.view.MenuItem, android.support.v4.view.MenuItemCompat.OnActionExpandListener);
     method public static void setShowAsAction(android.view.MenuItem, int);
+    method public static void setTooltipText(android.view.MenuItem, java.lang.CharSequence);
     field public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
     field public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
     field public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
@@ -7007,9 +7568,9 @@
     method public abstract void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode);
   }
 
-  public final class VelocityTrackerCompat {
-    method public static float getXVelocity(android.view.VelocityTracker, int);
-    method public static float getYVelocity(android.view.VelocityTracker, int);
+  public final deprecated class VelocityTrackerCompat {
+    method public static deprecated float getXVelocity(android.view.VelocityTracker, int);
+    method public static deprecated float getYVelocity(android.view.VelocityTracker, int);
   }
 
   public class ViewCompat {
@@ -7017,7 +7578,7 @@
     method public static android.support.v4.view.ViewPropertyAnimatorCompat animate(android.view.View);
     method public static boolean canScrollHorizontally(android.view.View, int);
     method public static boolean canScrollVertically(android.view.View, int);
-    method public static int combineMeasuredStates(int, int);
+    method public static deprecated int combineMeasuredStates(int, int);
     method public static android.support.v4.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
     method public static void dispatchFinishTemporaryDetach(android.view.View);
     method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
@@ -7027,7 +7588,7 @@
     method public static void dispatchStartTemporaryDetach(android.view.View);
     method public static int getAccessibilityLiveRegion(android.view.View);
     method public static android.support.v4.view.accessibility.AccessibilityNodeProviderCompat getAccessibilityNodeProvider(android.view.View);
-    method public static float getAlpha(android.view.View);
+    method public static deprecated float getAlpha(android.view.View);
     method public static android.content.res.ColorStateList getBackgroundTintList(android.view.View);
     method public static android.graphics.PorterDuff.Mode getBackgroundTintMode(android.view.View);
     method public static android.graphics.Rect getClipBounds(android.view.View);
@@ -7036,33 +7597,33 @@
     method public static boolean getFitsSystemWindows(android.view.View);
     method public static int getImportantForAccessibility(android.view.View);
     method public static int getLabelFor(android.view.View);
-    method public static int getLayerType(android.view.View);
+    method public static deprecated int getLayerType(android.view.View);
     method public static int getLayoutDirection(android.view.View);
-    method public static android.graphics.Matrix getMatrix(android.view.View);
-    method public static int getMeasuredHeightAndState(android.view.View);
-    method public static int getMeasuredState(android.view.View);
-    method public static int getMeasuredWidthAndState(android.view.View);
+    method public static deprecated android.graphics.Matrix getMatrix(android.view.View);
+    method public static deprecated int getMeasuredHeightAndState(android.view.View);
+    method public static deprecated int getMeasuredState(android.view.View);
+    method public static deprecated int getMeasuredWidthAndState(android.view.View);
     method public static int getMinimumHeight(android.view.View);
     method public static int getMinimumWidth(android.view.View);
     method public static deprecated int getOverScrollMode(android.view.View);
     method public static int getPaddingEnd(android.view.View);
     method public static int getPaddingStart(android.view.View);
     method public static android.view.ViewParent getParentForAccessibility(android.view.View);
-    method public static float getPivotX(android.view.View);
-    method public static float getPivotY(android.view.View);
-    method public static float getRotation(android.view.View);
-    method public static float getRotationX(android.view.View);
-    method public static float getRotationY(android.view.View);
-    method public static float getScaleX(android.view.View);
-    method public static float getScaleY(android.view.View);
+    method public static deprecated float getPivotX(android.view.View);
+    method public static deprecated float getPivotY(android.view.View);
+    method public static deprecated float getRotation(android.view.View);
+    method public static deprecated float getRotationX(android.view.View);
+    method public static deprecated float getRotationY(android.view.View);
+    method public static deprecated float getScaleX(android.view.View);
+    method public static deprecated float getScaleY(android.view.View);
     method public static int getScrollIndicators(android.view.View);
     method public static java.lang.String getTransitionName(android.view.View);
-    method public static float getTranslationX(android.view.View);
-    method public static float getTranslationY(android.view.View);
+    method public static deprecated float getTranslationX(android.view.View);
+    method public static deprecated float getTranslationY(android.view.View);
     method public static float getTranslationZ(android.view.View);
     method public static int getWindowSystemUiVisibility(android.view.View);
-    method public static float getX(android.view.View);
-    method public static float getY(android.view.View);
+    method public static deprecated float getX(android.view.View);
+    method public static deprecated float getY(android.view.View);
     method public static float getZ(android.view.View);
     method public static boolean hasAccessibilityDelegate(android.view.View);
     method public static boolean hasNestedScrollingParent(android.view.View);
@@ -7077,7 +7638,7 @@
     method public static boolean isNestedScrollingEnabled(android.view.View);
     method public static deprecated boolean isOpaque(android.view.View);
     method public static boolean isPaddingRelative(android.view.View);
-    method public static void jumpDrawablesToCurrentState(android.view.View);
+    method public static deprecated void jumpDrawablesToCurrentState(android.view.View);
     method public static void offsetLeftAndRight(android.view.View, int);
     method public static void offsetTopAndBottom(android.view.View, int);
     method public static android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
@@ -7090,11 +7651,11 @@
     method public static void postOnAnimation(android.view.View, java.lang.Runnable);
     method public static void postOnAnimationDelayed(android.view.View, java.lang.Runnable, long);
     method public static void requestApplyInsets(android.view.View);
-    method public static int resolveSizeAndState(int, int, int);
+    method public static deprecated int resolveSizeAndState(int, int, int);
     method public static void setAccessibilityDelegate(android.view.View, android.support.v4.view.AccessibilityDelegateCompat);
     method public static void setAccessibilityLiveRegion(android.view.View, int);
-    method public static void setActivated(android.view.View, boolean);
-    method public static void setAlpha(android.view.View, float);
+    method public static deprecated void setActivated(android.view.View, boolean);
+    method public static deprecated void setAlpha(android.view.View, float);
     method public static void setBackground(android.view.View, android.graphics.drawable.Drawable);
     method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList);
     method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode);
@@ -7106,29 +7667,30 @@
     method public static void setImportantForAccessibility(android.view.View, int);
     method public static void setLabelFor(android.view.View, int);
     method public static void setLayerPaint(android.view.View, android.graphics.Paint);
-    method public static void setLayerType(android.view.View, int, android.graphics.Paint);
+    method public static deprecated void setLayerType(android.view.View, int, android.graphics.Paint);
     method public static void setLayoutDirection(android.view.View, int);
     method public static void setNestedScrollingEnabled(android.view.View, boolean);
     method public static void setOnApplyWindowInsetsListener(android.view.View, android.support.v4.view.OnApplyWindowInsetsListener);
     method public static deprecated void setOverScrollMode(android.view.View, int);
     method public static void setPaddingRelative(android.view.View, int, int, int, int);
-    method public static void setPivotX(android.view.View, float);
-    method public static void setPivotY(android.view.View, float);
+    method public static deprecated void setPivotX(android.view.View, float);
+    method public static deprecated void setPivotY(android.view.View, float);
     method public static void setPointerIcon(android.view.View, android.support.v4.view.PointerIconCompat);
-    method public static void setRotation(android.view.View, float);
-    method public static void setRotationX(android.view.View, float);
-    method public static void setRotationY(android.view.View, float);
-    method public static void setSaveFromParentEnabled(android.view.View, boolean);
-    method public static void setScaleX(android.view.View, float);
-    method public static void setScaleY(android.view.View, float);
+    method public static deprecated void setRotation(android.view.View, float);
+    method public static deprecated void setRotationX(android.view.View, float);
+    method public static deprecated void setRotationY(android.view.View, float);
+    method public static deprecated void setSaveFromParentEnabled(android.view.View, boolean);
+    method public static deprecated void setScaleX(android.view.View, float);
+    method public static deprecated void setScaleY(android.view.View, float);
     method public static void setScrollIndicators(android.view.View, int);
     method public static void setScrollIndicators(android.view.View, int, int);
+    method public static void setTooltipText(android.view.View, java.lang.CharSequence);
     method public static void setTransitionName(android.view.View, java.lang.String);
-    method public static void setTranslationX(android.view.View, float);
-    method public static void setTranslationY(android.view.View, float);
+    method public static deprecated void setTranslationX(android.view.View, float);
+    method public static deprecated void setTranslationY(android.view.View, float);
     method public static void setTranslationZ(android.view.View, float);
-    method public static void setX(android.view.View, float);
-    method public static void setY(android.view.View, float);
+    method public static deprecated void setX(android.view.View, float);
+    method public static deprecated void setY(android.view.View, float);
     method public static void setZ(android.view.View, float);
     method public static boolean startNestedScroll(android.view.View, int);
     method public static void stopNestedScroll(android.view.View);
@@ -7146,10 +7708,10 @@
     field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
     field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
     field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
-    field public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
-    field public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
-    field public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
-    field public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
+    field public static final deprecated int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
+    field public static final deprecated int MEASURED_SIZE_MASK = 16777215; // 0xffffff
+    field public static final deprecated int MEASURED_STATE_MASK = -16777216; // 0xff000000
+    field public static final deprecated int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
     field public static final deprecated int OVER_SCROLL_ALWAYS = 0; // 0x0
     field public static final deprecated int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
     field public static final deprecated int OVER_SCROLL_NEVER = 2; // 0x2
@@ -10525,6 +11087,7 @@
     method public boolean isLayoutHierarchical(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
     method public boolean isMeasurementCacheEnabled();
     method public boolean isSmoothScrolling();
+    method public boolean isViewPartiallyVisible(android.view.View, boolean, boolean);
     method public void layoutDecorated(android.view.View, int, int, int, int);
     method public void layoutDecoratedWithMargins(android.view.View, int, int, int, int);
     method public void measureChild(android.view.View, int, int);
@@ -10569,6 +11132,7 @@
     method public void removeView(android.view.View);
     method public void removeViewAt(int);
     method public boolean requestChildRectangleOnScreen(android.support.v7.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean);
+    method public boolean requestChildRectangleOnScreen(android.support.v7.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean, boolean);
     method public void requestLayout();
     method public void requestSimpleAnimationsInNextLayout();
     method public int scrollHorizontallyBy(int, android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
@@ -10744,6 +11308,10 @@
     method public android.support.v4.view.AccessibilityDelegateCompat getItemDelegate();
   }
 
+  public static class RecyclerViewAccessibilityDelegate.ItemDelegate extends android.support.v4.view.AccessibilityDelegateCompat {
+    ctor public RecyclerViewAccessibilityDelegate.ItemDelegate(android.support.v7.widget.RecyclerViewAccessibilityDelegate);
+  }
+
   public class SearchView extends android.support.v7.widget.LinearLayoutCompat implements android.support.v7.view.CollapsibleActionView {
     ctor public SearchView(android.content.Context);
     ctor public SearchView(android.content.Context, android.util.AttributeSet);
@@ -11111,3 +11679,32 @@
 
 }
 
+package android.support.wearable.view {
+
+  public class BoxInsetLayout extends android.view.ViewGroup {
+    ctor public BoxInsetLayout(android.content.Context);
+    ctor public BoxInsetLayout(android.content.Context, android.util.AttributeSet);
+    ctor public BoxInsetLayout(android.content.Context, android.util.AttributeSet, int);
+    method protected void onLayout(boolean, int, int, int, int);
+  }
+
+  public static class BoxInsetLayout.LayoutParams extends android.widget.FrameLayout.LayoutParams {
+    ctor public BoxInsetLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public BoxInsetLayout.LayoutParams(int, int);
+    ctor public BoxInsetLayout.LayoutParams(int, int, int);
+    ctor public BoxInsetLayout.LayoutParams(int, int, int, int);
+    ctor public BoxInsetLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public BoxInsetLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public BoxInsetLayout.LayoutParams(android.widget.FrameLayout.LayoutParams);
+    ctor public BoxInsetLayout.LayoutParams(android.support.wearable.view.BoxInsetLayout.LayoutParams);
+    field public static final int BOX_ALL = 15; // 0xf
+    field public static final int BOX_BOTTOM = 8; // 0x8
+    field public static final int BOX_LEFT = 1; // 0x1
+    field public static final int BOX_NONE = 0; // 0x0
+    field public static final int BOX_RIGHT = 4; // 0x4
+    field public static final int BOX_TOP = 2; // 0x2
+    field public int boxedEdges;
+  }
+
+}
+
diff --git a/build.gradle b/build.gradle
index 59ef734..c2dc7a9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,8 +1,11 @@
+import android.support.checkapi.ApiXmlConversionTask
 import android.support.checkapi.CheckApiTask
 import android.support.checkapi.UpdateApiTask
 import android.support.doclava.DoclavaMultilineJavadocOptionFileOption
 import android.support.doclava.DoclavaTask
+import android.support.jdiff.JDiffTask
 
+import com.android.build.gradle.internal.coverage.JacocoPlugin
 import com.android.build.gradle.internal.coverage.JacocoReportTask
 import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask
 import org.gradle.internal.os.OperatingSystem
@@ -16,37 +19,42 @@
 import groovy.io.FileType
 
 buildscript {
+    apply from: 'buildSrc/dependencies.gradle'
+
     repositories {
         maven { url '../../prebuilts/gradle-plugin' }
         maven { url '../../prebuilts/tools/common/m2/repository' }
         maven { url '../../prebuilts/tools/common/m2/internal' }
-        maven { url "../../prebuilts/maven_repo/android" }
+        maven { url '../../prebuilts/maven_repo/android' }
     }
     dependencies {
-        // Keep gradle plugin version in sync with ub_supportlib-master manifest.
-        classpath 'com.android.tools.build:gradle:2.2.4'
+        classpath libs.gradle
     }
 }
 
+apply from: 'buildSrc/dependencies.gradle'
+
 repositories {
     maven { url '../../prebuilts/tools/common/m2/repository' }
 }
 
 configurations {
     doclava
+    jdiff
 }
 
 dependencies {
     doclava project(':doclava')
+    jdiff project(':jdiff')
+    jdiff libs.xml_parser_apis
+    jdiff libs.xerces_impl
 }
 
-ext.supportVersion = '25.4.0-SNAPSHOT'
-ext.extraVersion = 43
-ext.supportRepoOut = ''
-ext.buildNumber = Integer.toString(ext.extraVersion)
+// Version code components.
+ext.supportVersion = "26.0.0-SNAPSHOT"
 
-ext.testRunnerVersion = '0.6-alpha'
-ext.espressoVersion = '2.3-alpha'
+// This number gets incremented for each public release.
+ext.extraVersion = 43
 
 // Enforce the use of prebuilt dependencies in all sub-projects. This is
 // required for the doclava dependency.
@@ -56,8 +64,8 @@
 System.setProperty('android.dir', "${rootDir}/../../")
 final String fullSdkPath = "${rootDir}/../../prebuilts/fullsdk-${platform}"
 if (file(fullSdkPath).exists()) {
-    gradle.ext.currentSdk = 25
-    ext.buildToolsVersion = '24.0.1'
+    gradle.ext.currentSdk = 26
+    ext.buildToolsVersion = '26.0.0'
     project.ext.androidJar = files("${fullSdkPath}/platforms/android-${gradle.ext.currentSdk}/android.jar")
     System.setProperty('android.home', "${rootDir}/../../prebuilts/fullsdk-${platform}")
     File props = file("local.properties")
@@ -70,6 +78,9 @@
     props.write "android.dir=../../"
 }
 
+ext.supportRepoOut = ''
+ext.buildNumber = Integer.toString(ext.extraVersion)
+
 /*
  * With the build server you are given two env variables.
  * The OUT_DIR is a temporary directory you can use to put things during the build.
@@ -98,13 +109,11 @@
 ext.testApkDistOut = ext.distDir
 
 // Main task called by the build server.
-task(createArchive) << {
-}
+task(createArchive)
 
 // upload anchor for subprojects to upload their artifacts
 // to the local repo.
-task(mainUpload) << {
-}
+task(mainUpload)
 
 // repository creation task
 task createRepository(type: Zip, dependsOn: mainUpload) {
@@ -127,14 +136,12 @@
 }
 
 // anchor for prepare repo. This is post unzip + sourceProp.
-task(prepareRepo) << {
-}
+task(prepareRepo)
 
 // lint every library
-task(lint) << {
-}
+task(lint)
 
-task(createXml) << {
+task(createXml).doLast({
     def repoArchive = createRepository.archivePath
     def repoArchiveName = createRepository.archiveName
     def size = repoArchive.length()
@@ -161,11 +168,11 @@
 </sdk:sdk-addon>"
 
     Files.write(xml, new File(project.ext.distDir, 'repo-extras.xml'), Charsets.UTF_8)
-}
+})
 createArchive.dependsOn createXml
 createXml.dependsOn createRepository
 
-task(createSourceProp) << {
+task(createSourceProp).doLast({
     def sourceProp =
 "Extra.VendorDisplay=Android\n\
 Extra.Path=m2repository\n\
@@ -177,7 +184,7 @@
 Extra.VendorId=android"
 
     Files.write(sourceProp, new File(project.ext.supportRepoOut, 'source.properties'), Charsets.UTF_8)
-}
+})
 createSourceProp.dependsOn unzipRepo
 prepareRepo.dependsOn createSourceProp
 
@@ -240,6 +247,24 @@
     exclude '**/BuildConfig.java'
 }
 
+JDiffTask createApiDiffsTask(String taskName, File oldApiXml, File newApiXml, File outDir,
+                             Configuration jdiff, Task... dependencies) {
+    return tasks.create(name: taskName, type: JDiffTask.class) {
+        dependsOn jdiff
+        dependsOn dependencies
+
+        docletpath = jdiff.resolve()
+
+        oldApiXmlFile oldApiXml
+        newApiXmlFile newApiXml
+        destinationDir = outDir
+
+        // This prefix is based on the assumption that the output diffs will
+        // ultimately land in frameworks/base/docs/html/sdk/support_api_diff/.
+        newJavadocPrefix = "../reference/"
+    }
+}
+
 // Generates API files.
 task generateApi(type: DoclavaTask, dependsOn: configurations.doclava) {
     docletpath = configurations.doclava.resolve()
@@ -303,24 +328,138 @@
     checkApiWarnings = [23, 24]
     checkApiHidden = (2..6) + (19..22) + (25..30)
 
-    def lastReleasedApiFile = null
-    def apiDir = new File(project.rootDir, 'api')
-    apiDir.eachFileMatch FileType.FILES, ~/(\d+\.){3}txt/, { File apiFile ->
-        if (lastReleasedApiFile == null || apiFile.name > lastReleasedApiFile.name) {
-            lastReleasedApiFile = apiFile;
-        }
-    }
-
     newApiFile = new File(project.docsDir, 'release/current.txt')
-    oldApiFile = lastReleasedApiFile
+    oldApiFile = getReleasedApiFile()
     newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
     oldRemovedApiFile = new File(project.rootDir, 'api/removed.txt')
 }
 checkApi.dependsOn checkApiStable
 
+/**
+ * Converts the <code>toApi</code>.txt file (or current.txt if not explicitly
+ * defined using -PtoAPi=<file>) to XML format for use by JDiff.
+ */
+task newApiXml(type: ApiXmlConversionTask, dependsOn: configurations.doclava) {
+    classpath configurations.doclava.resolve()
+
+    if (project.hasProperty("toApi")) {
+        // Use an explicit API file.
+        inputApiFile = new File(project.rootDir, "api/${toApi}.txt")
+    } else {
+        // Use the current API file (e.g. current.txt).
+        inputApiFile = generateApi.apiFile
+        dependsOn generateApi
+    }
+
+    int lastDot = inputApiFile.name.lastIndexOf('.')
+    outputApiXmlFile = new File(project.docsDir,
+            "release/" + inputApiFile.name.substring(0, lastDot) + ".xml")
+}
+
+/**
+ * Converts the <code>fromApi</code>.txt file (or the most recently released
+ * X.Y.Z.txt if not explicitly defined using -PfromAPi=<file>) to XML format
+ * for use by JDiff.
+ */
+task oldApiXml(type: ApiXmlConversionTask, dependsOn: configurations.doclava) {
+    classpath configurations.doclava.resolve()
+
+    if (project.hasProperty("fromApi")) {
+        // Use an explicit API file.
+        inputApiFile = new File(project.rootDir, "api/${fromApi}.txt")
+    } else if (project.hasProperty("toApi") && toApi.matches(~/(\d+\.){2}\d+/)) {
+        // If toApi matches released API (X.Y.Z) format, use the most recently
+        // released API file prior to toApi.
+        inputApiFile = getReleasedApiFile(toApi)
+    } else {
+        // Use the most recently released API file.
+        inputApiFile = getReleasedApiFile();
+    }
+
+    int lastDot = inputApiFile.name.lastIndexOf('.')
+    outputApiXmlFile = new File(project.docsDir,
+            "release/" + inputApiFile.name.substring(0, lastDot) + ".xml")
+}
+
+/**
+ * Generates API diffs.
+ * <p>
+ * By default, diffs are generated for the delta between current.txt and the
+ * next most recent X.Y.Z.txt API file. Behavior may be changed by specifying
+ * one or both of -PtoApi and -PfromApi.
+ * <p>
+ * If both fromApi and toApi are specified, diffs will be generated for
+ * fromApi -> toApi. For example, 25.0.0 -> 26.0.0 diffs could be generated by
+ * using:
+ * <br><code>
+ *   ./gradlew generateDiffs -PfromApi=25.0.0 -PtoApi=26.0.0
+ * </code>
+ * <p>
+ * If only toApi is specified, it MUST be specified as X.Y.Z and diffs will be
+ * generated for (release before toApi) -> toApi. For example, 24.2.0 -> 25.0.0
+ * diffs could be generated by using:
+ * <br><code>
+ *   ./gradlew generateDiffs -PtoApi=25.0.0
+ * </code>
+ * <p>
+ * If only fromApi is specified, diffs will be generated for fromApi -> current.
+ * For example, lastApiReview -> current diffs could be generated by using:
+ * <br><code>
+ *   ./gradlew generateDiffs -PfromApi=lastApiReview
+ * </code>
+ * <p>
+ */
+task generateDiffs(type: JDiffTask, dependsOn: [configurations.jdiff, configurations.doclava,
+                                                oldApiXml, newApiXml, generateDocs]) {
+    // Base classpath is Android SDK, sub-projects add their own.
+    classpath = project.ext.androidJar
+
+    // JDiff properties.
+    oldApiXmlFile = oldApiXml.outputApiXmlFile
+    newApiXmlFile = newApiXml.outputApiXmlFile
+    newJavadocPrefix = "../../../../reference/"
+
+    String newApi = newApiXmlFile.name
+    int lastDot = newApi.lastIndexOf('.')
+    newApi = newApi.substring(0, lastDot)
+
+    // Javadoc properties.
+    docletpath = configurations.jdiff.resolve()
+    destinationDir = new File(project.docsDir, "online/sdk/support_api_diff/$newApi")
+    title = "Support&nbsp;Library&nbsp;API&nbsp;Differences&nbsp;Report"
+
+    exclude '**/BuildConfig.java'
+    exclude '**/R.java'
+}
+
+/**
+ * Returns the most recently released API, optionally restricting to APIs
+ * before <code>beforeApi</code>.
+ *
+ * @param beforeApi the API to find an API file before, ex. 25.0.0
+ * @return the most recently released API file
+ */
+File getReleasedApiFile(String beforeApi = null) {
+    String beforeApiFileName = beforeApi != null ? beforeApi + ".txt" : null
+    File lastReleasedApiFile = null
+    File apiDir = new File(project.rootDir, 'api')
+
+    apiDir.eachFileMatch FileType.FILES, ~/(\d+\.){3}txt/, { File apiFile ->
+        // Is the current API file newer than the last one we saw?
+        if (lastReleasedApiFile == null || apiFile.name > lastReleasedApiFile.name) {
+            // Is the current API file older than the "before" API?
+            if (beforeApiFileName == null || apiFile.name < beforeApiFileName) {
+                lastReleasedApiFile = apiFile
+            }
+        }
+    }
+
+    return lastReleasedApiFile
+}
+
 subprojects {
     // Only modify Android projects.
-    if (project.name.equals('doclava')) return;
+    if (project.name.equals('doclava') || project.name.equals('jdiff')) return;
 
     // Current SDK is set in studioCompat.gradle.
     project.ext.currentSdk = gradle.ext.currentSdk
@@ -348,6 +487,42 @@
             // debugger.
             project.android.buildTypes.debug.testCoverageEnabled = !hasProperty('android.injected.invoked.from.ide')
 
+            // Copy the class files in a jar to be later used to generate code coverage report
+            project.android.testVariants.all { v ->
+                // check if the variant has any source files
+                // and test coverage is enabled
+                if (v.buildType.testCoverageEnabled
+                        && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
+                    def jarifyTask = project.tasks.create(
+                            name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
+                            type: Jar) {
+                        from v.testedVariant.javaCompile.destinationDir
+                        exclude "**/R.class"
+                        exclude "**/R\$*.class"
+                        destinationDir file(project.distDir)
+                        archiveName "${project.archivesBaseName}-${v.baseName}-allclasses.jar"
+                    }
+                    def jacocoAntConfig =
+                            project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
+                    def jacocoAntArtifacts = jacocoAntConfig.resolvedConfiguration.resolvedArtifacts
+                    def version = jacocoAntArtifacts.find { "org.jacoco.ant".equals(it.name) }
+                            .moduleVersion.id.version
+                    def collectJacocoAntPackages = project.tasks.create(
+                            name: "collectJacocoAntPackages",
+                            type: Jar) {
+                        from (jacocoAntArtifacts.collect { zipTree(it.getFile()) }) {
+                            // exclude all the signatures the jar might have
+                            exclude "META-INF/*.SF"
+                            exclude "META-INF/*.DSA"
+                            exclude "META-INF/*.RSA"
+                        }
+                        destinationDir file(project.distDir)
+                        archiveName "jacocoant-" + version  + ".jar"
+                    }
+                    v.assemble.dependsOn jarifyTask, collectJacocoAntPackages
+                }
+            }
+
             // Enforce NewApi lint check as fatal.
             project.android.lintOptions.check 'NewApi'
             project.android.lintOptions.fatal 'NewApi'
@@ -400,7 +575,8 @@
                 return new File(artifactDir, version)
             }
 
-            task generateSourceProps(dependsOn: createRepository) << {
+            task generateSourceProps(dependsOn: createRepository)
+            generateSourceProps.doLast({
                 def content = "Maven.GroupId=$deployer.pom.groupId\n" +
                         "Maven.ArtifactId=$deployer.pom.artifactId\n" +
                         "Maven.Version=$deployer.pom.version\n" +
@@ -415,7 +591,7 @@
                         }.grep()) +
                         "\n"
                 Files.write(content, new File(versionDir(), 'source.properties'), Charsets.UTF_8)
-            }
+            })
 
             task createSeparateZip(type: Zip, dependsOn: generateSourceProps)  {
                 into archivesBaseName
@@ -485,18 +661,11 @@
                 if (v.name == 'release') {
                     registerForDocsTask(rootProject.generateDocs, p, v)
                     registerForDocsTask(rootProject.generateApi, p, v)
+                    registerForDocsTask(rootProject.generateDiffs, p, v)
                 }
             }
         }
     }
-
-    // Update the version meta-data in each Manifest
-    project.afterEvaluate { p ->
-        if (p.hasProperty('android')) {
-            p.android.defaultConfig.manifestPlaceholders =
-                    ["support-version": rootProject.ext.supportVersion]
-        }
-    }
 }
 
 project.gradle.buildFinished { buildResult ->
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
new file mode 100644
index 0000000..ae9582a
--- /dev/null
+++ b/buildSrc/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'groovy'
+
+apply from: "dependencies.gradle"
+
+repositories {
+    maven { url '../../../prebuilts/gradle-plugin' }
+    maven { url '../../../prebuilts/tools/common/m2/repository' }
+    maven { url '../../../prebuilts/tools/common/m2/internal' }
+    maven { url '../../../prebuilts/maven_repo/android' }
+}
+dependencies {
+    compile libs.gradle
+}
diff --git a/buildSrc/dependencies.gradle b/buildSrc/dependencies.gradle
new file mode 100644
index 0000000..ba08b5f
--- /dev/null
+++ b/buildSrc/dependencies.gradle
@@ -0,0 +1,20 @@
+// Add ext.libs for library versions
+def libs = [:]
+
+// Testing dependencies
+libs.mockito_core = 'org.mockito:mockito-core:1.9.5'
+libs.dexmaker = 'com.google.dexmaker:dexmaker:1.2'
+libs.dexmaker_mockito = 'com.google.dexmaker:dexmaker-mockito:1.2'
+libs.junit = 'junit:junit:4.12'
+libs.test_runner = 'com.android.support.test:runner:0.6-alpha'
+libs.espresso_core = 'com.android.support.test.espresso:espresso-core:2.3-alpha'
+libs.espresso_contrib = 'com.android.support.test.espresso:espresso-contrib:2.3-alpha'
+
+// Keep gradle plugin version in sync with ub_supportlib-master manifest.
+libs.gradle = 'com.android.tools.build:gradle:2.2.4'
+
+// Other dependencies
+libs.xml_parser_apis = 'xerces:xmlParserAPIs:2.6.2'
+libs.xerces_impl = 'xerces:xercesImpl:2.6.2'
+
+rootProject.ext['libs'] = libs
diff --git a/media-compat/tests/src/android/support/v4/media/session/TestActivity.java b/buildSrc/src/main/groovy/android/support/SupportLibraryExtension.groovy
similarity index 70%
copy from media-compat/tests/src/android/support/v4/media/session/TestActivity.java
copy to buildSrc/src/main/groovy/android/support/SupportLibraryExtension.groovy
index dd56467..b3b5783 100644
--- a/media-compat/tests/src/android/support/v4/media/session/TestActivity.java
+++ b/buildSrc/src/main/groovy/android/support/SupportLibraryExtension.groovy
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -14,9 +14,13 @@
  * limitations under the License.
  */
 
-package android.support.v4.media.session;
+package android.support;
 
-import android.app.Activity;
-
-public class TestActivity extends Activity {
+/**
+ * Extension for {@link SupportLibraryPlugin}.
+ */
+class SupportLibraryExtension {
+    String name;
+    String description;
+    String inceptionYear;
 }
diff --git a/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy b/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
new file mode 100644
index 0000000..333a9f4
--- /dev/null
+++ b/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support
+
+import com.android.build.gradle.LibraryExtension
+import com.android.build.gradle.api.AndroidSourceSet
+import com.android.build.gradle.api.LibraryVariant
+import com.android.builder.core.BuilderConstants
+import com.google.common.collect.ImmutableMap
+import org.gradle.api.Action
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.maven.MavenDeployer
+import org.gradle.api.tasks.Upload
+import org.gradle.api.tasks.bundling.Jar
+
+/**
+ * Support library specific com.android.library plugin that sets common configurations needed for
+ * support library modules.
+ */
+class SupportLibraryPlugin implements Plugin<Project> {
+    private static final String INSTRUMENTATION_RUNNER =
+            "android.support.test.runner.AndroidJUnitRunner";
+
+    @Override
+    public void apply(Project project) {
+        SupportLibraryExtension supportLibraryExtension =
+                project.getExtensions().create("supportLibrary", SupportLibraryExtension);
+
+        project.apply(ImmutableMap.of("plugin", "com.android.library"));
+        LibraryExtension library =
+                project.getExtensions().findByType(LibraryExtension.class);
+
+        library.setCompileSdkVersion(project.ext.currentSdk)
+
+        // Main sourceSet related options
+        AndroidSourceSet mainSet = library.getSourceSets().findByName("main");
+        mainSet.getManifest().srcFile("AndroidManifest.xml");
+
+        // Update the version meta-data in each Manifest
+        library.getDefaultConfig().addManifestPlaceholders(
+                ["support-version": project.rootProject.ext.supportVersion])
+
+        // Set test related options
+        library.getDefaultConfig().setTestInstrumentationRunner(INSTRUMENTATION_RUNNER);
+
+        library.sourceSets.androidTest {
+            root "tests"
+            java.srcDir "tests/src"
+            res.srcDir "tests/res"
+            manifest.srcFile "tests/AndroidManifest.xml"
+        }
+
+        // Set compile options
+        library.getCompileOptions().setSourceCompatibility(JavaVersion.VERSION_1_7);
+        library.getCompileOptions().setTargetCompatibility(JavaVersion.VERSION_1_7);
+
+        // Create sources jar for release builds
+        library.getLibraryVariants().all(new Action<LibraryVariant>() {
+            @Override
+            public void execute(LibraryVariant libraryVariant) {
+                if (!libraryVariant.getBuildType().getName().equals(BuilderConstants.RELEASE)) {
+                    return; // Skip non-release builds.
+                }
+
+                Jar sourceJar = project.getTasks().create("sourceJarRelease", Jar.class);
+                sourceJar.setClassifier("sources");
+                sourceJar.from(library.getSourceSets().findByName("main").getJava().getSrcDirs());
+                project.getArtifacts().add("archives", sourceJar);
+            }
+        });
+
+        // Set uploadArchives options
+        Upload uploadTask = (Upload) project.getTasks().getByName("uploadArchives");
+        project.afterEvaluate {
+            uploadTask.repositories {
+                mavenDeployer {
+                    repository(url: project.uri(project.rootProject.ext.supportRepoOut))
+                }
+            };
+            uploadTask.getRepositories().withType(MavenDeployer.class, new Action<MavenDeployer>() {
+                @Override
+                public void execute(MavenDeployer mavenDeployer) {
+                    mavenDeployer.getPom().project {
+                        name supportLibraryExtension.getName()
+                        description supportLibraryExtension.getDescription()
+                        url 'http://developer.android.com/tools/extras/support-library.html'
+                        inceptionYear supportLibraryExtension.getInceptionYear()
+
+                        licenses {
+                            license {
+                                name 'The Apache Software License, Version 2.0'
+                                url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+                                distribution 'repo'
+                            }
+                        }
+
+                        scm {
+                            url "http://source.android.com"
+                            connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
+                        }
+                        developers {
+                            developer {
+                                name 'The Android Open Source Project'
+                            }
+                        }
+                    }
+                }
+            });
+        }
+    }
+}
diff --git a/buildSrc/src/main/groovy/android/support/checkapi/ApiXmlConversionTask.groovy b/buildSrc/src/main/groovy/android/support/checkapi/ApiXmlConversionTask.groovy
new file mode 100644
index 0000000..61e84d4
--- /dev/null
+++ b/buildSrc/src/main/groovy/android/support/checkapi/ApiXmlConversionTask.groovy
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.checkapi
+
+import org.gradle.api.tasks.JavaExec
+import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.ParallelizableTask
+import org.gradle.api.tasks.OutputFile
+
+@ParallelizableTask
+public class ApiXmlConversionTask extends JavaExec {
+
+    @InputFile
+    File inputApiFile
+
+    @OutputFile
+    File outputApiXmlFile
+
+    public ApiXmlConversionTask() {
+        maxHeapSize = "1024m"
+
+        // Despite this tool living in ApiCheck, its purpose more fits with doclava's "purposes",
+        // generation of api files in this case. Thus, I am putting this in the doclava package.
+        setMain('com.google.doclava.apicheck.ApiCheck')
+    }
+
+    /**
+     * "Configures" this ApiXmlConversionTask with parameters that might not be at their final
+     * values until this task is run.
+     */
+    private configureApiXmlConversionTask() {
+        setArgs([
+                '-convert2xml',
+                getInputApiFile().absolutePath,
+                getOutputApiXmlFile().absolutePath
+        ])
+    }
+
+    @Override
+    public void exec() {
+        configureApiXmlConversionTask()
+        super.exec()
+    }
+}
diff --git a/buildSrc/src/main/groovy/android/support/checkapi/CheckApiTask.groovy b/buildSrc/src/main/groovy/android/support/checkapi/CheckApiTask.groovy
index 3578958..4517105 100644
--- a/buildSrc/src/main/groovy/android/support/checkapi/CheckApiTask.groovy
+++ b/buildSrc/src/main/groovy/android/support/checkapi/CheckApiTask.groovy
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package android.support.checkapi;
 
 import org.gradle.api.DefaultTask
diff --git a/buildSrc/src/main/groovy/android/support/checkapi/UpdateApiTask.groovy b/buildSrc/src/main/groovy/android/support/checkapi/UpdateApiTask.groovy
index 1170b0b..c1b7563 100644
--- a/buildSrc/src/main/groovy/android/support/checkapi/UpdateApiTask.groovy
+++ b/buildSrc/src/main/groovy/android/support/checkapi/UpdateApiTask.groovy
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package android.support.checkapi;
 
 import org.gradle.api.DefaultTask
diff --git a/buildSrc/src/main/groovy/android/support/doclava/DoclavaTask.groovy b/buildSrc/src/main/groovy/android/support/doclava/DoclavaTask.groovy
index 53c0797..b13bc64 100644
--- a/buildSrc/src/main/groovy/android/support/doclava/DoclavaTask.groovy
+++ b/buildSrc/src/main/groovy/android/support/doclava/DoclavaTask.groovy
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package android.support.doclava;
 
 import org.gradle.api.InvalidUserDataException
diff --git a/buildSrc/src/main/groovy/android/support/jdiff/JDiffTask.groovy b/buildSrc/src/main/groovy/android/support/jdiff/JDiffTask.groovy
new file mode 100644
index 0000000..7bb9435
--- /dev/null
+++ b/buildSrc/src/main/groovy/android/support/jdiff/JDiffTask.groovy
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.jdiff;
+
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.javadoc.Javadoc
+import org.gradle.api.tasks.Optional
+import org.gradle.api.tasks.ParallelizableTask
+
+@ParallelizableTask
+public class JDiffTask extends Javadoc {
+
+    @InputFiles
+    Collection<File> docletpath
+
+    @InputFile
+    File oldApiXmlFile
+
+    @InputFile
+    File newApiXmlFile
+
+    /**
+     * Relative path to the Javadoc corresponding to the old API, relative to
+     * "${destinationDir}/changes". Should end with the directory separator (usually '/').
+     */
+    @Input
+    @Optional
+    String oldJavadocPrefix
+
+    /**
+     * Relative path to the Javadoc corresponding to the new API, relative to
+     * "${destinationDir}/changes". Should end with the directory separator (usually '/').
+     */
+    @Input
+    String newJavadocPrefix
+
+    // HTML diff files will be placed in destinationDir, which is defined by the superclass.
+
+    @Input
+    boolean stats = true
+
+    public JDiffTask() {
+        failOnError = true
+        options.doclet = "jdiff.JDiff"
+        options.encoding("UTF-8")
+        maxMemory = "1280m"
+    }
+
+    /**
+     * Sets the doclet path which has the {@code com.gogole.doclava.Doclava} class.
+     * <p>
+     * This option will override any doclet path set in this instance's
+     * {@link #getOptions() JavadocOptions}.
+     *
+     * @see MinimalJavadocOptions#setDocletpath(java.util.List)
+     */
+    public void setDocletpath(Collection<File> docletpath) {
+        this.docletpath = docletpath
+
+        // Go ahead and keep the docletpath in our JavadocOptions object in sync.
+        options.docletpath = docletpath as List
+    }
+
+    /**
+     * "Configures" this JDiffTask with parameters that might not be at their final values
+     * until this task is run.
+     */
+    private void configureJDiffTask() {
+        options.docletpath = getDocletpath() as List
+
+        if (getStats()) {
+            options.addStringOption('stats')
+        }
+
+        File oldApiXmlFile = getOldApiXmlFile()
+        File newApiXmlFile = getNewApiXmlFile()
+
+        File oldApiXmlFileDir = oldApiXmlFile.parentFile
+        File newApiXmlFileDir = newApiXmlFile.parentFile
+
+        if (oldApiXmlFileDir) {
+            options.addStringOption('oldapidir', oldApiXmlFileDir.absolutePath)
+        }
+        // For whatever reason, jdiff appends .xml to the file name on its own.
+        // Strip the .xml off the end of the file name
+        options.addStringOption('oldapi',
+                oldApiXmlFile.name.substring(0, oldApiXmlFile.name.length() - 4))
+        if (newApiXmlFileDir) {
+            options.addStringOption('newapidir', newApiXmlFileDir.absolutePath)
+        }
+        options.addStringOption('newapi',
+                newApiXmlFile.name.substring(0, newApiXmlFile.name.length() - 4))
+
+        String oldJavadocPrefix = getOldJavadocPrefix()
+        String newJavadocPrefix = getNewJavadocPrefix()
+
+        if (oldJavadocPrefix) {
+            options.addStringOption('javadocold', oldJavadocPrefix)
+        }
+        if (newJavadocPrefix) {
+            options.addStringOption('javadocnew', newJavadocPrefix)
+        }
+    }
+
+    @Override
+    public void generate() {
+        configureJDiffTask();
+        super.generate();
+    }
+}
diff --git a/compat/Android.mk b/compat/Android.mk
index 97916ae..9d8d258 100644
--- a/compat/Android.mk
+++ b/compat/Android.mk
@@ -42,10 +42,10 @@
     $(call all-java-files-under,api22) \
     $(call all-java-files-under,api23) \
     $(call all-java-files-under,api24) \
+    $(call all-java-files-under,api26) \
     $(call all-java-files-under,java) \
     $(call all-Iaidl-files-under,java)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-annotations
 LOCAL_JAR_EXCLUDE_FILES := none
diff --git a/compat/AndroidManifest-make.xml b/compat/AndroidManifest-make.xml
deleted file mode 100644
index b2bd5bb..0000000
--- a/compat/AndroidManifest-make.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.support.compat">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.compat"/>
-    <application />
-</manifest>
diff --git a/compat/AndroidManifest.xml b/compat/AndroidManifest.xml
index 55ddcff..6a9f6a6 100644
--- a/compat/AndroidManifest.xml
+++ b/compat/AndroidManifest.xml
@@ -16,7 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.compat">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.compat"/>
+    <uses-sdk android:minSdkVersion="14" tools:overrideLibrary="android.support.compat"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/compat/api20/android/support/v4/app/NotificationCompatApi20.java b/compat/api20/android/support/v4/app/NotificationCompatApi20.java
index 57c272e..457ad0b 100644
--- a/compat/api20/android/support/v4/app/NotificationCompatApi20.java
+++ b/compat/api20/android/support/v4/app/NotificationCompatApi20.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.RemoteInput;
@@ -30,7 +29,6 @@
 import java.util.ArrayList;
 
 @RequiresApi(20)
-@TargetApi(20)
 class NotificationCompatApi20 {
     public static class Builder implements NotificationBuilderWithBuilderAccessor,
             NotificationBuilderWithActions {
@@ -148,7 +146,7 @@
         boolean allowGeneratedReplies = action.getExtras().getBoolean(
                 NotificationCompatJellybean.EXTRA_ALLOW_GENERATED_REPLIES);
         return actionFactory.build(action.icon, action.title, action.actionIntent,
-                action.getExtras(), remoteInputs, allowGeneratedReplies);
+                action.getExtras(), remoteInputs, null, allowGeneratedReplies);
     }
 
     private static Notification.Action getActionFromActionCompat(
diff --git a/compat/api20/android/support/v4/app/RemoteInputCompatApi20.java b/compat/api20/android/support/v4/app/RemoteInputCompatApi20.java
index 2949cfd..19c693c 100644
--- a/compat/api20/android/support/v4/app/RemoteInputCompatApi20.java
+++ b/compat/api20/android/support/v4/app/RemoteInputCompatApi20.java
@@ -17,14 +17,22 @@
 package android.support.v4.app;
 
 import android.app.RemoteInput;
+import android.content.ClipData;
+import android.content.ClipDescription;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
+
+import java.util.HashMap;
+import java.util.Map;
 
 @RequiresApi(20)
-@TargetApi(20)
 class RemoteInputCompatApi20 {
+    /** Extra added to a clip data intent object to hold the data results bundle. */
+    private static final String EXTRA_DATA_TYPE_RESULTS_DATA =
+            "android.remoteinput.dataTypeResultsData";
+
     static RemoteInputCompatBase.RemoteInput[] toCompat(RemoteInput[] srcArray,
             RemoteInputCompatBase.RemoteInput.Factory factory) {
         if (srcArray == null) {
@@ -34,7 +42,7 @@
         for (int i = 0; i < srcArray.length; i++) {
             RemoteInput src = srcArray[i];
             result[i] = factory.build(src.getResultKey(), src.getLabel(), src.getChoices(),
-                    src.getAllowFreeFormInput(), src.getExtras());
+                    src.getAllowFreeFormInput(), src.getExtras(), null);
         }
         return result;
     }
@@ -60,8 +68,100 @@
         return RemoteInput.getResultsFromIntent(intent);
     }
 
+    static Map<String, Uri> getDataResultsFromIntent(Intent intent, String remoteInputResultKey) {
+        Intent clipDataIntent = getClipDataIntentFromIntent(intent);
+        if (clipDataIntent == null) {
+            return null;
+        }
+        Map<String, Uri> results = new HashMap<>();
+        Bundle extras = clipDataIntent.getExtras();
+        for (String key : extras.keySet()) {
+            if (key.startsWith(EXTRA_DATA_TYPE_RESULTS_DATA)) {
+                String mimeType = key.substring(EXTRA_DATA_TYPE_RESULTS_DATA.length());
+                if (mimeType == null || mimeType.isEmpty()) {
+                    continue;
+                }
+                Bundle bundle = clipDataIntent.getBundleExtra(key);
+                String uriStr = bundle.getString(remoteInputResultKey);
+                if (uriStr == null || uriStr.isEmpty()) {
+                    continue;
+                }
+                results.put(mimeType, Uri.parse(uriStr));
+            }
+        }
+        return results.isEmpty() ? null : results;
+    }
+
     static void addResultsToIntent(RemoteInputCompatBase.RemoteInput[] remoteInputs,
             Intent intent, Bundle results) {
-        RemoteInput.addResultsToIntent(fromCompat(remoteInputs), intent, results);
+        // Implementations of RemoteInput#addResultsToIntent prior to SDK 26 don't actually add
+        // results, they wipe out old results and insert the new one. Work around that by preserving
+        // old results.
+        Bundle existingTextResults = getResultsFromIntent(intent);
+        if (existingTextResults == null) {
+            existingTextResults = results;
+        } else {
+            existingTextResults.putAll(results);
+        }
+        for (RemoteInputCompatBase.RemoteInput input : remoteInputs) {
+            // Data results are also wiped out. So grab them and add them back in.
+            Map<String, Uri> existingDataResults =
+                    getDataResultsFromIntent(intent, input.getResultKey());
+            RemoteInputCompatBase.RemoteInput[] arr = new RemoteInputCompatBase.RemoteInput[1];
+            arr[0] = input;
+            RemoteInput.addResultsToIntent(fromCompat(arr), intent, existingTextResults);
+            if (existingDataResults != null) {
+                addDataResultToIntent(input, intent, existingDataResults);
+            }
+        }
+    }
+
+    /**
+     * Same as {@link #addResultsToIntent} but for setting data results.
+     * @param remoteInput The remote input for which results are being provided
+     * @param intent The intent to add remote input results to. The {@link ClipData}
+     *               field of the intent will be modified to contain the results.
+     * @param results A map of mime type to the Uri result for that mime type.
+     */
+    public static void addDataResultToIntent(RemoteInputCompatBase.RemoteInput remoteInput,
+            Intent intent, Map<String, Uri> results) {
+        Intent clipDataIntent = getClipDataIntentFromIntent(intent);
+        if (clipDataIntent == null) {
+            clipDataIntent = new Intent();  // First time we've added a result.
+        }
+        for (Map.Entry<String, Uri> entry : results.entrySet()) {
+            String mimeType = entry.getKey();
+            Uri uri = entry.getValue();
+            if (mimeType == null) {
+                continue;
+            }
+            Bundle resultsBundle =
+                    clipDataIntent.getBundleExtra(getExtraResultsKeyForData(mimeType));
+            if (resultsBundle == null) {
+                resultsBundle = new Bundle();
+            }
+            resultsBundle.putString(remoteInput.getResultKey(), uri.toString());
+            clipDataIntent.putExtra(getExtraResultsKeyForData(mimeType), resultsBundle);
+        }
+        intent.setClipData(ClipData.newIntent(RemoteInput.RESULTS_CLIP_LABEL, clipDataIntent));
+    }
+
+    private static String getExtraResultsKeyForData(String mimeType) {
+        return EXTRA_DATA_TYPE_RESULTS_DATA + mimeType;
+    }
+
+    private static Intent getClipDataIntentFromIntent(Intent intent) {
+        ClipData clipData = intent.getClipData();
+        if (clipData == null) {
+            return null;
+        }
+        ClipDescription clipDescription = clipData.getDescription();
+        if (!clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_INTENT)) {
+            return null;
+        }
+        if (!clipDescription.getLabel().equals(RemoteInput.RESULTS_CLIP_LABEL)) {
+            return null;
+        }
+        return clipData.getItemAt(0).getIntent();
     }
 }
diff --git a/compat/api20/android/support/v4/view/WindowInsetsCompatApi20.java b/compat/api20/android/support/v4/view/WindowInsetsCompatApi20.java
index 617920c..6d5a547 100644
--- a/compat/api20/android/support/v4/view/WindowInsetsCompatApi20.java
+++ b/compat/api20/android/support/v4/view/WindowInsetsCompatApi20.java
@@ -17,11 +17,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.WindowInsets;
 
 @RequiresApi(20)
-@TargetApi(20)
 class WindowInsetsCompatApi20 {
     public static Object consumeSystemWindowInsets(Object insets) {
         return ((WindowInsets) insets).consumeSystemWindowInsets();
diff --git a/compat/api21/android/support/v4/app/ActivityCompatApi21.java b/compat/api21/android/support/v4/app/ActivityCompatApi21.java
index ddc95fd..7fdeb14 100644
--- a/compat/api21/android/support/v4/app/ActivityCompatApi21.java
+++ b/compat/api21/android/support/v4/app/ActivityCompatApi21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.SharedElementCallback;
 import android.content.Context;
@@ -30,7 +29,6 @@
 import java.util.Map;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ActivityCompatApi21 {
 
     public static void finishAfterTransition(Activity activity) {
diff --git a/compat/api21/android/support/v4/app/ActivityOptionsCompat21.java b/compat/api21/android/support/v4/app/ActivityOptionsCompat21.java
index 16287d2..8f2b2e8 100644
--- a/compat/api21/android/support/v4/app/ActivityOptionsCompat21.java
+++ b/compat/api21/android/support/v4/app/ActivityOptionsCompat21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.ActivityOptions;
 import android.content.Context;
@@ -27,7 +26,6 @@
 import android.view.View;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ActivityOptionsCompat21 {
 
     private final ActivityOptions mActivityOptions;
diff --git a/transition/api23/android/support/transition/TransitionApi23.java b/compat/api21/android/support/v4/app/AlarmManagerCompatApi21.java
similarity index 61%
copy from transition/api23/android/support/transition/TransitionApi23.java
copy to compat/api21/android/support/v4/app/AlarmManagerCompatApi21.java
index 0df0ec5..4d8f1ab 100644
--- a/transition/api23/android/support/transition/TransitionApi23.java
+++ b/compat/api21/android/support/v4/app/AlarmManagerCompatApi21.java
@@ -14,19 +14,17 @@
  * limitations under the License.
  */
 
-package android.support.transition;
+package android.support.v4.app;
 
-import android.annotation.TargetApi;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
 import android.support.annotation.RequiresApi;
 
-@RequiresApi(23)
-@TargetApi(23)
-class TransitionApi23 extends TransitionKitKat {
-
-    @Override
-    public TransitionImpl removeTarget(int targetId) {
-        mTransition.removeTarget(targetId);
-        return this;
+@RequiresApi(21)
+class AlarmManagerCompatApi21 {
+    static void setAlarmClock(AlarmManager alarmManager, long triggerTime,
+            PendingIntent showIntent, PendingIntent operation) {
+        alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(triggerTime, showIntent),
+                operation);
     }
-
 }
diff --git a/compat/api21/android/support/v4/app/NotificationCompatApi21.java b/compat/api21/android/support/v4/app/NotificationCompatApi21.java
index feeb044..7cd32ae 100644
--- a/compat/api21/android/support/v4/app/NotificationCompatApi21.java
+++ b/compat/api21/android/support/v4/app/NotificationCompatApi21.java
@@ -23,13 +23,11 @@
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.RemoteViews;
 
 import java.util.ArrayList;
 
 @RequiresApi(21)
-@TargetApi(21)
 class NotificationCompatApi21 {
 
     public static final String CATEGORY_CALL = Notification.CATEGORY_CALL;
@@ -244,6 +242,7 @@
                 remoteInput.getLabel(),
                 remoteInput.getChoices(),
                 remoteInput.getAllowFreeFormInput(),
-                remoteInput.getExtras());
+                remoteInput.getExtras(),
+                null /* allowedDataTypes */);
     }
 }
diff --git a/compat/api21/android/support/v4/content/ContextCompatApi21.java b/compat/api21/android/support/v4/content/ContextCompatApi21.java
index 97a0b37..3a45915 100644
--- a/compat/api21/android/support/v4/content/ContextCompatApi21.java
+++ b/compat/api21/android/support/v4/content/ContextCompatApi21.java
@@ -19,12 +19,10 @@
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import java.io.File;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ContextCompatApi21 {
     public static Drawable getDrawable(Context context, int id) {
         return context.getDrawable(id);
diff --git a/compat/api21/android/support/v4/content/res/ResourcesCompatApi21.java b/compat/api21/android/support/v4/content/res/ResourcesCompatApi21.java
index f08dbe1..51c3edf 100644
--- a/compat/api21/android/support/v4/content/res/ResourcesCompatApi21.java
+++ b/compat/api21/android/support/v4/content/res/ResourcesCompatApi21.java
@@ -21,10 +21,8 @@
 import android.content.res.Resources.Theme;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ResourcesCompatApi21 {
     public static Drawable getDrawable(Resources res, int id, Theme theme)
             throws NotFoundException {
diff --git a/compat/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java b/compat/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java
index a5e8650..fa3796a 100644
--- a/compat/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java
+++ b/compat/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java
@@ -24,7 +24,6 @@
 import android.graphics.drawable.DrawableContainer;
 import android.graphics.drawable.InsetDrawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.AttributeSet;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -37,7 +36,6 @@
  */
 
 @RequiresApi(21)
-@TargetApi(21)
 class DrawableCompatLollipop {
 
     public static void setHotspot(Drawable drawable, float x, float y) {
diff --git a/compat/api21/android/support/v4/graphics/drawable/DrawableWrapperLollipop.java b/compat/api21/android/support/v4/graphics/drawable/DrawableWrapperLollipop.java
index 9458f7b..f3cd894 100644
--- a/compat/api21/android/support/v4/graphics/drawable/DrawableWrapperLollipop.java
+++ b/compat/api21/android/support/v4/graphics/drawable/DrawableWrapperLollipop.java
@@ -29,10 +29,8 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(21)
-@TargetApi(21)
 class DrawableWrapperLollipop extends DrawableWrapperKitKat {
 
     DrawableWrapperLollipop(Drawable drawable) {
diff --git a/compat/api21/android/support/v4/view/LayoutInflaterCompatLollipop.java b/compat/api21/android/support/v4/view/LayoutInflaterCompatLollipop.java
index 7fae8a8..ae34419 100644
--- a/compat/api21/android/support/v4/view/LayoutInflaterCompatLollipop.java
+++ b/compat/api21/android/support/v4/view/LayoutInflaterCompatLollipop.java
@@ -18,11 +18,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.LayoutInflater;
 
 @RequiresApi(21)
-@TargetApi(21)
 class LayoutInflaterCompatLollipop {
     static void setFactory(LayoutInflater inflater, LayoutInflaterFactory factory) {
         inflater.setFactory2(factory != null
diff --git a/compat/api21/android/support/v4/view/ViewCompatLollipop.java b/compat/api21/android/support/v4/view/ViewCompatLollipop.java
index 26c462a..9d21d06 100644
--- a/compat/api21/android/support/v4/view/ViewCompatLollipop.java
+++ b/compat/api21/android/support/v4/view/ViewCompatLollipop.java
@@ -22,13 +22,11 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.ViewParent;
 import android.view.WindowInsets;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ViewCompatLollipop {
 
     public interface OnApplyWindowInsetsListenerBridge {
diff --git a/compat/api21/android/support/v4/view/ViewGroupCompatLollipop.java b/compat/api21/android/support/v4/view/ViewGroupCompatLollipop.java
index 03430e6..4a14377 100644
--- a/compat/api21/android/support/v4/view/ViewGroupCompatLollipop.java
+++ b/compat/api21/android/support/v4/view/ViewGroupCompatLollipop.java
@@ -17,11 +17,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.ViewGroup;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ViewGroupCompatLollipop {
 
     public static void setTransitionGroup(ViewGroup group, boolean isTransitionGroup) {
diff --git a/compat/api21/android/support/v4/view/ViewParentCompatLollipop.java b/compat/api21/android/support/v4/view/ViewParentCompatLollipop.java
index 1e65a09..f64db1e 100644
--- a/compat/api21/android/support/v4/view/ViewParentCompatLollipop.java
+++ b/compat/api21/android/support/v4/view/ViewParentCompatLollipop.java
@@ -18,13 +18,11 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewParent;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ViewParentCompatLollipop {
     private static final String TAG = "ViewParentCompat";
 
diff --git a/compat/api21/android/support/v4/view/ViewPropertyAnimatorCompatLollipop.java b/compat/api21/android/support/v4/view/ViewPropertyAnimatorCompatLollipop.java
index 2b979a9..f51a53e 100644
--- a/compat/api21/android/support/v4/view/ViewPropertyAnimatorCompatLollipop.java
+++ b/compat/api21/android/support/v4/view/ViewPropertyAnimatorCompatLollipop.java
@@ -17,11 +17,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ViewPropertyAnimatorCompatLollipop {
 
     public static void translationZ(View view, float value) {
diff --git a/compat/api21/android/support/v4/view/WindowInsetsCompatApi21.java b/compat/api21/android/support/v4/view/WindowInsetsCompatApi21.java
index 5bbb802..e81dc48 100644
--- a/compat/api21/android/support/v4/view/WindowInsetsCompatApi21.java
+++ b/compat/api21/android/support/v4/view/WindowInsetsCompatApi21.java
@@ -18,11 +18,9 @@
 
 import android.graphics.Rect;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.WindowInsets;
 
 @RequiresApi(21)
-@TargetApi(21)
 class WindowInsetsCompatApi21 {
     public static Object consumeStableInsets(Object insets) {
         return ((WindowInsets) insets).consumeStableInsets();
diff --git a/compat/api21/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi21.java b/compat/api21/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi21.java
index e24b873..7bbdb25 100644
--- a/compat/api21/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi21.java
+++ b/compat/api21/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi21.java
@@ -17,7 +17,6 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(21)
-@TargetApi(21)
 class AccessibilityNodeInfoCompatApi21 {
     static List<Object> getActionList(Object info) {
         Object result = ((AccessibilityNodeInfo) info).getActionList();
diff --git a/compat/api21/android/support/v4/view/accessibility/AccessibilityWindowInfoCompatApi21.java b/compat/api21/android/support/v4/view/accessibility/AccessibilityWindowInfoCompatApi21.java
index 23fd7ca..23a9eb8 100644
--- a/compat/api21/android/support/v4/view/accessibility/AccessibilityWindowInfoCompatApi21.java
+++ b/compat/api21/android/support/v4/view/accessibility/AccessibilityWindowInfoCompatApi21.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Rect;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityWindowInfo;
 
 /**
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(21)
-@TargetApi(21)
 class AccessibilityWindowInfoCompatApi21 {
 
     public static Object obtain() {
diff --git a/compat/api21/android/support/v4/view/animation/PathInterpolatorCompatApi21.java b/compat/api21/android/support/v4/view/animation/PathInterpolatorCompatApi21.java
index 835e4e0..d4cdbb8 100644
--- a/compat/api21/android/support/v4/view/animation/PathInterpolatorCompatApi21.java
+++ b/compat/api21/android/support/v4/view/animation/PathInterpolatorCompatApi21.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Path;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
@@ -27,7 +26,6 @@
  */
 
 @RequiresApi(21)
-@TargetApi(21)
 class PathInterpolatorCompatApi21  {
 
     private PathInterpolatorCompatApi21() {
diff --git a/compat/api21/android/support/v4/widget/CompoundButtonCompatLollipop.java b/compat/api21/android/support/v4/widget/CompoundButtonCompatLollipop.java
index 42aa89a..1e50e72 100644
--- a/compat/api21/android/support/v4/widget/CompoundButtonCompatLollipop.java
+++ b/compat/api21/android/support/v4/widget/CompoundButtonCompatLollipop.java
@@ -19,11 +19,9 @@
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.CompoundButton;
 
 @RequiresApi(21)
-@TargetApi(21)
 class CompoundButtonCompatLollipop {
 
     static void setButtonTintList(CompoundButton button, ColorStateList tint) {
diff --git a/compat/api21/android/support/v4/widget/EdgeEffectCompatLollipop.java b/compat/api21/android/support/v4/widget/EdgeEffectCompatLollipop.java
index f12bc23..017a6b0 100644
--- a/compat/api21/android/support/v4/widget/EdgeEffectCompatLollipop.java
+++ b/compat/api21/android/support/v4/widget/EdgeEffectCompatLollipop.java
@@ -18,11 +18,9 @@
 package android.support.v4.widget;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.EdgeEffect;
 
 @RequiresApi(21)
-@TargetApi(21)
 class EdgeEffectCompatLollipop {
     public static boolean onPull(Object edgeEffect, float deltaDistance, float displacement) {
         ((EdgeEffect) edgeEffect).onPull(deltaDistance, displacement);
diff --git a/compat/api21/android/support/v4/widget/PopupWindowCompatApi21.java b/compat/api21/android/support/v4/widget/PopupWindowCompatApi21.java
index 393efa6..f231722 100644
--- a/compat/api21/android/support/v4/widget/PopupWindowCompatApi21.java
+++ b/compat/api21/android/support/v4/widget/PopupWindowCompatApi21.java
@@ -17,14 +17,12 @@
 package android.support.v4.widget;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.Log;
 import android.widget.PopupWindow;
 
 import java.lang.reflect.Field;
 
 @RequiresApi(21)
-@TargetApi(21)
 class PopupWindowCompatApi21 {
 
     private static final String TAG = "PopupWindowCompatApi21";
diff --git a/compat/api22/android/support/v4/app/ActivityCompatApi22.java b/compat/api22/android/support/v4/app/ActivityCompatApi22.java
index 1efef64..889c188 100644
--- a/compat/api22/android/support/v4/app/ActivityCompatApi22.java
+++ b/compat/api22/android/support/v4/app/ActivityCompatApi22.java
@@ -19,10 +19,8 @@
 import android.app.Activity;
 import android.net.Uri;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(22)
-@TargetApi(22)
 class ActivityCompatApi22 {
     public static Uri getReferrer(Activity activity) {
         return activity.getReferrer();
diff --git a/compat/api22/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi22.java b/compat/api22/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi22.java
index dd482d4..8480357 100644
--- a/compat/api22/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi22.java
+++ b/compat/api22/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi22.java
@@ -17,7 +17,6 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(22)
-@TargetApi(22)
 class AccessibilityNodeInfoCompatApi22 {
 
     public static Object getTraversalBefore(Object info) {
diff --git a/compat/api23/android/support/v4/app/ActivityCompatApi23.java b/compat/api23/android/support/v4/app/ActivityCompatApi23.java
index 9012f56..d63ca68 100644
--- a/compat/api23/android/support/v4/app/ActivityCompatApi23.java
+++ b/compat/api23/android/support/v4/app/ActivityCompatApi23.java
@@ -23,14 +23,12 @@
 import android.graphics.RectF;
 import android.os.Parcelable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 
 import java.util.List;
 import java.util.Map;
 
 @RequiresApi(23)
-@TargetApi(23)
 class ActivityCompatApi23 {
     public interface OnSharedElementsReadyListenerBridge {
         void onSharedElementsReady();
diff --git a/compat/api23/android/support/v4/app/ActivityOptionsCompat23.java b/compat/api23/android/support/v4/app/ActivityOptionsCompat23.java
index 81be941..08863a5 100644
--- a/compat/api23/android/support/v4/app/ActivityOptionsCompat23.java
+++ b/compat/api23/android/support/v4/app/ActivityOptionsCompat23.java
@@ -23,12 +23,10 @@
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.Pair;
 import android.view.View;
 
 @RequiresApi(23)
-@TargetApi(23)
 class ActivityOptionsCompat23 {
 
     private final ActivityOptions mActivityOptions;
diff --git a/compat/api23/android/support/v4/app/AlarmManagerCompatApi23.java b/compat/api23/android/support/v4/app/AlarmManagerCompatApi23.java
new file mode 100644
index 0000000..894cbd6
--- /dev/null
+++ b/compat/api23/android/support/v4/app/AlarmManagerCompatApi23.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.app;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.support.annotation.RequiresApi;
+
+@RequiresApi(23)
+class AlarmManagerCompatApi23 {
+    static void setAndAllowWhileIdle(AlarmManager alarmManager, int type,
+            long triggerAtMillis, PendingIntent operation) {
+        alarmManager.setAndAllowWhileIdle(type, triggerAtMillis, operation);
+    }
+
+    static void setExactAndAllowWhileIdle(AlarmManager alarmManager, int type,
+            long triggerAtMillis, PendingIntent operation) {
+        alarmManager.setExactAndAllowWhileIdle(type, triggerAtMillis, operation);
+    }
+}
diff --git a/compat/api23/android/support/v4/app/AppOpsManagerCompat23.java b/compat/api23/android/support/v4/app/AppOpsManagerCompat23.java
index 853fd5d..26448ee 100644
--- a/compat/api23/android/support/v4/app/AppOpsManagerCompat23.java
+++ b/compat/api23/android/support/v4/app/AppOpsManagerCompat23.java
@@ -19,14 +19,12 @@
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * AppOpsManager implementations for API 23.
  */
 
 @RequiresApi(23)
-@TargetApi(23)
 class AppOpsManagerCompat23 {
     public static String permissionToOp(String permission) {
         return AppOpsManager.permissionToOp(permission);
diff --git a/compat/api23/android/support/v4/app/NotificationCompatApi23.java b/compat/api23/android/support/v4/app/NotificationCompatApi23.java
index 5262ef3..2f8216c 100644
--- a/compat/api23/android/support/v4/app/NotificationCompatApi23.java
+++ b/compat/api23/android/support/v4/app/NotificationCompatApi23.java
@@ -18,10 +18,8 @@
 
 import android.app.Notification;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(23)
-@TargetApi(23)
 class NotificationCompatApi23 {
 
     public static final String CATEGORY_REMINDER = Notification.CATEGORY_REMINDER;
diff --git a/compat/api23/android/support/v4/content/ContextCompatApi23.java b/compat/api23/android/support/v4/content/ContextCompatApi23.java
index c22f5b6..4ee261c 100644
--- a/compat/api23/android/support/v4/content/ContextCompatApi23.java
+++ b/compat/api23/android/support/v4/content/ContextCompatApi23.java
@@ -19,10 +19,8 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(23)
-@TargetApi(23)
 class ContextCompatApi23 {
     public static ColorStateList getColorStateList(Context context, int id) {
         return context.getColorStateList(id);
diff --git a/compat/api23/android/support/v4/content/res/ResourcesCompatApi23.java b/compat/api23/android/support/v4/content/res/ResourcesCompatApi23.java
index eade1ef..4f34e7b 100644
--- a/compat/api23/android/support/v4/content/res/ResourcesCompatApi23.java
+++ b/compat/api23/android/support/v4/content/res/ResourcesCompatApi23.java
@@ -21,10 +21,8 @@
 import android.content.res.Resources.NotFoundException;
 import android.content.res.Resources.Theme;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(23)
-@TargetApi(23)
 class ResourcesCompatApi23 {
     public static int getColor(Resources res, int id, Theme theme) throws NotFoundException {
         return res.getColor(id, theme);
diff --git a/compat/api23/android/support/v4/graphics/drawable/DrawableCompatApi23.java b/compat/api23/android/support/v4/graphics/drawable/DrawableCompatApi23.java
index e454d41..9186689 100644
--- a/compat/api23/android/support/v4/graphics/drawable/DrawableCompatApi23.java
+++ b/compat/api23/android/support/v4/graphics/drawable/DrawableCompatApi23.java
@@ -18,14 +18,12 @@
 
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * Implementation of drawable compatibility that can call M APIs.
  */
 
 @RequiresApi(23)
-@TargetApi(23)
 class DrawableCompatApi23 {
     public static boolean setLayoutDirection(Drawable drawable, int layoutDirection) {
         return drawable.setLayoutDirection(layoutDirection);
diff --git a/compat/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java b/compat/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java
index e4e2aa5..72a21a3 100644
--- a/compat/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java
+++ b/compat/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.hardware.fingerprint.FingerprintManager;
@@ -36,7 +35,6 @@
  * @hide
  */
 @RequiresApi(23)
-@TargetApi(23)
 @RestrictTo(LIBRARY_GROUP)
 public final class FingerprintManagerCompatApi23 {
 
diff --git a/compat/api23/android/support/v4/text/ICUCompatApi23.java b/compat/api23/android/support/v4/text/ICUCompatApi23.java
index 182c6f3..0088f95 100644
--- a/compat/api23/android/support/v4/text/ICUCompatApi23.java
+++ b/compat/api23/android/support/v4/text/ICUCompatApi23.java
@@ -17,7 +17,6 @@
 package android.support.v4.text;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.Log;
 
 import java.lang.reflect.InvocationTargetException;
@@ -25,7 +24,6 @@
 import java.util.Locale;
 
 @RequiresApi(23)
-@TargetApi(23)
 class ICUCompatApi23 {
 
     private static final String TAG = "ICUCompatIcs";
diff --git a/compat/api23/android/support/v4/view/ViewCompatMarshmallow.java b/compat/api23/android/support/v4/view/ViewCompatMarshmallow.java
index 30645ec..d370371 100644
--- a/compat/api23/android/support/v4/view/ViewCompatMarshmallow.java
+++ b/compat/api23/android/support/v4/view/ViewCompatMarshmallow.java
@@ -17,11 +17,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 
 @RequiresApi(23)
-@TargetApi(23)
 class ViewCompatMarshmallow {
     public static void setScrollIndicators(View view, int indicators) {
         view.setScrollIndicators(indicators);
diff --git a/compat/api23/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi23.java b/compat/api23/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi23.java
index 457cd39..c478e76 100644
--- a/compat/api23/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi23.java
+++ b/compat/api23/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi23.java
@@ -17,11 +17,9 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 @RequiresApi(23)
-@TargetApi(23)
 class AccessibilityNodeInfoCompatApi23 {
     public static Object getActionScrollToPosition() {
         return AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_TO_POSITION;
diff --git a/compat/api23/android/support/v4/widget/CompoundButtonCompatApi23.java b/compat/api23/android/support/v4/widget/CompoundButtonCompatApi23.java
index 6dddbdb..cbfb234 100644
--- a/compat/api23/android/support/v4/widget/CompoundButtonCompatApi23.java
+++ b/compat/api23/android/support/v4/widget/CompoundButtonCompatApi23.java
@@ -18,11 +18,9 @@
 
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.CompoundButton;
 
 @RequiresApi(23)
-@TargetApi(23)
 class CompoundButtonCompatApi23 {
 
     static Drawable getButtonDrawable(CompoundButton button) {
diff --git a/compat/api23/android/support/v4/widget/PopupWindowCompatApi23.java b/compat/api23/android/support/v4/widget/PopupWindowCompatApi23.java
index 1483e41..9d30f61 100644
--- a/compat/api23/android/support/v4/widget/PopupWindowCompatApi23.java
+++ b/compat/api23/android/support/v4/widget/PopupWindowCompatApi23.java
@@ -17,11 +17,9 @@
 package android.support.v4.widget;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.PopupWindow;
 
 @RequiresApi(23)
-@TargetApi(23)
 class PopupWindowCompatApi23 {
 
     static void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
diff --git a/compat/api23/android/support/v4/widget/TextViewCompatApi23.java b/compat/api23/android/support/v4/widget/TextViewCompatApi23.java
index f31242b..9d63929 100644
--- a/compat/api23/android/support/v4/widget/TextViewCompatApi23.java
+++ b/compat/api23/android/support/v4/widget/TextViewCompatApi23.java
@@ -18,12 +18,10 @@
 
 import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.support.annotation.StyleRes;
 import android.widget.TextView;
 
 @RequiresApi(23)
-@TargetApi(23)
 class TextViewCompatApi23 {
     public static void setTextAppearance(@NonNull TextView textView, @StyleRes int resId) {
         textView.setTextAppearance(resId);
diff --git a/compat/api24/android/support/v4/app/ActivityOptionsCompat24.java b/compat/api24/android/support/v4/app/ActivityOptionsCompat24.java
index d33d8a2..8e0d520 100644
--- a/compat/api24/android/support/v4/app/ActivityOptionsCompat24.java
+++ b/compat/api24/android/support/v4/app/ActivityOptionsCompat24.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.ActivityOptions;
 import android.app.PendingIntent;
@@ -30,7 +29,6 @@
 import android.view.View;
 
 @RequiresApi(24)
-@TargetApi(24)
 class ActivityOptionsCompat24 {
 
     public static ActivityOptionsCompat24 makeCustomAnimation(Context context,
diff --git a/compat/api24/android/support/v4/app/NotificationCompatApi24.java b/compat/api24/android/support/v4/app/NotificationCompatApi24.java
index 6a29d89..12faa8e 100644
--- a/compat/api24/android/support/v4/app/NotificationCompatApi24.java
+++ b/compat/api24/android/support/v4/app/NotificationCompatApi24.java
@@ -24,14 +24,12 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.RemoteViews;
 
 import java.util.ArrayList;
 import java.util.List;
 
 @RequiresApi(24)
-@TargetApi(24)
 class NotificationCompatApi24 {
 
     public static final String CATEGORY_CALL = Notification.CATEGORY_CALL;
@@ -115,25 +113,7 @@
 
         @Override
         public void addAction(NotificationCompatBase.Action action) {
-            Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
-                    action.getIcon(), action.getTitle(), action.getActionIntent());
-            if (action.getRemoteInputs() != null) {
-                for (RemoteInput remoteInput : RemoteInputCompatApi20.fromCompat(
-                        action.getRemoteInputs())) {
-                    actionBuilder.addRemoteInput(remoteInput);
-                }
-            }
-            Bundle actionExtras;
-            if (action.getExtras() != null) {
-                actionExtras = new Bundle(action.getExtras());
-            } else {
-                actionExtras = new Bundle();
-            }
-            actionExtras.putBoolean(NotificationCompatJellybean.EXTRA_ALLOW_GENERATED_REPLIES,
-                    action.getAllowGeneratedReplies());
-            actionBuilder.addExtras(actionExtras);
-            actionBuilder.setAllowGeneratedReplies(action.getAllowGeneratedReplies());
-            b.addAction(actionBuilder.build());
+            NotificationCompatApi24.addAction(b, action);
         }
 
         @Override
@@ -163,4 +143,26 @@
         }
         style.setBuilder(b.getBuilder());
     }
+
+    public static void addAction(Notification.Builder b, NotificationCompatBase.Action action) {
+        Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
+                action.getIcon(), action.getTitle(), action.getActionIntent());
+        if (action.getRemoteInputs() != null) {
+            for (RemoteInput remoteInput : RemoteInputCompatApi20.fromCompat(
+                    action.getRemoteInputs())) {
+                actionBuilder.addRemoteInput(remoteInput);
+            }
+        }
+        Bundle actionExtras;
+        if (action.getExtras() != null) {
+            actionExtras = new Bundle(action.getExtras());
+        } else {
+            actionExtras = new Bundle();
+        }
+        actionExtras.putBoolean(NotificationCompatJellybean.EXTRA_ALLOW_GENERATED_REPLIES,
+                action.getAllowGeneratedReplies());
+        actionBuilder.addExtras(actionExtras);
+        actionBuilder.setAllowGeneratedReplies(action.getAllowGeneratedReplies());
+        b.addAction(actionBuilder.build());
+    }
 }
diff --git a/compat/api24/android/support/v4/app/NotificationManagerCompatApi24.java b/compat/api24/android/support/v4/app/NotificationManagerCompatApi24.java
index 468592f..3e03dbd 100644
--- a/compat/api24/android/support/v4/app/NotificationManagerCompatApi24.java
+++ b/compat/api24/android/support/v4/app/NotificationManagerCompatApi24.java
@@ -17,10 +17,8 @@
 
 import android.app.NotificationManager;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(24)
-@TargetApi(24)
 class NotificationManagerCompatApi24 {
     public static boolean areNotificationsEnabled(NotificationManager notificationManager) {
         return notificationManager.areNotificationsEnabled();
diff --git a/compat/api24/android/support/v4/app/ServiceCompatApi24.java b/compat/api24/android/support/v4/app/ServiceCompatApi24.java
index 29b6112..74b8e2c 100644
--- a/compat/api24/android/support/v4/app/ServiceCompatApi24.java
+++ b/compat/api24/android/support/v4/app/ServiceCompatApi24.java
@@ -17,10 +17,8 @@
 
 import android.app.Service;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(24)
-@TargetApi(24)
 class ServiceCompatApi24 {
     public static void stopForeground(Service service, int flags) {
         service.stopForeground(flags);
diff --git a/compat/api24/android/support/v4/content/ContextCompatApi24.java b/compat/api24/android/support/v4/content/ContextCompatApi24.java
index a65f21b..c979fb4 100644
--- a/compat/api24/android/support/v4/content/ContextCompatApi24.java
+++ b/compat/api24/android/support/v4/content/ContextCompatApi24.java
@@ -18,12 +18,10 @@
 
 import android.content.Context;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import java.io.File;
 
 @RequiresApi(24)
-@TargetApi(24)
 class ContextCompatApi24 {
     public static File getDataDir(Context context) {
         return context.getDataDir();
diff --git a/compat/api24/android/support/v4/net/ConnectivityManagerCompatApi24.java b/compat/api24/android/support/v4/net/ConnectivityManagerCompatApi24.java
index b6e86cb..c63062d 100644
--- a/compat/api24/android/support/v4/net/ConnectivityManagerCompatApi24.java
+++ b/compat/api24/android/support/v4/net/ConnectivityManagerCompatApi24.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.net;
 
-import android.annotation.TargetApi;
 import android.net.ConnectivityManager;
 import android.support.annotation.RequiresApi;
 
@@ -24,7 +23,6 @@
  * Implementation of ConnectivityManagerCompat that can use API 24 APIs.
  */
 @RequiresApi(24)
-@TargetApi(24)
 class ConnectivityManagerCompatApi24 {
     public static int getRestrictBackgroundStatus(ConnectivityManager cm) {
         return cm.getRestrictBackgroundStatus();
diff --git a/compat/api24/android/support/v4/net/TrafficStatsCompatApi24.java b/compat/api24/android/support/v4/net/TrafficStatsCompatApi24.java
index 834c6ad..7a9e248 100644
--- a/compat/api24/android/support/v4/net/TrafficStatsCompatApi24.java
+++ b/compat/api24/android/support/v4/net/TrafficStatsCompatApi24.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.net.TrafficStats;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
@@ -28,7 +27,6 @@
 
 /** @hide */
 @RequiresApi(24)
-@TargetApi(24)
 @RestrictTo(LIBRARY_GROUP)
 public class TrafficStatsCompatApi24 {
     public static void tagDatagramSocket(DatagramSocket socket) throws SocketException {
diff --git a/compat/api24/android/support/v4/os/UserManagerCompatApi24.java b/compat/api24/android/support/v4/os/UserManagerCompatApi24.java
index ab6f91d..30a430c 100644
--- a/compat/api24/android/support/v4/os/UserManagerCompatApi24.java
+++ b/compat/api24/android/support/v4/os/UserManagerCompatApi24.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.os.UserManager;
 import android.support.annotation.RequiresApi;
@@ -26,7 +25,6 @@
 
 /** @hide */
 @RequiresApi(24)
-@TargetApi(24)
 @RestrictTo(LIBRARY_GROUP)
 public class UserManagerCompatApi24 {
     public static boolean isUserUnlocked(Context context) {
diff --git a/compat/api24/android/support/v4/view/PointerIconCompatApi24.java b/compat/api24/android/support/v4/view/PointerIconCompatApi24.java
index 424af92..0a54ae0 100644
--- a/compat/api24/android/support/v4/view/PointerIconCompatApi24.java
+++ b/compat/api24/android/support/v4/view/PointerIconCompatApi24.java
@@ -20,11 +20,9 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.PointerIcon;
 
 @RequiresApi(24)
-@TargetApi(24)
 class PointerIconCompatApi24 {
     public static Object getSystemIcon(Context context, int style) {
         return PointerIcon.getSystemIcon(context, style);
diff --git a/compat/api24/android/support/v4/view/ViewCompatApi24.java b/compat/api24/android/support/v4/view/ViewCompatApi24.java
index 71366a8..924466f 100644
--- a/compat/api24/android/support/v4/view/ViewCompatApi24.java
+++ b/compat/api24/android/support/v4/view/ViewCompatApi24.java
@@ -17,14 +17,20 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.PointerIcon;
 import android.view.View;
 
 @RequiresApi(24)
-@TargetApi(24)
 class ViewCompatApi24 {
     public static void setPointerIcon(View view, Object pointerIcon) {
         view.setPointerIcon((PointerIcon)pointerIcon);
     }
+
+    public static void dispatchStartTemporaryDetach(View view) {
+        view.dispatchStartTemporaryDetach();
+    }
+
+    public static void dispatchFinishTemporaryDetach(View view) {
+        view.dispatchFinishTemporaryDetach();
+    }
 }
diff --git a/compat/api24/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi24.java b/compat/api24/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi24.java
index 5e64091..8b593b3 100644
--- a/compat/api24/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi24.java
+++ b/compat/api24/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatApi24.java
@@ -17,7 +17,6 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 /**
@@ -25,7 +24,6 @@
  */
 
 @RequiresApi(24)
-@TargetApi(24)
 class AccessibilityNodeInfoCompatApi24 {
     public static Object getActionSetProgress() {
         return AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_PROGRESS;
diff --git a/compat/api24/android/support/v4/view/accessibility/AccessibilityWindowInfoCompatApi24.java b/compat/api24/android/support/v4/view/accessibility/AccessibilityWindowInfoCompatApi24.java
index c8aa21a..6a68bca 100644
--- a/compat/api24/android/support/v4/view/accessibility/AccessibilityWindowInfoCompatApi24.java
+++ b/compat/api24/android/support/v4/view/accessibility/AccessibilityWindowInfoCompatApi24.java
@@ -17,7 +17,6 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityWindowInfo;
 
 /**
@@ -25,7 +24,6 @@
  */
 
 @RequiresApi(24)
-@TargetApi(24)
 class AccessibilityWindowInfoCompatApi24 {
     public static CharSequence getTitle(Object info) {
         return ((AccessibilityWindowInfo) info).getTitle();
diff --git a/compat/api26/android/support/v4/app/NotificationCompatApi26.java b/compat/api26/android/support/v4/app/NotificationCompatApi26.java
new file mode 100644
index 0000000..b6acd04
--- /dev/null
+++ b/compat/api26/android/support/v4/app/NotificationCompatApi26.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.app;
+
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.support.annotation.RequiresApi;
+import android.widget.RemoteViews;
+
+import java.util.ArrayList;
+
+@RequiresApi(26)
+class NotificationCompatApi26 {
+    public static class Builder implements NotificationBuilderWithBuilderAccessor,
+            NotificationBuilderWithActions {
+        private Notification.Builder mB;
+
+        Builder(Context context, Notification n,
+                CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
+                RemoteViews tickerView, int number,
+                PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon,
+                int progressMax, int progress, boolean progressIndeterminate, boolean showWhen,
+                boolean useChronometer, int priority, CharSequence subText, boolean localOnly,
+                String category, ArrayList<String> people, Bundle extras, int color,
+                int visibility, Notification publicVersion, String groupKey, boolean groupSummary,
+                String sortKey, CharSequence[] remoteInputHistory, RemoteViews contentView,
+                RemoteViews bigContentView, RemoteViews headsUpContentView,
+                String channelId) {
+            mB = new Notification.Builder(context)
+                    .setWhen(n.when)
+                    .setShowWhen(showWhen)
+                    .setSmallIcon(n.icon, n.iconLevel)
+                    .setContent(n.contentView)
+                    .setTicker(n.tickerText, tickerView)
+                    .setSound(n.sound, n.audioStreamType)
+                    .setVibrate(n.vibrate)
+                    .setLights(n.ledARGB, n.ledOnMS, n.ledOffMS)
+                    .setOngoing((n.flags & Notification.FLAG_ONGOING_EVENT) != 0)
+                    .setOnlyAlertOnce((n.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)
+                    .setAutoCancel((n.flags & Notification.FLAG_AUTO_CANCEL) != 0)
+                    .setDefaults(n.defaults)
+                    .setContentTitle(contentTitle)
+                    .setContentText(contentText)
+                    .setSubText(subText)
+                    .setContentInfo(contentInfo)
+                    .setContentIntent(contentIntent)
+                    .setDeleteIntent(n.deleteIntent)
+                    .setFullScreenIntent(fullScreenIntent,
+                            (n.flags & Notification.FLAG_HIGH_PRIORITY) != 0)
+                    .setLargeIcon(largeIcon)
+                    .setNumber(number)
+                    .setUsesChronometer(useChronometer)
+                    .setPriority(priority)
+                    .setProgress(progressMax, progress, progressIndeterminate)
+                    .setLocalOnly(localOnly)
+                    .setExtras(extras)
+                    .setGroup(groupKey)
+                    .setGroupSummary(groupSummary)
+                    .setSortKey(sortKey)
+                    .setCategory(category)
+                    .setColor(color)
+                    .setVisibility(visibility)
+                    .setPublicVersion(publicVersion)
+                    .setRemoteInputHistory(remoteInputHistory)
+                    .setChannel(channelId);
+            if (contentView != null) {
+                mB.setCustomContentView(contentView);
+            }
+            if (bigContentView != null) {
+                mB.setCustomBigContentView(bigContentView);
+            }
+            if (headsUpContentView != null) {
+                mB.setCustomHeadsUpContentView(headsUpContentView);
+            }
+            for (String person : people) {
+                mB.addPerson(person);
+            }
+        }
+
+        @Override
+        public void addAction(NotificationCompatBase.Action action) {
+            NotificationCompatApi24.addAction(mB, action);
+        }
+
+        @Override
+        public Notification.Builder getBuilder() {
+            return mB;
+        }
+
+        @Override
+        public Notification build() {
+            return mB.build();
+        }
+    }
+
+    public static String getChannel(Notification n) {
+        return n.getChannel();
+    }
+}
diff --git a/compat/api26/android/support/v4/content/pm/ShortcutManagerCompatApi26.java b/compat/api26/android/support/v4/content/pm/ShortcutManagerCompatApi26.java
new file mode 100644
index 0000000..692d629
--- /dev/null
+++ b/compat/api26/android/support/v4/content/pm/ShortcutManagerCompatApi26.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.content.pm;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.ShortcutManager;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
+
+@RequiresApi(26)
+class ShortcutManagerCompatApi26 {
+
+    public static boolean isRequestPinShortcutSupported(Context context) {
+        return context.getSystemService(ShortcutManager.class).isRequestPinShortcutSupported();
+    }
+
+    public static boolean requestPinShortcut(final Context context,
+            @NonNull ShortcutInfoCompat shortcut, @Nullable final IntentSender callback) {
+        return context.getSystemService(ShortcutManager.class).requestPinShortcut(
+                shortcut.toShortcutInfo(), callback);
+    }
+
+    @Nullable
+    public static Intent createShortcutResultIntent(Context context,
+            @NonNull ShortcutInfoCompat shortcut) {
+        return context.getSystemService(ShortcutManager.class)
+                .createShortcutResultIntent(shortcut.toShortcutInfo());
+    }
+}
diff --git a/compat/api26/android/support/v4/view/MenuItemCompatApi26.java b/compat/api26/android/support/v4/view/MenuItemCompatApi26.java
new file mode 100644
index 0000000..053ee5a
--- /dev/null
+++ b/compat/api26/android/support/v4/view/MenuItemCompatApi26.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.view;
+
+import android.support.annotation.RequiresApi;
+import android.view.MenuItem;
+
+@RequiresApi(26)
+class MenuItemCompatApi26 {
+    public static void setContentDescription(MenuItem item, CharSequence contentDescription) {
+        item.setContentDescription(contentDescription);
+    }
+
+    public static CharSequence getContentDescription(MenuItem item) {
+        return item.getContentDescription();
+    }
+
+    public static void setTooltipText(MenuItem item, CharSequence tooltipText) {
+        item.setTooltipText(tooltipText);
+    }
+
+    public static CharSequence getTooltipText(MenuItem item) {
+        return item.getTooltipText();
+    }
+}
diff --git a/design/base/android/support/design/internal/BottomNavigationAnimationHelperBase.java b/compat/api26/android/support/v4/view/ViewCompatApi26.java
similarity index 69%
rename from design/base/android/support/design/internal/BottomNavigationAnimationHelperBase.java
rename to compat/api26/android/support/v4/view/ViewCompatApi26.java
index 22501c1..06d468c 100644
--- a/design/base/android/support/design/internal/BottomNavigationAnimationHelperBase.java
+++ b/compat/api26/android/support/v4/view/ViewCompatApi26.java
@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
-package android.support.design.internal;
+package android.support.v4.view;
 
-import android.view.ViewGroup;
+import android.support.annotation.RequiresApi;
+import android.view.View;
 
-class BottomNavigationAnimationHelperBase {
-    void beginDelayedTransition(ViewGroup view) {
-        // Do nothing.
+@RequiresApi(26)
+class ViewCompatApi26 {
+    public static void setTooltipText(View view, CharSequence tooltipText) {
+        view.setTooltipText(tooltipText);
     }
 }
diff --git a/compat/build.gradle b/compat/build.gradle
index e87db0e..0bc9137 100644
--- a/compat/build.gradle
+++ b/compat/build.gradle
@@ -1,30 +1,26 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'support-compat'
 
 dependencies {
     compile project(':support-annotations')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile 'org.mockito:mockito-core:1.9.5'
-    androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
-    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
-    testCompile 'junit:junit:4.12'
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'gingerbread',
                 'honeycomb',
@@ -41,71 +37,15 @@
                 'api22',
                 'api23',
                 'api24',
+                'api26',
                 'java'
         ]
         main.aidl.srcDirs = ['java']
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/java'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
     }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
-        compileSdkVersion project.ext.currentSdk
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-        exclude('android/content/pm/**')
-        exclude('android/service/media/**')
-    }
-
-    artifacts.add('archives', sourcesJarTask);
+supportLibrary {
+    name 'Android Support Library compat'
+    inceptionYear '2015'
+    description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 4 or later."
 }
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Library compat'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/compat/gingerbread/android/support/v4/animation/AnimatorListenerCompat.java b/compat/gingerbread/android/support/v4/animation/AnimatorListenerCompat.java
deleted file mode 100644
index a2c043f..0000000
--- a/compat/gingerbread/android/support/v4/animation/AnimatorListenerCompat.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.animation;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.support.annotation.RestrictTo;
-
-/**
- * <p>An animation listener that receives notifications from an animation.
- * Notifications indicate animation related events, such as the end or the
- * repetition of the animation.</p>
- *
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-public interface AnimatorListenerCompat {
-
-    /**
-     * <p>Notifies the start of the animation.</p>
-     *
-     * @param animation The started animation.
-     */
-    void onAnimationStart(ValueAnimatorCompat 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(ValueAnimatorCompat 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(ValueAnimatorCompat animation);
-
-    /**
-     * <p>Notifies the repetition of the animation.</p>
-     *
-     * @param animation The animation which was repeated.
-     */
-    void onAnimationRepeat(ValueAnimatorCompat animation);
-}
diff --git a/compat/gingerbread/android/support/v4/animation/AnimatorProvider.java b/compat/gingerbread/android/support/v4/animation/AnimatorProvider.java
deleted file mode 100644
index 51d4bb0..0000000
--- a/compat/gingerbread/android/support/v4/animation/AnimatorProvider.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.animation;
-
-import android.view.View;
-
-/**
- * A simple interface to do things in animation pulse.
- * <p>
- * Before Honeycomb, it uses a simple Handler to mimic animation callback.
- * <p>
- * This is only a minimal implementation which is why this class is hidden.
- */
-interface AnimatorProvider {
-
-    /**
-     * Provides a simple ValueAnimator w/o any start or end values. It provides the same
-     * Animator callback interface.
-     */
-    ValueAnimatorCompat emptyValueAnimator();
-
-    void clearInterpolator(View view);
-}
diff --git a/compat/gingerbread/android/support/v4/animation/AnimatorUpdateListenerCompat.java b/compat/gingerbread/android/support/v4/animation/AnimatorUpdateListenerCompat.java
deleted file mode 100644
index 2cf3fbd..0000000
--- a/compat/gingerbread/android/support/v4/animation/AnimatorUpdateListenerCompat.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.animation;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.support.annotation.RestrictTo;
-
-/**
- * Implementors of this interface can add themselves as update listeners
- * to a <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>.
- *
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-public interface AnimatorUpdateListenerCompat {
-
-    /**
-     * <p>Notifies the occurrence of another frame of the animation.</p>
-     *
-     * @param animation The animation which was repeated.
-     */
-    void onAnimationUpdate(ValueAnimatorCompat animation);
-
-}
\ No newline at end of file
diff --git a/compat/gingerbread/android/support/v4/animation/GingerbreadAnimatorCompatProvider.java b/compat/gingerbread/android/support/v4/animation/GingerbreadAnimatorCompatProvider.java
deleted file mode 100644
index 83ba12a..0000000
--- a/compat/gingerbread/android/support/v4/animation/GingerbreadAnimatorCompatProvider.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.animation;
-
-import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
-import android.view.View;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides similar functionality to Animators on platforms prior to Honeycomb.
- * <p>
- * This is not a fully implemented API which is why it is not public.
- */
-
-@RequiresApi(9)
-@TargetApi(9)
-class GingerbreadAnimatorCompatProvider implements AnimatorProvider {
-
-    @Override
-    public ValueAnimatorCompat emptyValueAnimator() {
-        return new GingerbreadFloatValueAnimator();
-    }
-
-    private static class GingerbreadFloatValueAnimator implements ValueAnimatorCompat {
-
-        List<AnimatorListenerCompat> mListeners = new ArrayList<AnimatorListenerCompat>();
-        List<AnimatorUpdateListenerCompat> mUpdateListeners
-                = new ArrayList<AnimatorUpdateListenerCompat>();
-        View mTarget;
-        private long mStartTime;
-        private long mDuration = 200;
-        private float mFraction = 0f;
-
-        private boolean mStarted = false;
-        private boolean mEnded = false;
-
-        public GingerbreadFloatValueAnimator() {
-        }
-
-        private Runnable mLoopRunnable = new Runnable() {
-            @Override
-            public void run() {
-                long dt = getTime() - mStartTime;
-                float fraction = dt * 1f / mDuration;
-                if (fraction > 1f || mTarget.getParent() == null) {
-                    fraction = 1f;
-                }
-                mFraction = fraction;
-                notifyUpdateListeners();
-                if (mFraction >= 1f) {
-                    dispatchEnd();
-                } else {
-                    mTarget.postDelayed(mLoopRunnable, 16);
-                }
-            }
-        };
-
-        private void notifyUpdateListeners() {
-            for (int i = mUpdateListeners.size() - 1; i >= 0; i--) {
-                mUpdateListeners.get(i).onAnimationUpdate(this);
-            }
-        }
-
-        @Override
-        public void setTarget(View view) {
-            mTarget = view;
-        }
-
-        @Override
-        public void addListener(AnimatorListenerCompat listener) {
-            mListeners.add(listener);
-        }
-
-        @Override
-        public void setDuration(long duration) {
-            if (!mStarted) {
-                mDuration = duration;
-            }
-        }
-
-        @Override
-        public void start() {
-            if (mStarted) {
-                return;
-            }
-            mStarted = true;
-            dispatchStart();
-            mFraction = 0f;
-            mStartTime = getTime();
-            mTarget.postDelayed(mLoopRunnable, 16);
-        }
-
-        private long getTime() {
-            return mTarget.getDrawingTime();
-        }
-
-        private void dispatchStart() {
-            for (int i = mListeners.size() - 1; i >= 0; i--) {
-                mListeners.get(i).onAnimationStart(this);
-            }
-        }
-
-        private void dispatchEnd() {
-            for (int i = mListeners.size() - 1; i >= 0; i--) {
-                mListeners.get(i).onAnimationEnd(this);
-            }
-        }
-
-        private void dispatchCancel() {
-            for (int i = mListeners.size() - 1; i >= 0; i--) {
-                mListeners.get(i).onAnimationCancel(this);
-            }
-        }
-
-        @Override
-        public void cancel() {
-            if (mEnded) {
-                return;
-            }
-            mEnded = true;
-            if (mStarted) {
-                dispatchCancel();
-            }
-            dispatchEnd();
-        }
-
-        @Override
-        public void addUpdateListener(AnimatorUpdateListenerCompat animatorUpdateListener) {
-            mUpdateListeners.add(animatorUpdateListener);
-        }
-
-        @Override
-        public float getAnimatedFraction() {
-            return mFraction;
-        }
-    }
-
-    @Override
-    public void clearInterpolator(View view) {
-    }
-}
diff --git a/compat/gingerbread/android/support/v4/animation/ValueAnimatorCompat.java b/compat/gingerbread/android/support/v4/animation/ValueAnimatorCompat.java
deleted file mode 100644
index b064030..0000000
--- a/compat/gingerbread/android/support/v4/animation/ValueAnimatorCompat.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.animation;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.support.annotation.RestrictTo;
-import android.view.View;
-
-/**
- * Compatibility implementation for {@code android.animation.ValueAnimator}.
- *
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-public interface ValueAnimatorCompat {
-
-    public void setTarget(View view);
-
-    public void addListener(AnimatorListenerCompat listener);
-
-    public void setDuration(long duration);
-
-    public void start();
-
-    public void cancel();
-
-    void addUpdateListener(AnimatorUpdateListenerCompat animatorUpdateListener);
-
-    public float getAnimatedFraction();
-}
diff --git a/compat/gingerbread/android/support/v4/app/BundleCompatGingerbread.java b/compat/gingerbread/android/support/v4/app/BundleCompatGingerbread.java
index f7656be..24da775 100644
--- a/compat/gingerbread/android/support/v4/app/BundleCompatGingerbread.java
+++ b/compat/gingerbread/android/support/v4/app/BundleCompatGingerbread.java
@@ -19,14 +19,12 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.Log;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 @RequiresApi(9)
-@TargetApi(9)
 class BundleCompatGingerbread {
     private static final String TAG = "BundleCompatGingerbread";
 
diff --git a/compat/gingerbread/android/support/v4/app/NotificationCompatBase.java b/compat/gingerbread/android/support/v4/app/NotificationCompatBase.java
index 33447cc..95ebba9 100644
--- a/compat/gingerbread/android/support/v4/app/NotificationCompatBase.java
+++ b/compat/gingerbread/android/support/v4/app/NotificationCompatBase.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -34,7 +33,6 @@
  */
 @RestrictTo(LIBRARY_GROUP)
 @RequiresApi(9)
-@TargetApi(9)
 public class NotificationCompatBase {
     private static Method sSetLatestEventInfo;
 
@@ -44,11 +42,14 @@
         public abstract PendingIntent getActionIntent();
         public abstract Bundle getExtras();
         public abstract RemoteInputCompatBase.RemoteInput[] getRemoteInputs();
+        /** Returns RemoteInputs that ONLY accept data results, not text. */
+        public abstract RemoteInputCompatBase.RemoteInput[] getDataOnlyRemoteInputs();
         public abstract boolean getAllowGeneratedReplies();
 
         public interface Factory {
             Action build(int icon, CharSequence title, PendingIntent actionIntent,
                     Bundle extras, RemoteInputCompatBase.RemoteInput[] remoteInputs,
+                    RemoteInputCompatBase.RemoteInput[] dataOnlyRemoteInputs,
                     boolean allowGeneratedReplies);
             public Action[] newArray(int length);
         }
diff --git a/compat/gingerbread/android/support/v4/app/RemoteInputCompatBase.java b/compat/gingerbread/android/support/v4/app/RemoteInputCompatBase.java
index 85117dd..e3db942 100644
--- a/compat/gingerbread/android/support/v4/app/RemoteInputCompatBase.java
+++ b/compat/gingerbread/android/support/v4/app/RemoteInputCompatBase.java
@@ -18,10 +18,10 @@
 
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
+
+import java.util.Set;
 
 @RequiresApi(9)
-@TargetApi(9)
 class RemoteInputCompatBase {
 
     public static abstract class RemoteInput {
@@ -30,10 +30,12 @@
         protected abstract CharSequence[] getChoices();
         protected abstract boolean getAllowFreeFormInput();
         protected abstract Bundle getExtras();
+        protected abstract Set<String> getAllowedDataTypes();
 
         public interface Factory {
             public RemoteInput build(String resultKey, CharSequence label,
-                    CharSequence[] choices, boolean allowFreeFormInput, Bundle extras);
+                    CharSequence[] choices, boolean allowFreeFormInput, Bundle extras,
+                    Set<String> allowedDataTypes);
             public RemoteInput[] newArray(int length);
         }
     }
diff --git a/compat/gingerbread/android/support/v4/content/res/ConfigurationHelperGingerbread.java b/compat/gingerbread/android/support/v4/content/res/ConfigurationHelperGingerbread.java
index 6667431..ac2db3c 100644
--- a/compat/gingerbread/android/support/v4/content/res/ConfigurationHelperGingerbread.java
+++ b/compat/gingerbread/android/support/v4/content/res/ConfigurationHelperGingerbread.java
@@ -19,11 +19,9 @@
 import android.content.res.Resources;
 import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.DisplayMetrics;
 
 @RequiresApi(9)
-@TargetApi(9)
 class ConfigurationHelperGingerbread {
 
     static int getScreenHeightDp(@NonNull Resources resources) {
diff --git a/compat/gingerbread/android/support/v4/graphics/drawable/DrawableCompatBase.java b/compat/gingerbread/android/support/v4/graphics/drawable/DrawableCompatBase.java
index 8e5cd9f..d871ad5 100644
--- a/compat/gingerbread/android/support/v4/graphics/drawable/DrawableCompatBase.java
+++ b/compat/gingerbread/android/support/v4/graphics/drawable/DrawableCompatBase.java
@@ -21,7 +21,6 @@
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.AttributeSet;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -34,7 +33,6 @@
  */
 
 @RequiresApi(9)
-@TargetApi(9)
 class DrawableCompatBase {
 
     public static void setTint(Drawable drawable, int tint) {
diff --git a/compat/gingerbread/android/support/v4/graphics/drawable/DrawableWrapperGingerbread.java b/compat/gingerbread/android/support/v4/graphics/drawable/DrawableWrapperGingerbread.java
index 646c677..13efc32 100644
--- a/compat/gingerbread/android/support/v4/graphics/drawable/DrawableWrapperGingerbread.java
+++ b/compat/gingerbread/android/support/v4/graphics/drawable/DrawableWrapperGingerbread.java
@@ -27,7 +27,6 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * Drawable which delegates all calls to it's wrapped {@link Drawable}.
@@ -37,7 +36,6 @@
  */
 
 @RequiresApi(9)
-@TargetApi(9)
 class DrawableWrapperGingerbread extends Drawable
         implements Drawable.Callback, DrawableWrapper, TintAwareDrawable {
 
diff --git a/compat/gingerbread/android/support/v4/os/BuildCompat.java b/compat/gingerbread/android/support/v4/os/BuildCompat.java
index 7a2efe0..b8e9d9b 100644
--- a/compat/gingerbread/android/support/v4/os/BuildCompat.java
+++ b/compat/gingerbread/android/support/v4/os/BuildCompat.java
@@ -26,6 +26,12 @@
 public class BuildCompat {
     private BuildCompat() {
     }
+    /* Boilerplate for isAtLeast${PLATFORM}:
+     * public static boolean isAtLeast*() {
+     *     return !"REL".equals(VERSION.CODENAME)
+     *             && ("${PLATFORM}".equals(VERSION.CODENAME) || VERSION.CODENAME.startsWith("${PLATFORM}MR"));
+     * }
+     */
 
     /**
      * Check if the device is running on the Android N release or newer.
diff --git a/compat/gingerbread/android/support/v4/view/LayoutInflaterCompatBase.java b/compat/gingerbread/android/support/v4/view/LayoutInflaterCompatBase.java
index 5d97d04..3a57106 100644
--- a/compat/gingerbread/android/support/v4/view/LayoutInflaterCompatBase.java
+++ b/compat/gingerbread/android/support/v4/view/LayoutInflaterCompatBase.java
@@ -18,13 +18,11 @@
 
 import android.content.Context;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
 
 @RequiresApi(9)
-@TargetApi(9)
 class LayoutInflaterCompatBase {
 
     static class FactoryWrapper implements LayoutInflater.Factory {
diff --git a/compat/gingerbread/android/support/v4/view/ViewCompatBase.java b/compat/gingerbread/android/support/v4/view/ViewCompatBase.java
index 7c81f5e..72d19c1 100644
--- a/compat/gingerbread/android/support/v4/view/ViewCompatBase.java
+++ b/compat/gingerbread/android/support/v4/view/ViewCompatBase.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.view;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
@@ -27,9 +26,9 @@
 import android.view.WindowManager;
 
 import java.lang.reflect.Field;
+import java.util.WeakHashMap;
 
 @RequiresApi(9)
-@TargetApi(9)
 class ViewCompatBase {
 
     private static final String TAG = "ViewCompatBase";
@@ -38,6 +37,7 @@
     private static boolean sMinWidthFieldFetched;
     private static Field sMinHeightField;
     private static boolean sMinHeightFieldFetched;
+    private static WeakHashMap<View, String> sTransitionNameMap;
 
     static ColorStateList getBackgroundTintList(View view) {
         return (view instanceof TintableBackgroundView)
@@ -166,4 +166,18 @@
         return null;
     }
 
+    static void setTransitionName(View view, String transitionName) {
+        if (sTransitionNameMap == null) {
+            sTransitionNameMap = new WeakHashMap<>();
+        }
+        sTransitionNameMap.put(view, transitionName);
+    }
+
+    static String getTransitionName(View view) {
+        if (sTransitionNameMap == null) {
+            return null;
+        }
+        return sTransitionNameMap.get(view);
+    }
+
 }
diff --git a/compat/gingerbread/android/support/v4/view/animation/PathInterpolatorCompatBase.java b/compat/gingerbread/android/support/v4/view/animation/PathInterpolatorCompatBase.java
index 5f3e253..e885de3 100644
--- a/compat/gingerbread/android/support/v4/view/animation/PathInterpolatorCompatBase.java
+++ b/compat/gingerbread/android/support/v4/view/animation/PathInterpolatorCompatBase.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Path;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.animation.Interpolator;
 
 /**
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(9)
-@TargetApi(9)
 class PathInterpolatorCompatBase  {
 
     private PathInterpolatorCompatBase() {
diff --git a/compat/gingerbread/android/support/v4/view/animation/PathInterpolatorGingerbread.java b/compat/gingerbread/android/support/v4/view/animation/PathInterpolatorGingerbread.java
index 4c96b97..dff9cf6 100644
--- a/compat/gingerbread/android/support/v4/view/animation/PathInterpolatorGingerbread.java
+++ b/compat/gingerbread/android/support/v4/view/animation/PathInterpolatorGingerbread.java
@@ -19,7 +19,6 @@
 import android.graphics.Path;
 import android.graphics.PathMeasure;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.animation.Interpolator;
 
 /**
@@ -27,7 +26,6 @@
  */
 
 @RequiresApi(9)
-@TargetApi(9)
 class PathInterpolatorGingerbread implements Interpolator {
 
     /**
diff --git a/compat/gingerbread/android/support/v4/widget/CompoundButtonCompatGingerbread.java b/compat/gingerbread/android/support/v4/widget/CompoundButtonCompatGingerbread.java
index 0fe01f0..ba0ed38 100644
--- a/compat/gingerbread/android/support/v4/widget/CompoundButtonCompatGingerbread.java
+++ b/compat/gingerbread/android/support/v4/widget/CompoundButtonCompatGingerbread.java
@@ -20,14 +20,12 @@
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.Log;
 import android.widget.CompoundButton;
 
 import java.lang.reflect.Field;
 
 @RequiresApi(9)
-@TargetApi(9)
 class CompoundButtonCompatGingerbread {
 
     private static final String TAG = "CompoundButtonCompatGingerbread";
diff --git a/compat/gingerbread/android/support/v4/widget/ListViewCompatGingerbread.java b/compat/gingerbread/android/support/v4/widget/ListViewCompatGingerbread.java
index 79edf2c..c390ba1 100644
--- a/compat/gingerbread/android/support/v4/widget/ListViewCompatGingerbread.java
+++ b/compat/gingerbread/android/support/v4/widget/ListViewCompatGingerbread.java
@@ -17,12 +17,10 @@
 package android.support.v4.widget;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.widget.ListView;
 
 @RequiresApi(9)
-@TargetApi(9)
 class ListViewCompatGingerbread {
     static void scrollListBy(final ListView listView, int y) {
         final int firstPosition = listView.getFirstVisiblePosition();
diff --git a/compat/honeycomb/android/support/v4/app/ActivityCompatHoneycomb.java b/compat/honeycomb/android/support/v4/app/ActivityCompatHoneycomb.java
index e5f3bbf..81c3a90 100644
--- a/compat/honeycomb/android/support/v4/app/ActivityCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/app/ActivityCompatHoneycomb.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -28,7 +27,6 @@
  */
 
 @RequiresApi(11)
-@TargetApi(11)
 class ActivityCompatHoneycomb {
     static void invalidateOptionsMenu(Activity activity) {
         activity.invalidateOptionsMenu();
diff --git a/compat/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java b/compat/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
index c75e6a2..f7d42b6 100644
--- a/compat/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
+++ b/compat/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
@@ -31,7 +30,6 @@
  * @hide
  */
 @RequiresApi(11)
-@TargetApi(11)
 @RestrictTo(LIBRARY_GROUP)
 public interface NotificationBuilderWithBuilderAccessor {
     public Notification.Builder getBuilder();
diff --git a/compat/honeycomb/android/support/v4/app/NotificationCompatHoneycomb.java b/compat/honeycomb/android/support/v4/app/NotificationCompatHoneycomb.java
index 44ef21a..43ce5ed 100644
--- a/compat/honeycomb/android/support/v4/app/NotificationCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/app/NotificationCompatHoneycomb.java
@@ -21,11 +21,9 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.RemoteViews;
 
 @RequiresApi(11)
-@TargetApi(11)
 class NotificationCompatHoneycomb {
     static Notification add(Context context, Notification n,
             CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
diff --git a/compat/honeycomb/android/support/v4/content/ContextCompatHoneycomb.java b/compat/honeycomb/android/support/v4/content/ContextCompatHoneycomb.java
index 6b804ad..83fb972 100644
--- a/compat/honeycomb/android/support/v4/content/ContextCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/content/ContextCompatHoneycomb.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import java.io.File;
 
@@ -28,7 +27,6 @@
  */
 
 @RequiresApi(11)
-@TargetApi(11)
 class ContextCompatHoneycomb {
 
     static void startActivities(Context context, Intent[] intents) {
diff --git a/compat/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java b/compat/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java
index 0dcd0d7..dec61db 100644
--- a/compat/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java
@@ -18,7 +18,6 @@
 
 import android.os.AsyncTask;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import java.util.concurrent.Executor;
 
@@ -27,7 +26,6 @@
  */
 
 @RequiresApi(11)
-@TargetApi(11)
 class ExecutorCompatHoneycomb {
     public static Executor getParallelExecutor() {
         return AsyncTask.THREAD_POOL_EXECUTOR;
diff --git a/compat/honeycomb/android/support/v4/content/IntentCompatHoneycomb.java b/compat/honeycomb/android/support/v4/content/IntentCompatHoneycomb.java
index 81ada48..d3243d6 100644
--- a/compat/honeycomb/android/support/v4/content/IntentCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/content/IntentCompatHoneycomb.java
@@ -19,10 +19,8 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(11)
-@TargetApi(11)
 class IntentCompatHoneycomb {
     public static Intent makeMainActivity(ComponentName mainActivity) {
         return Intent.makeMainActivity(mainActivity);
diff --git a/compat/honeycomb/android/support/v4/graphics/drawable/DrawableCompatHoneycomb.java b/compat/honeycomb/android/support/v4/graphics/drawable/DrawableCompatHoneycomb.java
index e19f8a8..93605af 100644
--- a/compat/honeycomb/android/support/v4/graphics/drawable/DrawableCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/graphics/drawable/DrawableCompatHoneycomb.java
@@ -18,14 +18,12 @@
 
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * Implementation of drawable compatibility that can call Honeycomb APIs.
  */
 
 @RequiresApi(11)
-@TargetApi(11)
 class DrawableCompatHoneycomb {
 
     public static void jumpToCurrentState(Drawable drawable) {
diff --git a/compat/honeycomb/android/support/v4/graphics/drawable/DrawableWrapperHoneycomb.java b/compat/honeycomb/android/support/v4/graphics/drawable/DrawableWrapperHoneycomb.java
index 1bd6355..1b5f112 100644
--- a/compat/honeycomb/android/support/v4/graphics/drawable/DrawableWrapperHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/graphics/drawable/DrawableWrapperHoneycomb.java
@@ -21,10 +21,8 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(11)
-@TargetApi(11)
 class DrawableWrapperHoneycomb extends DrawableWrapperGingerbread {
 
     DrawableWrapperHoneycomb(Drawable drawable) {
diff --git a/compat/honeycomb/android/support/v4/os/AsyncTaskCompatHoneycomb.java b/compat/honeycomb/android/support/v4/os/AsyncTaskCompatHoneycomb.java
deleted file mode 100644
index 1b3836e..0000000
--- a/compat/honeycomb/android/support/v4/os/AsyncTaskCompatHoneycomb.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.os;
-
-import android.os.AsyncTask;
-import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
-
-/**
- * Implementation of AsyncTask compatibility that can call Honeycomb APIs.
- */
-
-@RequiresApi(11)
-@TargetApi(11)
-class AsyncTaskCompatHoneycomb {
-
-    static <Params, Progress, Result> void executeParallel(
-            AsyncTask<Params, Progress, Result> task,
-            Params... params) {
-        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
-    }
-
-}
diff --git a/compat/honeycomb/android/support/v4/view/KeyEventCompatHoneycomb.java b/compat/honeycomb/android/support/v4/view/KeyEventCompatHoneycomb.java
index 80425d8..caf0657 100644
--- a/compat/honeycomb/android/support/v4/view/KeyEventCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/view/KeyEventCompatHoneycomb.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.KeyEvent;
 
 /**
@@ -25,7 +24,6 @@
  */
 
 @RequiresApi(11)
-@TargetApi(11)
 class KeyEventCompatHoneycomb {
     public static int normalizeMetaState(int metaState) {
         return KeyEvent.normalizeMetaState(metaState);
diff --git a/compat/honeycomb/android/support/v4/view/LayoutInflaterCompatHC.java b/compat/honeycomb/android/support/v4/view/LayoutInflaterCompatHC.java
index 7eea934..7edae85 100644
--- a/compat/honeycomb/android/support/v4/view/LayoutInflaterCompatHC.java
+++ b/compat/honeycomb/android/support/v4/view/LayoutInflaterCompatHC.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -27,7 +26,6 @@
 import java.lang.reflect.Field;
 
 @RequiresApi(11)
-@TargetApi(11)
 class LayoutInflaterCompatHC {
     private static final String TAG = "LayoutInflaterCompatHC";
 
diff --git a/compat/honeycomb/android/support/v4/view/MenuItemCompatHoneycomb.java b/compat/honeycomb/android/support/v4/view/MenuItemCompatHoneycomb.java
index 0b267d2..f8597bc 100644
--- a/compat/honeycomb/android/support/v4/view/MenuItemCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/view/MenuItemCompatHoneycomb.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.MenuItem;
 import android.view.View;
 
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(11)
-@TargetApi(11)
 class MenuItemCompatHoneycomb {
     public static void setShowAsAction(MenuItem item, int actionEnum) {
         item.setShowAsAction(actionEnum);
diff --git a/compat/honeycomb/android/support/v4/view/VelocityTrackerCompatHoneycomb.java b/compat/honeycomb/android/support/v4/view/VelocityTrackerCompatHoneycomb.java
deleted file mode 100644
index 189dc03..0000000
--- a/compat/honeycomb/android/support/v4/view/VelocityTrackerCompatHoneycomb.java
+++ /dev/null
@@ -1,36 +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 android.support.v4.view;
-
-import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
-import android.view.VelocityTracker;
-
-/**
- * Implementation of velocity tracker compatibility that can call Honeycomb APIs.
- */
-
-@RequiresApi(11)
-@TargetApi(11)
-class VelocityTrackerCompatHoneycomb {
-    public static float getXVelocity(VelocityTracker tracker, int pointerId) {
-        return tracker.getXVelocity(pointerId);
-    }
-    public static float getYVelocity(VelocityTracker tracker, int pointerId) {
-        return tracker.getYVelocity(pointerId);
-    }
-}
diff --git a/compat/honeycomb/android/support/v4/view/ViewCompatHC.java b/compat/honeycomb/android/support/v4/view/ViewCompatHC.java
index 607175b..2209c52 100644
--- a/compat/honeycomb/android/support/v4/view/ViewCompatHC.java
+++ b/compat/honeycomb/android/support/v4/view/ViewCompatHC.java
@@ -16,161 +16,12 @@
 
 package android.support.v4.view;
 
-import android.animation.ValueAnimator;
-import android.graphics.Matrix;
-import android.graphics.Paint;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.ViewParent;
 
 @RequiresApi(11)
-@TargetApi(11)
 class ViewCompatHC {
-    static long getFrameTime() {
-        return ValueAnimator.getFrameDelay();
-    }
-
-    public static float getAlpha(View view) {
-        return view.getAlpha();
-    }
-
-    public static void setLayerType(View view, int layerType, Paint paint) {
-        view.setLayerType(layerType, paint);
-    }
-
-    public static int getLayerType(View view) {
-        return view.getLayerType();
-    }
-
-    public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
-        return View.resolveSizeAndState(size, measureSpec, childMeasuredState);
-    }
-
-    public static int getMeasuredWidthAndState(View view) {
-        return view.getMeasuredWidthAndState();
-    }
-
-    public static int getMeasuredHeightAndState(View view) {
-        return view.getMeasuredHeightAndState();
-    }
-
-    public static int getMeasuredState(View view) {
-        return view.getMeasuredState();
-    }
-
-    public static float getTranslationX(View view) {
-        return view.getTranslationX();
-    }
-
-    public static float getTranslationY(View view) {
-        return view.getTranslationY();
-    }
-
-    public static float getX(View view) {
-        return view.getX();
-    }
-
-    public static float getY(View view) {
-        return view.getY();
-    }
-
-    public static float getRotation(View view) {
-        return view.getRotation();
-    }
-
-    public static float getRotationX(View view) {
-        return view.getRotationX();
-    }
-
-    public static float getRotationY(View view) {
-        return view.getRotationY();
-    }
-
-    public static float getScaleX(View view) {
-        return view.getScaleX();
-    }
-
-    public static float getScaleY(View view) {
-        return view.getScaleY();
-    }
-
-    public static void setTranslationX(View view, float value) {
-        view.setTranslationX(value);
-    }
-
-    public static void setTranslationY(View view, float value) {
-        view.setTranslationY(value);
-    }
-
-    public static Matrix getMatrix(View view) {
-        return view.getMatrix();
-    }
-
-    public static void setAlpha(View view, float value) {
-        view.setAlpha(value);
-    }
-
-    public static void setX(View view, float value) {
-        view.setX(value);
-    }
-
-    public static void setY(View view, float value) {
-        view.setY(value);
-    }
-
-    public static void setRotation(View view, float value) {
-        view.setRotation(value);
-    }
-
-    public static void setRotationX(View view, float value) {
-        view.setRotationX(value);
-    }
-
-    public static void setRotationY(View view, float value) {
-        view.setRotationY(value);
-    }
-
-    public static void setScaleX(View view, float value) {
-        view.setScaleX(value);
-    }
-
-    public static void setScaleY(View view, float value) {
-        view.setScaleY(value);
-    }
-
-    public static void setPivotX(View view, float value) {
-        view.setPivotX(value);
-    }
-
-    public static void setPivotY(View view, float value) {
-        view.setPivotY(value);
-    }
-
-    public static float getPivotX(View view) {
-        return view.getPivotX();
-    }
-
-    public static float getPivotY(View view) {
-        return view.getPivotY();
-    }
-
-    public static void jumpDrawablesToCurrentState(View view) {
-        view.jumpDrawablesToCurrentState();
-    }
-
-    public static void setSaveFromParentEnabled(View view, boolean enabled) {
-        view.setSaveFromParentEnabled(enabled);
-    }
-
-    public static void setActivated(View view, boolean activated) {
-        view.setActivated(activated);
-    }
-
-    public static int combineMeasuredStates(int curState, int newState) {
-        return View.combineMeasuredStates(curState, newState);
-    }
-
     static void offsetTopAndBottom(View view, int offset) {
         view.offsetTopAndBottom(offset);
         if (view.getVisibility() == View.VISIBLE) {
diff --git a/compat/honeycomb/android/support/v4/view/ViewGroupCompatHC.java b/compat/honeycomb/android/support/v4/view/ViewGroupCompatHC.java
index 3b31adf..4e010c6 100644
--- a/compat/honeycomb/android/support/v4/view/ViewGroupCompatHC.java
+++ b/compat/honeycomb/android/support/v4/view/ViewGroupCompatHC.java
@@ -18,11 +18,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.ViewGroup;
 
 @RequiresApi(11)
-@TargetApi(11)
 class ViewGroupCompatHC {
     private ViewGroupCompatHC() {
     }
diff --git a/compat/honeycomb/android/support/v4/widget/SearchViewCompatHoneycomb.java b/compat/honeycomb/android/support/v4/widget/SearchViewCompatHoneycomb.java
index 01867d8..f44e398 100644
--- a/compat/honeycomb/android/support/v4/widget/SearchViewCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/widget/SearchViewCompatHoneycomb.java
@@ -20,7 +20,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.widget.SearchView;
 import android.widget.SearchView.OnCloseListener;
@@ -31,7 +30,6 @@
  */
 
 @RequiresApi(11)
-@TargetApi(11)
 class SearchViewCompatHoneycomb {
 
     public static void checkIfLegalArg(View searchView) {
diff --git a/compat/honeycomb_mr1/android/support/v4/animation/HoneycombMr1AnimatorCompatProvider.java b/compat/honeycomb_mr1/android/support/v4/animation/HoneycombMr1AnimatorCompatProvider.java
deleted file mode 100644
index 9aaae0b..0000000
--- a/compat/honeycomb_mr1/android/support/v4/animation/HoneycombMr1AnimatorCompatProvider.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.animation;
-
-import android.animation.Animator;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
-import android.view.View;
-
-/**
- * Uses framework Animators to provide ValueAnimatorCompat interface.
- * <p/>
- * This is not a fully implemented API which is why it is not public.
- */
-
-@RequiresApi(12)
-@TargetApi(12)
-class HoneycombMr1AnimatorCompatProvider implements AnimatorProvider {
-
-    private TimeInterpolator mDefaultInterpolator;
-
-    @Override
-    public ValueAnimatorCompat emptyValueAnimator() {
-        return new HoneycombValueAnimatorCompat(ValueAnimator.ofFloat(0f, 1f));
-    }
-
-    static class HoneycombValueAnimatorCompat implements ValueAnimatorCompat {
-
-        final Animator mWrapped;
-
-        public HoneycombValueAnimatorCompat(Animator wrapped) {
-            mWrapped = wrapped;
-        }
-
-        @Override
-        public void setTarget(View view) {
-            mWrapped.setTarget(view);
-        }
-
-        @Override
-        public void addListener(AnimatorListenerCompat listener) {
-            mWrapped.addListener(new AnimatorListenerCompatWrapper(listener, this));
-        }
-
-        @Override
-        public void setDuration(long duration) {
-            mWrapped.setDuration(duration);
-        }
-
-        @Override
-        public void start() {
-            mWrapped.start();
-        }
-
-        @Override
-        public void cancel() {
-            mWrapped.cancel();
-        }
-
-        @Override
-        public void addUpdateListener(final AnimatorUpdateListenerCompat animatorUpdateListener) {
-            if (mWrapped instanceof ValueAnimator) {
-                ((ValueAnimator) mWrapped).addUpdateListener(
-                        new ValueAnimator.AnimatorUpdateListener() {
-                            @Override
-                            public void onAnimationUpdate(ValueAnimator animation) {
-                                animatorUpdateListener
-                                        .onAnimationUpdate(HoneycombValueAnimatorCompat.this);
-                            }
-                        });
-            }
-        }
-
-        @Override
-        public float getAnimatedFraction() {
-            return ((ValueAnimator) mWrapped).getAnimatedFraction();
-        }
-    }
-
-    static class AnimatorListenerCompatWrapper implements Animator.AnimatorListener {
-
-        final AnimatorListenerCompat mWrapped;
-
-        final ValueAnimatorCompat mValueAnimatorCompat;
-
-        public AnimatorListenerCompatWrapper(
-                AnimatorListenerCompat wrapped, ValueAnimatorCompat valueAnimatorCompat) {
-            mWrapped = wrapped;
-            mValueAnimatorCompat = valueAnimatorCompat;
-        }
-
-        @Override
-        public void onAnimationStart(Animator animation) {
-            mWrapped.onAnimationStart(mValueAnimatorCompat);
-        }
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            mWrapped.onAnimationEnd(mValueAnimatorCompat);
-        }
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-            mWrapped.onAnimationCancel(mValueAnimatorCompat);
-        }
-
-        @Override
-        public void onAnimationRepeat(Animator animation) {
-            mWrapped.onAnimationRepeat(mValueAnimatorCompat);
-        }
-    }
-
-    @Override
-    public void clearInterpolator(View view) {
-        if (mDefaultInterpolator == null) {
-            mDefaultInterpolator = new ValueAnimator().getInterpolator();
-        }
-        view.animate().setInterpolator(mDefaultInterpolator);
-    }
-}
diff --git a/compat/honeycomb_mr1/android/support/v4/graphics/BitmapCompatHoneycombMr1.java b/compat/honeycomb_mr1/android/support/v4/graphics/BitmapCompatHoneycombMr1.java
index 4266460..5a6f246 100644
--- a/compat/honeycomb_mr1/android/support/v4/graphics/BitmapCompatHoneycombMr1.java
+++ b/compat/honeycomb_mr1/android/support/v4/graphics/BitmapCompatHoneycombMr1.java
@@ -17,14 +17,12 @@
 
 import android.graphics.Bitmap;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * Implementation of BitmapCompat that can use Honeycomb MR1 APIs.
  */
 
 @RequiresApi(12)
-@TargetApi(12)
 class BitmapCompatHoneycombMr1 {
 
     static int getAllocationByteCount(Bitmap bitmap) {
diff --git a/compat/honeycomb_mr1/android/support/v4/view/MotionEventCompatHoneycombMr1.java b/compat/honeycomb_mr1/android/support/v4/view/MotionEventCompatHoneycombMr1.java
index f14e77d..ae4da58 100644
--- a/compat/honeycomb_mr1/android/support/v4/view/MotionEventCompatHoneycombMr1.java
+++ b/compat/honeycomb_mr1/android/support/v4/view/MotionEventCompatHoneycombMr1.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.MotionEvent;
 
 /**
@@ -25,7 +24,6 @@
  */
 
 @RequiresApi(12)
-@TargetApi(12)
 class MotionEventCompatHoneycombMr1 {
     static float getAxisValue(MotionEvent event, int axis) {
         return event.getAxisValue(axis);
diff --git a/compat/honeycomb_mr2/android/support/v4/content/res/ConfigurationHelperHoneycombMr2.java b/compat/honeycomb_mr2/android/support/v4/content/res/ConfigurationHelperHoneycombMr2.java
index aa3aaef..63a6d3b 100644
--- a/compat/honeycomb_mr2/android/support/v4/content/res/ConfigurationHelperHoneycombMr2.java
+++ b/compat/honeycomb_mr2/android/support/v4/content/res/ConfigurationHelperHoneycombMr2.java
@@ -19,10 +19,8 @@
 import android.content.res.Resources;
 import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(13)
-@TargetApi(13)
 class ConfigurationHelperHoneycombMr2 {
 
     static int getScreenHeightDp(@NonNull Resources resources) {
diff --git a/compat/honeycomb_mr2/android/support/v4/net/ConnectivityManagerCompatHoneycombMR2.java b/compat/honeycomb_mr2/android/support/v4/net/ConnectivityManagerCompatHoneycombMR2.java
index a631941..5a93799 100644
--- a/compat/honeycomb_mr2/android/support/v4/net/ConnectivityManagerCompatHoneycombMR2.java
+++ b/compat/honeycomb_mr2/android/support/v4/net/ConnectivityManagerCompatHoneycombMR2.java
@@ -19,7 +19,6 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
@@ -36,7 +35,6 @@
  */
 
 @RequiresApi(13)
-@TargetApi(13)
 class ConnectivityManagerCompatHoneycombMR2 {
     public static boolean isActiveNetworkMetered(ConnectivityManager cm) {
         final NetworkInfo info = cm.getActiveNetworkInfo();
diff --git a/compat/honeycomb_mr2/android/support/v4/os/ParcelableCompatHoneycombMR2.java b/compat/honeycomb_mr2/android/support/v4/os/ParcelableCompatHoneycombMR2.java
index fe754c4..4accbca 100644
--- a/compat/honeycomb_mr2/android/support/v4/os/ParcelableCompatHoneycombMR2.java
+++ b/compat/honeycomb_mr2/android/support/v4/os/ParcelableCompatHoneycombMR2.java
@@ -19,10 +19,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(13)
-@TargetApi(13)
 class ParcelableCompatCreatorHoneycombMR2Stub {
     static <T> Parcelable.Creator<T> instantiate(ParcelableCompatCreatorCallbacks<T> callbacks) {
         return new ParcelableCompatCreatorHoneycombMR2<T>(callbacks);
@@ -30,7 +28,6 @@
 }
 
 @RequiresApi(13)
-@TargetApi(13)
 class ParcelableCompatCreatorHoneycombMR2<T> implements Parcelable.ClassLoaderCreator<T> {
     private final ParcelableCompatCreatorCallbacks<T> mCallbacks;
 
diff --git a/compat/ics-mr1/android/support/v4/content/IntentCompatIcsMr1.java b/compat/ics-mr1/android/support/v4/content/IntentCompatIcsMr1.java
index be17cd6..8dd75d8 100644
--- a/compat/ics-mr1/android/support/v4/content/IntentCompatIcsMr1.java
+++ b/compat/ics-mr1/android/support/v4/content/IntentCompatIcsMr1.java
@@ -18,10 +18,8 @@
 
 import android.content.Intent;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(15)
-@TargetApi(15)
 class IntentCompatIcsMr1 {
 
     public static Intent makeMainSelectorActivity(String selectorAction, String selectorCategory) {
diff --git a/compat/ics-mr1/android/support/v4/content/res/ResourcesCompatIcsMr1.java b/compat/ics-mr1/android/support/v4/content/res/ResourcesCompatIcsMr1.java
index be229b5..9a5fd76 100644
--- a/compat/ics-mr1/android/support/v4/content/res/ResourcesCompatIcsMr1.java
+++ b/compat/ics-mr1/android/support/v4/content/res/ResourcesCompatIcsMr1.java
@@ -20,10 +20,8 @@
 import android.content.res.Resources.NotFoundException;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(15)
-@TargetApi(15)
 class ResourcesCompatIcsMr1 {
     public static Drawable getDrawableForDensity(Resources res, int id, int density)
             throws NotFoundException {
diff --git a/compat/ics-mr1/android/support/v4/view/ViewCompatICSMr1.java b/compat/ics-mr1/android/support/v4/view/ViewCompatICSMr1.java
index 3cf4e5e..16d4bbc 100644
--- a/compat/ics-mr1/android/support/v4/view/ViewCompatICSMr1.java
+++ b/compat/ics-mr1/android/support/v4/view/ViewCompatICSMr1.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 
 /**
@@ -25,7 +24,6 @@
  */
 
 @RequiresApi(15)
-@TargetApi(15)
 class ViewCompatICSMr1 {
     public static boolean hasOnClickListeners(View v) {
         return v.hasOnClickListeners();
diff --git a/compat/ics-mr1/android/support/v4/view/accessibility/AccessibilityRecordCompatIcsMr1.java b/compat/ics-mr1/android/support/v4/view/accessibility/AccessibilityRecordCompatIcsMr1.java
index f249bdd..103eadc 100644
--- a/compat/ics-mr1/android/support/v4/view/accessibility/AccessibilityRecordCompatIcsMr1.java
+++ b/compat/ics-mr1/android/support/v4/view/accessibility/AccessibilityRecordCompatIcsMr1.java
@@ -17,7 +17,6 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityRecord;
 
 /**
@@ -25,7 +24,6 @@
  */
 
 @RequiresApi(15)
-@TargetApi(15)
 class AccessibilityRecordCompatIcsMr1 {
 
     public static int getMaxScrollX(Object record) {
diff --git a/compat/ics/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatIcs.java b/compat/ics/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatIcs.java
index 21e797d..209bf46 100644
--- a/compat/ics/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatIcs.java
+++ b/compat/ics/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatIcs.java
@@ -20,14 +20,12 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.content.pm.ResolveInfo;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * ICS implementation of the new APIs in AccessibilityServiceInfo.
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class AccessibilityServiceInfoCompatIcs {
 
     public static boolean getCanRetrieveWindowContent(AccessibilityServiceInfo info) {
diff --git a/compat/ics/android/support/v4/app/NotificationCompatIceCreamSandwich.java b/compat/ics/android/support/v4/app/NotificationCompatIceCreamSandwich.java
index d2e0e44..7799d18 100644
--- a/compat/ics/android/support/v4/app/NotificationCompatIceCreamSandwich.java
+++ b/compat/ics/android/support/v4/app/NotificationCompatIceCreamSandwich.java
@@ -21,11 +21,9 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.RemoteViews;
 
 @RequiresApi(14)
-@TargetApi(14)
 class NotificationCompatIceCreamSandwich {
 
     public static class Builder implements NotificationBuilderWithBuilderAccessor {
diff --git a/compat/ics/android/support/v4/app/NotificationManagerCompatIceCreamSandwich.java b/compat/ics/android/support/v4/app/NotificationManagerCompatIceCreamSandwich.java
index 4fcf2b1..2cda7e6 100644
--- a/compat/ics/android/support/v4/app/NotificationManagerCompatIceCreamSandwich.java
+++ b/compat/ics/android/support/v4/app/NotificationManagerCompatIceCreamSandwich.java
@@ -18,10 +18,8 @@
 
 import android.app.Service;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(14)
-@TargetApi(14)
 class NotificationManagerCompatIceCreamSandwich {
     static final int SIDE_CHANNEL_BIND_FLAGS = Service.BIND_AUTO_CREATE
             | Service.BIND_WAIVE_PRIORITY;
diff --git a/compat/ics/android/support/v4/app/ShareCompatICS.java b/compat/ics/android/support/v4/app/ShareCompatICS.java
index a6d1e92..f635e73 100644
--- a/compat/ics/android/support/v4/app/ShareCompatICS.java
+++ b/compat/ics/android/support/v4/app/ShareCompatICS.java
@@ -19,13 +19,11 @@
 import android.app.Activity;
 import android.content.Intent;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.ActionProvider;
 import android.view.MenuItem;
 import android.widget.ShareActionProvider;
 
 @RequiresApi(14)
-@TargetApi(14)
 class ShareCompatICS {
     private static final String HISTORY_FILENAME_PREFIX = ".sharecompat_";
 
diff --git a/compat/ics/android/support/v4/net/TrafficStatsCompatIcs.java b/compat/ics/android/support/v4/net/TrafficStatsCompatIcs.java
index 724c34e..4066386 100644
--- a/compat/ics/android/support/v4/net/TrafficStatsCompatIcs.java
+++ b/compat/ics/android/support/v4/net/TrafficStatsCompatIcs.java
@@ -19,7 +19,6 @@
 import android.net.TrafficStats;
 import android.os.ParcelFileDescriptor;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import java.net.DatagramSocket;
 import java.net.Socket;
@@ -30,7 +29,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class TrafficStatsCompatIcs {
     public static void clearThreadStatsTag() {
         TrafficStats.clearThreadStatsTag();
diff --git a/compat/ics/android/support/v4/text/ICUCompatIcs.java b/compat/ics/android/support/v4/text/ICUCompatIcs.java
index 4baafd6..cd773b5 100644
--- a/compat/ics/android/support/v4/text/ICUCompatIcs.java
+++ b/compat/ics/android/support/v4/text/ICUCompatIcs.java
@@ -17,7 +17,6 @@
 package android.support.v4.text;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.Log;
 
 import java.lang.reflect.InvocationTargetException;
@@ -25,7 +24,6 @@
 import java.util.Locale;
 
 @RequiresApi(14)
-@TargetApi(14)
 class ICUCompatIcs {
 
     private static final String TAG = "ICUCompatIcs";
diff --git a/compat/ics/android/support/v4/view/AccessibilityDelegateCompatIcs.java b/compat/ics/android/support/v4/view/AccessibilityDelegateCompatIcs.java
index fee33d7..0b3496b 100644
--- a/compat/ics/android/support/v4/view/AccessibilityDelegateCompatIcs.java
+++ b/compat/ics/android/support/v4/view/AccessibilityDelegateCompatIcs.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.View.AccessibilityDelegate;
 import android.view.ViewGroup;
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class AccessibilityDelegateCompatIcs {
 
     public interface AccessibilityDelegateBridge {
diff --git a/compat/ics/android/support/v4/view/MenuItemCompatIcs.java b/compat/ics/android/support/v4/view/MenuItemCompatIcs.java
index 4dbea9a..06c5818 100644
--- a/compat/ics/android/support/v4/view/MenuItemCompatIcs.java
+++ b/compat/ics/android/support/v4/view/MenuItemCompatIcs.java
@@ -18,11 +18,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.MenuItem;
 
 @RequiresApi(14)
-@TargetApi(14)
 class MenuItemCompatIcs {
     public static boolean expandActionView(MenuItem item) {
         return item.expandActionView();
diff --git a/compat/ics/android/support/v4/view/MotionEventCompatICS.java b/compat/ics/android/support/v4/view/MotionEventCompatICS.java
index e8f9d49..986bab7 100644
--- a/compat/ics/android/support/v4/view/MotionEventCompatICS.java
+++ b/compat/ics/android/support/v4/view/MotionEventCompatICS.java
@@ -17,11 +17,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.MotionEvent;
 
 @RequiresApi(14)
-@TargetApi(14)
 class MotionEventCompatICS {
     public static int getButtonState(MotionEvent event) {
         return event.getButtonState();
diff --git a/compat/ics/android/support/v4/view/ViewCompatICS.java b/compat/ics/android/support/v4/view/ViewCompatICS.java
index 338b009..420ae18 100644
--- a/compat/ics/android/support/v4/view/ViewCompatICS.java
+++ b/compat/ics/android/support/v4/view/ViewCompatICS.java
@@ -18,7 +18,6 @@
 
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.View.AccessibilityDelegate;
 import android.view.accessibility.AccessibilityEvent;
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class ViewCompatICS {
 
     public static boolean canScrollHorizontally(View v, int direction) {
diff --git a/compat/ics/android/support/v4/view/ViewConfigurationCompatICS.java b/compat/ics/android/support/v4/view/ViewConfigurationCompatICS.java
index 19a7174..1667439 100644
--- a/compat/ics/android/support/v4/view/ViewConfigurationCompatICS.java
+++ b/compat/ics/android/support/v4/view/ViewConfigurationCompatICS.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.ViewConfiguration;
 
 /**
@@ -25,7 +24,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class ViewConfigurationCompatICS {
     static boolean hasPermanentMenuKey(ViewConfiguration config) {
         return config.hasPermanentMenuKey();
diff --git a/compat/ics/android/support/v4/view/ViewGroupCompatIcs.java b/compat/ics/android/support/v4/view/ViewGroupCompatIcs.java
index bb03e7d..d2a0237 100644
--- a/compat/ics/android/support/v4/view/ViewGroupCompatIcs.java
+++ b/compat/ics/android/support/v4/view/ViewGroupCompatIcs.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
@@ -27,7 +26,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class ViewGroupCompatIcs {
     public static boolean onRequestSendAccessibilityEvent(ViewGroup group, View child,
             AccessibilityEvent event) {
diff --git a/compat/ics/android/support/v4/view/ViewParentCompatICS.java b/compat/ics/android/support/v4/view/ViewParentCompatICS.java
index 693aa40..69fefb5 100644
--- a/compat/ics/android/support/v4/view/ViewParentCompatICS.java
+++ b/compat/ics/android/support/v4/view/ViewParentCompatICS.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.ViewParent;
 import android.view.accessibility.AccessibilityEvent;
@@ -27,7 +26,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class ViewParentCompatICS {
     public static boolean requestSendAccessibilityEvent(
             ViewParent parent, View child, AccessibilityEvent event) {
diff --git a/compat/ics/android/support/v4/view/ViewPropertyAnimatorCompatICS.java b/compat/ics/android/support/v4/view/ViewPropertyAnimatorCompatICS.java
index 9cc5583..a9e4f0e 100644
--- a/compat/ics/android/support/v4/view/ViewPropertyAnimatorCompatICS.java
+++ b/compat/ics/android/support/v4/view/ViewPropertyAnimatorCompatICS.java
@@ -18,12 +18,10 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.animation.Interpolator;
 
 @RequiresApi(14)
-@TargetApi(14)
 class ViewPropertyAnimatorCompatICS {
 
     public static void setDuration(View view, long value) {
diff --git a/compat/ics/android/support/v4/view/accessibility/AccessibilityEventCompatIcs.java b/compat/ics/android/support/v4/view/accessibility/AccessibilityEventCompatIcs.java
index 0d5196f..b2cb068 100644
--- a/compat/ics/android/support/v4/view/accessibility/AccessibilityEventCompatIcs.java
+++ b/compat/ics/android/support/v4/view/accessibility/AccessibilityEventCompatIcs.java
@@ -17,7 +17,6 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityRecord;
 
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class AccessibilityEventCompatIcs {
 
     public static int getRecordCount(AccessibilityEvent event) {
diff --git a/compat/ics/android/support/v4/view/accessibility/AccessibilityManagerCompatIcs.java b/compat/ics/android/support/v4/view/accessibility/AccessibilityManagerCompatIcs.java
index 4af6aa3..62cabea 100644
--- a/compat/ics/android/support/v4/view/accessibility/AccessibilityManagerCompatIcs.java
+++ b/compat/ics/android/support/v4/view/accessibility/AccessibilityManagerCompatIcs.java
@@ -18,7 +18,6 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
 
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class AccessibilityManagerCompatIcs {
 
     public static class AccessibilityStateChangeListenerWrapper
diff --git a/compat/ics/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatIcs.java b/compat/ics/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatIcs.java
index 51faa89..6e3ac90 100644
--- a/compat/ics/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatIcs.java
+++ b/compat/ics/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatIcs.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.view.accessibility;
 
-import android.annotation.TargetApi;
 import android.graphics.Rect;
 import android.support.annotation.RequiresApi;
 import android.view.View;
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class AccessibilityNodeInfoCompatIcs {
     public static Object obtain() {
         return AccessibilityNodeInfo.obtain();
diff --git a/compat/ics/android/support/v4/view/accessibility/AccessibilityRecordCompatIcs.java b/compat/ics/android/support/v4/view/accessibility/AccessibilityRecordCompatIcs.java
index f6e078f..9225ff7 100644
--- a/compat/ics/android/support/v4/view/accessibility/AccessibilityRecordCompatIcs.java
+++ b/compat/ics/android/support/v4/view/accessibility/AccessibilityRecordCompatIcs.java
@@ -18,7 +18,6 @@
 
 import android.os.Parcelable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.accessibility.AccessibilityRecord;
 
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class AccessibilityRecordCompatIcs {
 
     public static Object obtain() {
diff --git a/compat/ics/android/support/v4/widget/EdgeEffectCompatIcs.java b/compat/ics/android/support/v4/widget/EdgeEffectCompatIcs.java
index 1f75b4a..05e3e80 100644
--- a/compat/ics/android/support/v4/widget/EdgeEffectCompatIcs.java
+++ b/compat/ics/android/support/v4/widget/EdgeEffectCompatIcs.java
@@ -18,7 +18,6 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.EdgeEffect;
 
 /**
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class EdgeEffectCompatIcs {
     public static Object newEdgeEffect(Context context) {
         return new EdgeEffect(context);
diff --git a/compat/ics/android/support/v4/widget/ScrollerCompatIcs.java b/compat/ics/android/support/v4/widget/ScrollerCompatIcs.java
index be7a07e..cce00c6 100644
--- a/compat/ics/android/support/v4/widget/ScrollerCompatIcs.java
+++ b/compat/ics/android/support/v4/widget/ScrollerCompatIcs.java
@@ -17,7 +17,6 @@
 package android.support.v4.widget;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.OverScroller;
 
 /**
@@ -25,7 +24,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class ScrollerCompatIcs {
     public static float getCurrVelocity(Object scroller) {
         return ((OverScroller) scroller).getCurrVelocity();
diff --git a/compat/ics/android/support/v4/widget/SearchViewCompatIcs.java b/compat/ics/android/support/v4/widget/SearchViewCompatIcs.java
index 3938081..bf5c44e 100644
--- a/compat/ics/android/support/v4/widget/SearchViewCompatIcs.java
+++ b/compat/ics/android/support/v4/widget/SearchViewCompatIcs.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.widget.SearchView;
 
@@ -27,7 +26,6 @@
  */
 
 @RequiresApi(14)
-@TargetApi(14)
 class SearchViewCompatIcs {
 
     public static class MySearchView extends SearchView {
diff --git a/compat/java/android/support/v4/animation/AnimatorCompatHelper.java b/compat/java/android/support/v4/animation/AnimatorCompatHelper.java
deleted file mode 100644
index 46b5b15..0000000
--- a/compat/java/android/support/v4/animation/AnimatorCompatHelper.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.animation;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.os.Build;
-import android.support.annotation.RestrictTo;
-import android.view.View;
-
-/**
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-public final class AnimatorCompatHelper {
-
-    private final static AnimatorProvider IMPL;
-
-    static {
-        if (Build.VERSION.SDK_INT >= 12) {
-            IMPL = new HoneycombMr1AnimatorCompatProvider();
-        } else {
-            IMPL = new GingerbreadAnimatorCompatProvider();
-        }
-    }
-
-    public static ValueAnimatorCompat emptyValueAnimator() {
-        return IMPL.emptyValueAnimator();
-    }
-
-    private AnimatorCompatHelper() {}
-
-    public static void clearInterpolator(View view) {
-        IMPL.clearInterpolator(view);
-    }
-}
diff --git a/compat/java/android/support/v4/app/ActivityOptionsCompat.java b/compat/java/android/support/v4/app/ActivityOptionsCompat.java
index 57ca1a4..3abe044 100644
--- a/compat/java/android/support/v4/app/ActivityOptionsCompat.java
+++ b/compat/java/android/support/v4/app/ActivityOptionsCompat.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -309,7 +308,6 @@
     }
 
     @RequiresApi(16)
-    @TargetApi(16)
     private static class ActivityOptionsImplJB extends ActivityOptionsCompat {
         private final ActivityOptionsCompatJB mImpl;
 
@@ -332,7 +330,6 @@
     }
 
     @RequiresApi(21)
-    @TargetApi(21)
     private static class ActivityOptionsImpl21 extends ActivityOptionsCompat {
         private final ActivityOptionsCompat21 mImpl;
 
@@ -356,7 +353,6 @@
     }
 
     @RequiresApi(23)
-    @TargetApi(23)
     private static class ActivityOptionsImpl23 extends ActivityOptionsCompat {
         private final ActivityOptionsCompat23 mImpl;
 
@@ -385,7 +381,6 @@
     }
 
     @RequiresApi(24)
-    @TargetApi(24)
     private static class ActivityOptionsImpl24 extends ActivityOptionsCompat {
         private final ActivityOptionsCompat24 mImpl;
 
diff --git a/compat/java/android/support/v4/app/AlarmManagerCompat.java b/compat/java/android/support/v4/app/AlarmManagerCompat.java
new file mode 100644
index 0000000..3fd7931
--- /dev/null
+++ b/compat/java/android/support/v4/app/AlarmManagerCompat.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.app;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.os.Build;
+
+/**
+ * Compatibility library for {@link AlarmManager} with fallbacks for older platforms.
+ */
+public final class AlarmManagerCompat {
+    /**
+     * Schedule an alarm that represents an alarm clock.
+     *
+     * The system may choose to display information about this alarm to the user.
+     *
+     * <p>
+     * This method is like {@link #setExact}, but implies
+     * {@link AlarmManager#RTC_WAKEUP}.
+     *
+     * @param alarmManager AlarmManager instance used to set the alarm
+     * @param triggerTime time at which the underlying alarm is triggered in wall time
+     *                    milliseconds since the epoch
+     * @param showIntent an intent that can be used to show or edit details of
+     *                    the alarm clock.
+     * @param operation Action to perform when the alarm goes off;
+     *        typically comes from {@link PendingIntent#getBroadcast
+     *        IntentSender.getBroadcast()}.
+     *
+     * @see AlarmManager#set
+     * @see AlarmManager#setRepeating
+     * @see AlarmManager#setWindow
+     * @see #setExact
+     * @see AlarmManager#cancel
+     * @see AlarmManager#getNextAlarmClock()
+     * @see android.content.Context#sendBroadcast
+     * @see android.content.Context#registerReceiver
+     * @see android.content.Intent#filterEquals
+     */
+    public static void setAlarmClock(AlarmManager alarmManager, long triggerTime,
+            PendingIntent showIntent, PendingIntent operation) {
+        if (Build.VERSION.SDK_INT >= 21) {
+            AlarmManagerCompatApi21.setAlarmClock(alarmManager, triggerTime, showIntent,
+                    operation);
+        } else {
+            AlarmManagerCompat.setExact(alarmManager, AlarmManager.RTC_WAKEUP, triggerTime,
+                    operation);
+        }
+    }
+
+    /**
+     * Like {@link AlarmManager#set(int, long, PendingIntent)}, but this alarm will be allowed to
+     * execute even when the system is in low-power idle modes.  This type of alarm must <b>only</b>
+     * be used for situations where it is actually required that the alarm go off while in
+     * idle -- a reasonable example would be for a calendar notification that should make a
+     * sound so the user is aware of it.  When the alarm is dispatched, the app will also be
+     * added to the system's temporary whitelist for approximately 10 seconds to allow that
+     * application to acquire further wake locks in which to complete its work.</p>
+     *
+     * <p>These alarms can significantly impact the power use
+     * of the device when idle (and thus cause significant battery blame to the app scheduling
+     * them), so they should be used with care.  To reduce abuse, there are restrictions on how
+     * frequently these alarms will go off for a particular application.
+     * Under normal system operation, it will not dispatch these
+     * alarms more than about every minute (at which point every such pending alarm is
+     * dispatched); when in low-power idle modes this duration may be significantly longer,
+     * such as 15 minutes.</p>
+     *
+     * <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen
+     * out of order with any other alarms, even those from the same app.  This will clearly happen
+     * when the device is idle (since this alarm can go off while idle, when any other alarms
+     * from the app will be held until later), but may also happen even when not idle.</p>
+     *
+     * <p>Regardless of the app's target SDK version, this call always allows batching of the
+     * alarm.</p>
+     *
+     * @param alarmManager AlarmManager instance used to set the alarm
+     * @param type One of {@link AlarmManager#ELAPSED_REALTIME},
+     *        {@link AlarmManager#ELAPSED_REALTIME_WAKEUP},
+     *        {@link AlarmManager#RTC}, or {@link AlarmManager#RTC_WAKEUP}.
+     * @param triggerAtMillis time in milliseconds that the alarm should go
+     * off, using the appropriate clock (depending on the alarm type).
+     * @param operation Action to perform when the alarm goes off;
+     * typically comes from {@link PendingIntent#getBroadcast
+     * IntentSender.getBroadcast()}.
+     *
+     * @see AlarmManager#set(int, long, PendingIntent)
+     * @see #setExactAndAllowWhileIdle
+     * @see AlarmManager#cancel
+     * @see android.content.Context#sendBroadcast
+     * @see android.content.Context#registerReceiver
+     * @see android.content.Intent#filterEquals
+     * @see AlarmManager#ELAPSED_REALTIME
+     * @see AlarmManager#ELAPSED_REALTIME_WAKEUP
+     * @see AlarmManager#RTC
+     * @see AlarmManager#RTC_WAKEUP
+     */
+    public static void setAndAllowWhileIdle(AlarmManager alarmManager, int type,
+            long triggerAtMillis, PendingIntent operation) {
+        if (Build.VERSION.SDK_INT >= 23) {
+            AlarmManagerCompatApi23.setAndAllowWhileIdle(alarmManager, type, triggerAtMillis,
+                    operation);
+        } else {
+            alarmManager.set(type, triggerAtMillis, operation);
+        }
+    }
+
+    /**
+     * Schedule an alarm to be delivered precisely at the stated time.
+     *
+     * <p>
+     * This method is like {@link AlarmManager#set(int, long, PendingIntent)}, but does not permit
+     * the OS to adjust the delivery time.  The alarm will be delivered as nearly as
+     * possible to the requested trigger time.
+     *
+     * <p>
+     * <b>Note:</b> only alarms for which there is a strong demand for exact-time
+     * delivery (such as an alarm clock ringing at the requested time) should be
+     * scheduled as exact.  Applications are strongly discouraged from using exact
+     * alarms unnecessarily as they reduce the OS's ability to minimize battery use.
+     *
+     * @param alarmManager AlarmManager instance used to set the alarm
+     * @param type One of {@link AlarmManager#ELAPSED_REALTIME},
+     *        {@link AlarmManager#ELAPSED_REALTIME_WAKEUP},
+     *        {@link AlarmManager#RTC}, or {@link AlarmManager#RTC_WAKEUP}.
+     * @param triggerAtMillis time in milliseconds that the alarm should go
+     *        off, using the appropriate clock (depending on the alarm type).
+     * @param operation Action to perform when the alarm goes off;
+     *        typically comes from {@link PendingIntent#getBroadcast
+     *        IntentSender.getBroadcast()}.
+     *
+     * @see AlarmManager#set
+     * @see AlarmManager#setRepeating
+     * @see AlarmManager#setWindow
+     * @see AlarmManager#cancel
+     * @see android.content.Context#sendBroadcast
+     * @see android.content.Context#registerReceiver
+     * @see android.content.Intent#filterEquals
+     * @see AlarmManager#ELAPSED_REALTIME
+     * @see AlarmManager#ELAPSED_REALTIME_WAKEUP
+     * @see AlarmManager#RTC
+     * @see AlarmManager#RTC_WAKEUP
+     */
+    public static void setExact(AlarmManager alarmManager, int type, long triggerAtMillis,
+            PendingIntent operation) {
+        if (Build.VERSION.SDK_INT >= 19) {
+            AlarmManagerCompatKitKat.setExact(alarmManager, type, triggerAtMillis, operation);
+        } else {
+            alarmManager.set(type, triggerAtMillis, operation);
+        }
+    }
+
+    /**
+     * Like {@link #setExact}, but this alarm will be allowed to execute
+     * even when the system is in low-power idle modes.  If you don't need exact scheduling of
+     * the alarm but still need to execute while idle, consider using
+     * {@link #setAndAllowWhileIdle}.  This type of alarm must <b>only</b>
+     * be used for situations where it is actually required that the alarm go off while in
+     * idle -- a reasonable example would be for a calendar notification that should make a
+     * sound so the user is aware of it.  When the alarm is dispatched, the app will also be
+     * added to the system's temporary whitelist for approximately 10 seconds to allow that
+     * application to acquire further wake locks in which to complete its work.</p>
+     *
+     * <p>These alarms can significantly impact the power use
+     * of the device when idle (and thus cause significant battery blame to the app scheduling
+     * them), so they should be used with care.  To reduce abuse, there are restrictions on how
+     * frequently these alarms will go off for a particular application.
+     * Under normal system operation, it will not dispatch these
+     * alarms more than about every minute (at which point every such pending alarm is
+     * dispatched); when in low-power idle modes this duration may be significantly longer,
+     * such as 15 minutes.</p>
+     *
+     * <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen
+     * out of order with any other alarms, even those from the same app.  This will clearly happen
+     * when the device is idle (since this alarm can go off while idle, when any other alarms
+     * from the app will be held until later), but may also happen even when not idle.
+     * Note that the OS will allow itself more flexibility for scheduling these alarms than
+     * regular exact alarms, since the application has opted into this behavior.  When the
+     * device is idle it may take even more liberties with scheduling in order to optimize
+     * for battery life.</p>
+     *
+     * @param alarmManager AlarmManager instance used to set the alarm
+     * @param type One of {@link AlarmManager#ELAPSED_REALTIME},
+     *        {@link AlarmManager#ELAPSED_REALTIME_WAKEUP},
+     *        {@link AlarmManager#RTC}, or {@link AlarmManager#RTC_WAKEUP}.
+     * @param triggerAtMillis time in milliseconds that the alarm should go
+     *        off, using the appropriate clock (depending on the alarm type).
+     * @param operation Action to perform when the alarm goes off;
+     *        typically comes from {@link PendingIntent#getBroadcast
+     *        IntentSender.getBroadcast()}.
+     *
+     * @see AlarmManager#set
+     * @see AlarmManager#setRepeating
+     * @see AlarmManager#setWindow
+     * @see AlarmManager#cancel
+     * @see android.content.Context#sendBroadcast
+     * @see android.content.Context#registerReceiver
+     * @see android.content.Intent#filterEquals
+     * @see AlarmManager#ELAPSED_REALTIME
+     * @see AlarmManager#ELAPSED_REALTIME_WAKEUP
+     * @see AlarmManager#RTC
+     * @see AlarmManager#RTC_WAKEUP
+     */
+    public static void setExactAndAllowWhileIdle(AlarmManager alarmManager, int type,
+            long triggerAtMillis, PendingIntent operation) {
+        if (Build.VERSION.SDK_INT >= 23) {
+            AlarmManagerCompatApi23.setExactAndAllowWhileIdle(alarmManager, type, triggerAtMillis,
+                    operation);
+        } else {
+            AlarmManagerCompat.setExact(alarmManager, type, triggerAtMillis, operation);
+        }
+    }
+
+    private AlarmManagerCompat() {
+    }
+}
diff --git a/compat/java/android/support/v4/app/NotificationCompat.java b/compat/java/android/support/v4/app/NotificationCompat.java
index 5d08191..2683300 100644
--- a/compat/java/android/support/v4/app/NotificationCompat.java
+++ b/compat/java/android/support/v4/app/NotificationCompat.java
@@ -33,6 +33,7 @@
 import android.support.annotation.ColorInt;
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
 import android.support.v4.os.BuildCompat;
 import android.support.v4.view.GravityCompat;
@@ -385,6 +386,32 @@
     public static final String EXTRA_MESSAGES = "android.messages";
 
     /**
+     * Keys into the {@link #getExtras} Bundle: the audio contents of this notification.
+     *
+     * This is for use when rendering the notification on an audio-focused interface;
+     * the audio contents are a complete sound sample that contains the contents/body of the
+     * notification. This may be used in substitute of a Text-to-Speech reading of the
+     * notification. For example if the notification represents a voice message this should point
+     * to the audio of that message.
+     *
+     * The data stored under this key should be a String representation of a Uri that contains the
+     * audio contents in one of the following formats: WAV, PCM 16-bit, AMR-WB.
+     *
+     * This extra is unnecessary if you are using {@code MessagingStyle} since each {@code Message}
+     * has a field for holding data URI. That field can be used for audio.
+     * See {@code Message#setData}.
+     *
+     * Example usage:
+     * <pre>
+     * {@code
+     * NotificationCompat.Builder myBuilder = (build your Notification as normal);
+     * myBuilder.getExtras().putString(EXTRA_AUDIO_CONTENTS_URI, myAudioUri.toString());
+     * }
+     * </pre>
+     */
+    public static final String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
+
+    /**
      * Value of {@link Notification#color} equal to 0 (also known as
      * {@link android.graphics.Color#TRANSPARENT Color.TRANSPARENT}),
      * telling the system not to decorate this notification with any special color but instead use
@@ -515,6 +542,7 @@
         NotificationCompatBase.UnreadConversation getUnreadConversationFromBundle(
                 Bundle b, NotificationCompatBase.UnreadConversation.Factory factory,
                 RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory);
+        String getChannel(Notification n);
     }
 
     /**
@@ -611,6 +639,11 @@
                 RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
             return null;
         }
+
+        @Override
+        public String getChannel(Notification n) {
+            return null;
+        }
     }
 
     static class NotificationCompatImplHoneycomb extends NotificationCompatImplBase {
@@ -638,6 +671,7 @@
         }
     }
 
+    @RequiresApi(16)
     static class NotificationCompatImplJellybean extends NotificationCompatImplBase {
         @Override
         public Notification build(Builder b, BuilderExtender extender) {
@@ -709,6 +743,7 @@
         }
     }
 
+    @RequiresApi(19)
     static class NotificationCompatImplKitKat extends NotificationCompatImplJellybean {
         @Override
         public Notification build(Builder b, BuilderExtender extender) {
@@ -761,6 +796,7 @@
         }
     }
 
+    @RequiresApi(20)
     static class NotificationCompatImplApi20 extends NotificationCompatImplKitKat {
         @Override
         public Notification build(Builder b, BuilderExtender extender) {
@@ -819,6 +855,7 @@
         }
     }
 
+    @RequiresApi(21)
     static class NotificationCompatImplApi21 extends NotificationCompatImplApi20 {
         @Override
         public Notification build(Builder b, BuilderExtender extender) {
@@ -858,6 +895,7 @@
         }
     }
 
+    @RequiresApi(24)
     static class NotificationCompatImplApi24 extends NotificationCompatImplApi21 {
         @Override
         public Notification build(Builder b,
@@ -880,6 +918,34 @@
         }
     }
 
+    @RequiresApi(26)
+    static class NotificationCompatImplApi26 extends NotificationCompatImplApi24 {
+        @Override
+        public Notification build(Builder b,
+                                  BuilderExtender extender) {
+            NotificationCompatApi26.Builder builder = new NotificationCompatApi26.Builder(
+                    b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
+                    b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
+                    b.mProgressMax, b.mProgress, b.mProgressIndeterminate, b.mShowWhen,
+                    b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mCategory,
+                    b.mPeople, b.mExtras, b.mColor, b.mVisibility, b.mPublicVersion,
+                    b.mGroupKey, b.mGroupSummary, b.mSortKey, b.mRemoteInputHistory, b.mContentView,
+                    b.mBigContentView, b.mHeadsUpContentView, b.mChannelId);
+            addActionsToBuilder(builder, b.mActions);
+            addStyleToBuilderApi24(builder, b.mStyle);
+            Notification notification = extender.build(b, builder);
+            if (b.mStyle != null) {
+                b.mStyle.addCompatExtras(getExtras(notification));
+            }
+            return notification;
+        }
+
+        @Override
+        public String getChannel(Notification n) {
+            return NotificationCompatApi26.getChannel(n);
+        }
+    }
+
     static void addActionsToBuilder(NotificationBuilderWithActions builder,
             ArrayList<Action> actions) {
         for (Action action : actions) {
@@ -887,6 +953,7 @@
         }
     }
 
+    @RequiresApi(16)
     static void addStyleToBuilderJellybean(NotificationBuilderWithBuilderAccessor builder,
             Style style) {
         if (style != null) {
@@ -917,6 +984,7 @@
         }
     }
 
+    @RequiresApi(24)
     static void addStyleToBuilderApi24(NotificationBuilderWithBuilderAccessor builder,
             Style style) {
         if (style != null) {
@@ -945,7 +1013,9 @@
     }
 
     static {
-        if (BuildCompat.isAtLeastN()) {
+        if (BuildCompat.isAtLeastO()) {
+            IMPL = new NotificationCompatImplApi26();
+        } else if (Build.VERSION.SDK_INT >= 24) {
             IMPL = new NotificationCompatImplApi24();
         } else if (Build.VERSION.SDK_INT >= 21) {
             IMPL = new NotificationCompatImplApi21();
@@ -1050,6 +1120,7 @@
         RemoteViews mContentView;
         RemoteViews mBigContentView;
         RemoteViews mHeadsUpContentView;
+        String mChannelId;
 
         /** @hide */
         @RestrictTo(LIBRARY_GROUP)
@@ -1728,6 +1799,16 @@
         }
 
         /**
+         * Specifies the channel the notification should be delivered on.
+         *
+         * No-op on versions prior to {@link android.os.Build.VERSION_CODES#O} .
+         */
+        public Builder setChannel(String channelId) {
+            mChannelId = channelId;
+            return this;
+        }
+
+        /**
          * Apply an extender to this notification builder. Extenders may be used to add
          * metadata or change options on this builder.
          */
@@ -2432,6 +2513,19 @@
     public static class Action extends NotificationCompatBase.Action {
         final Bundle mExtras;
         private final RemoteInput[] mRemoteInputs;
+
+        /**
+         * Holds {@link RemoteInput}s that only accept data, meaning
+         * {@link RemoteInput#getAllowFreeFormInput} is false, {@link RemoteInput#getChoices}
+         * is null or empty, and {@link RemoteInput#getAllowedDataTypes is non-null and not
+         * empty. These {@link RemoteInput}s will be ignored by devices that do not
+         * support non-text-based {@link RemoteInput}s. See {@link Builder#build}.
+         *
+         * You can test if a RemoteInput matches these constraints using
+         * {@link RemoteInput#isDataOnly}.
+         */
+        private final RemoteInput[] mDataOnlyRemoteInputs;
+
         private boolean mAllowGeneratedReplies;
 
         /**
@@ -2449,16 +2543,18 @@
         public PendingIntent actionIntent;
 
         public Action(int icon, CharSequence title, PendingIntent intent) {
-            this(icon, title, intent, new Bundle(), null, true);
+            this(icon, title, intent, new Bundle(), null, null, true);
         }
 
         Action(int icon, CharSequence title, PendingIntent intent, Bundle extras,
-                RemoteInput[] remoteInputs, boolean allowGeneratedReplies) {
+                RemoteInput[] remoteInputs, RemoteInput[] dataOnlyRemoteInputs,
+                boolean allowGeneratedReplies) {
             this.icon = icon;
             this.title = NotificationCompat.Builder.limitCharSequenceLength(title);
             this.actionIntent = intent;
             this.mExtras = extras != null ? extras : new Bundle();
             this.mRemoteInputs = remoteInputs;
+            this.mDataOnlyRemoteInputs = dataOnlyRemoteInputs;
             this.mAllowGeneratedReplies = allowGeneratedReplies;
         }
 
@@ -2496,7 +2592,8 @@
 
         /**
          * Get the list of inputs to be collected from the user when this action is sent.
-         * May return null if no remote inputs were added.
+         * May return null if no remote inputs were added. Only returns inputs which accept
+         * a text input. For inputs which only accept data use {@link #getDataOnlyRemoteInputs}.
          */
         @Override
         public RemoteInput[] getRemoteInputs() {
@@ -2504,6 +2601,21 @@
         }
 
         /**
+         * Get the list of inputs to be collected from the user that ONLY accept data when this
+         * action is sent. These remote inputs are guaranteed to return true on a call to
+         * {@link RemoteInput#isDataOnly}.
+         *
+         * <p>May return null if no data-only remote inputs were added.
+         *
+         * <p>This method exists so that legacy RemoteInput collectors that pre-date the addition
+         * of non-textual RemoteInputs do not access these remote inputs.
+         */
+        @Override
+        public RemoteInput[] getDataOnlyRemoteInputs() {
+            return mDataOnlyRemoteInputs;
+        }
+
+        /**
          * Builder class for {@link Action} objects.
          */
         public static final class Builder {
@@ -2612,10 +2724,23 @@
              * @return the built action
              */
             public Action build() {
-                RemoteInput[] remoteInputs = mRemoteInputs != null
-                        ? mRemoteInputs.toArray(new RemoteInput[mRemoteInputs.size()]) : null;
-                return new Action(mIcon, mTitle, mIntent, mExtras, remoteInputs,
-                        mAllowGeneratedReplies);
+                List<RemoteInput> dataOnlyInputs = new ArrayList<>();
+                List<RemoteInput> textInputs = new ArrayList<>();
+                if (mRemoteInputs != null) {
+                    for (RemoteInput input : mRemoteInputs) {
+                        if (input.isDataOnly()) {
+                            dataOnlyInputs.add(input);
+                        } else {
+                            textInputs.add(input);
+                        }
+                    }
+                }
+                RemoteInput[] dataOnlyInputsArr = dataOnlyInputs.isEmpty()
+                        ? null : dataOnlyInputs.toArray(new RemoteInput[dataOnlyInputs.size()]);
+                RemoteInput[] textInputsArr = textInputs.isEmpty()
+                        ? null : textInputs.toArray(new RemoteInput[textInputs.size()]);
+                return new Action(mIcon, mTitle, mIntent, mExtras, textInputsArr,
+                        dataOnlyInputsArr, mAllowGeneratedReplies);
             }
         }
 
@@ -2883,9 +3008,11 @@
             public NotificationCompatBase.Action build(int icon, CharSequence title,
                     PendingIntent actionIntent, Bundle extras,
                     RemoteInputCompatBase.RemoteInput[] remoteInputs,
+                    RemoteInputCompatBase.RemoteInput[] dataOnlyRemoteInputs,
                     boolean allowGeneratedReplies) {
                 return new Action(icon, title, actionIntent, extras,
-                        (RemoteInput[]) remoteInputs, allowGeneratedReplies);
+                        (RemoteInput[]) remoteInputs, (RemoteInput[]) dataOnlyRemoteInputs,
+                        allowGeneratedReplies);
             }
 
             @Override
@@ -4175,4 +4302,11 @@
     public static String getSortKey(Notification notif) {
         return IMPL.getSortKey(notif);
     }
+
+    /**
+     * @return the ID of the channel this notification posts to.
+     */
+    public static String getChannel(Notification n) {
+        return IMPL.getChannel(n);
+    }
 }
diff --git a/compat/java/android/support/v4/app/RemoteInput.java b/compat/java/android/support/v4/app/RemoteInput.java
index 1f69520..2bf2f28 100644
--- a/compat/java/android/support/v4/app/RemoteInput.java
+++ b/compat/java/android/support/v4/app/RemoteInput.java
@@ -19,14 +19,18 @@
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.support.annotation.RestrictTo;
 import android.util.Log;
 
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
 /**
- * Helper for using the {@link android.app.RemoteInput} API
- * introduced after API level 4 in a backwards compatible fashion.
+ * Helper for using the {@link android.app.RemoteInput} API in a backwards compatible fashion.
  */
 public final class RemoteInput extends RemoteInputCompatBase.RemoteInput {
     private static final String TAG = "RemoteInput";
@@ -34,22 +38,28 @@
     /** Label used to denote the clip data type used for remote input transport */
     public static final String RESULTS_CLIP_LABEL = RemoteInputCompatJellybean.RESULTS_CLIP_LABEL;
 
-    /** Extra added to a clip data intent object to hold the results bundle. */
-    public static final String EXTRA_RESULTS_DATA = RemoteInputCompatJellybean.EXTRA_RESULTS_DATA;
+    /** Extra added to a clip data intent object to hold the text results bundle. */
+    public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+
+    /** Extra added to a clip data intent object to hold the data results bundle. */
+    private static final String EXTRA_DATA_TYPE_RESULTS_DATA =
+            "android.remoteinput.dataTypeResultsData";
 
     private final String mResultKey;
     private final CharSequence mLabel;
     private final CharSequence[] mChoices;
-    private final boolean mAllowFreeFormInput;
+    private final boolean mAllowFreeFormTextInput;
     private final Bundle mExtras;
+    private final Set<String> mAllowedDataTypes;
 
     RemoteInput(String resultKey, CharSequence label, CharSequence[] choices,
-            boolean allowFreeFormInput, Bundle extras) {
+            boolean allowFreeFormTextInput, Bundle extras, Set<String> allowedDataTypes) {
         this.mResultKey = resultKey;
         this.mLabel = label;
         this.mChoices = choices;
-        this.mAllowFreeFormInput = allowFreeFormInput;
+        this.mAllowFreeFormTextInput = allowFreeFormTextInput;
         this.mExtras = extras;
+        this.mAllowedDataTypes = allowedDataTypes;
     }
 
     /**
@@ -77,6 +87,22 @@
         return mChoices;
     }
 
+    public Set<String> getAllowedDataTypes() {
+        return mAllowedDataTypes;
+    }
+
+    /**
+     * Returns true if the input only accepts data, meaning {@link #getAllowFreeFormInput}
+     * is false, {@link #getChoices} is null or empty, and {@link #getAllowedDataTypes is
+     * non-null and not empty.
+     */
+    public boolean isDataOnly() {
+        return !getAllowFreeFormInput()
+                && (getChoices() == null || getChoices().length == 0)
+                && getAllowedDataTypes() != null
+                && !getAllowedDataTypes().isEmpty();
+    }
+
     /**
      * Get whether or not users can provide an arbitrary value for
      * input. If you set this to {@code false}, users must select one of the
@@ -85,7 +111,7 @@
      */
     @Override
     public boolean getAllowFreeFormInput() {
-        return mAllowFreeFormInput;
+        return mAllowFreeFormTextInput;
     }
 
     /**
@@ -103,8 +129,9 @@
         private final String mResultKey;
         private CharSequence mLabel;
         private CharSequence[] mChoices;
-        private boolean mAllowFreeFormInput = true;
+        private boolean mAllowFreeFormTextInput = true;
         private Bundle mExtras = new Bundle();
+        private final Set<String> mAllowedDataTypes = new HashSet<>();
 
         /**
          * Create a builder object for {@link android.support.v4.app.RemoteInput} objects.
@@ -142,14 +169,34 @@
         /**
          * Specifies whether the user can provide arbitrary values.
          *
-         * @param allowFreeFormInput The default is {@code true}.
-         *         If you specify {@code false}, you must provide a non-null
-         *         and non-empty array to {@link #setChoices} or an
+         * @param mimeType A mime type that results are allowed to come in.
+         *         Be aware that text results (see {@link #setAllowFreeFormInput}
+         *         are allowed by default. If you do not want text results you will have to
+         *         pass false to {@code setAllowFreeFormInput}.
+         * @param doAllow Whether the mime type should be allowed or not.
+         * @return this object for method chaining
+         */
+        public Builder setAllowDataType(String mimeType, boolean doAllow) {
+            if (doAllow) {
+                mAllowedDataTypes.add(mimeType);
+            } else {
+                mAllowedDataTypes.remove(mimeType);
+            }
+            return this;
+        }
+
+        /**
+         * Specifies whether the user can provide arbitrary text values.
+         *
+         * @param allowFreeFormTextInput The default is {@code true}.
+         *         If you specify {@code false}, you must either provide a non-null
+         *         and non-empty array to {@link #setChoices}, or enable a data result
+         *         in {@code setAllowDataType}. Otherwise an
          *         {@link IllegalArgumentException} is thrown.
          * @return this object for method chaining
          */
-        public Builder setAllowFreeFormInput(boolean allowFreeFormInput) {
-            mAllowFreeFormInput = allowFreeFormInput;
+        public Builder setAllowFreeFormInput(boolean allowFreeFormTextInput) {
+            mAllowFreeFormTextInput = allowFreeFormTextInput;
             return this;
         }
 
@@ -181,14 +228,42 @@
          * {@link android.support.v4.app.RemoteInput} object.
          */
         public RemoteInput build() {
-            return new RemoteInput(mResultKey, mLabel, mChoices, mAllowFreeFormInput, mExtras);
+            return new RemoteInput(
+                    mResultKey,
+                    mLabel,
+                    mChoices,
+                    mAllowFreeFormTextInput,
+                    mExtras,
+                    mAllowedDataTypes);
         }
     }
 
     /**
-     * Get the remote input results bundle from an intent. The returned Bundle will
+     * Similar as {@link #getResultsFromIntent} but retrieves data results for a
+     * specific RemoteInput result. To retrieve a value use:
+     * <pre>
+     * {@code
+     * Map<String, Uri> results =
+     *     RemoteInput.getDataResultsFromIntent(intent, REMOTE_INPUT_KEY);
+     * if (results != null) {
+     *   Uri data = results.get(MIME_TYPE_OF_INTEREST);
+     * }
+     * }
+     * </pre>
+     * @param intent The intent object that fired in response to an action or content intent
+     *               which also had one or more remote input requested.
+     * @param remoteInputResultKey The result key for the RemoteInput you want results for.
+     */
+    public static Map<String, Uri> getDataResultsFromIntent(
+            Intent intent, String remoteInputResultKey) {
+        return IMPL.getDataResultsFromIntent(intent, remoteInputResultKey);
+    }
+
+    /**
+     * Get the remote input text results bundle from an intent. The returned Bundle will
      * contain a key/value for every result key populated by remote input collector.
-     * Use the {@link Bundle#getCharSequence(String)} method to retrieve a value.
+     * Use the {@link Bundle#getCharSequence(String)} method to retrieve a value. For data results
+     * use {@link #getDataResultsFromIntent}.
      * @param intent The intent object that fired in response to an action or content intent
      *               which also had one or more remote input requested.
      */
@@ -212,12 +287,28 @@
         IMPL.addResultsToIntent(remoteInputs, intent, results);
     }
 
+    /**
+     * Same as {@link #addResultsToIntent} but for setting data results.
+     * @param remoteInput The remote input for which results are being provided
+     * @param intent The intent to add remote input results to. The
+     *               {@link android.content.ClipData} field of the intent will be
+     *               modified to contain the results.
+     * @param results A map of mime type to the Uri result for that mime type.
+     */
+    public static void addDataResultToIntent(RemoteInput remoteInput, Intent intent,
+            Map<String, Uri> results) {
+        IMPL.addDataResultToIntent(remoteInput, intent, results);
+    }
+
     private static final Impl IMPL;
 
     interface Impl {
         Bundle getResultsFromIntent(Intent intent);
+        Map<String, Uri> getDataResultsFromIntent(Intent intent, String remoteInputResultKey);
         void addResultsToIntent(RemoteInput[] remoteInputs, Intent intent,
                 Bundle results);
+        void addDataResultToIntent(RemoteInput remoteInput, Intent intent,
+                Map<String, Uri> results);
     }
 
     static class ImplBase implements Impl {
@@ -228,9 +319,22 @@
         }
 
         @Override
+        public Map<String, Uri> getDataResultsFromIntent(
+                Intent intent, String remoteInputResultKey) {
+            Log.w(TAG, "RemoteInput is only supported from API Level 16");
+            return null;
+        }
+
+        @Override
         public void addResultsToIntent(RemoteInput[] remoteInputs, Intent intent, Bundle results) {
             Log.w(TAG, "RemoteInput is only supported from API Level 16");
         }
+
+        @Override
+        public void addDataResultToIntent(RemoteInput remoteInput, Intent intent,
+                Map<String, Uri> results) {
+            Log.w(TAG, "RemoteInput is only supported from API Level 16");
+        }
     }
 
     static class ImplJellybean implements Impl {
@@ -240,9 +344,22 @@
         }
 
         @Override
+        public Map<String, Uri> getDataResultsFromIntent(
+                Intent intent, String remoteInputResultKey) {
+            return RemoteInputCompatJellybean.getDataResultsFromIntent(
+                    intent, remoteInputResultKey);
+        }
+
+        @Override
         public void addResultsToIntent(RemoteInput[] remoteInputs, Intent intent, Bundle results) {
             RemoteInputCompatJellybean.addResultsToIntent(remoteInputs, intent, results);
         }
+
+        @Override
+        public void addDataResultToIntent(RemoteInput remoteInput, Intent intent,
+                Map<String, Uri> results) {
+            RemoteInputCompatJellybean.addDataResultToIntent(remoteInput, intent, results);
+        }
     }
 
     static class ImplApi20 implements Impl {
@@ -252,9 +369,21 @@
         }
 
         @Override
+        public Map<String, Uri> getDataResultsFromIntent(
+                Intent intent, String remoteInputResultKey) {
+            return RemoteInputCompatApi20.getDataResultsFromIntent(intent, remoteInputResultKey);
+        }
+
+        @Override
         public void addResultsToIntent(RemoteInput[] remoteInputs, Intent intent, Bundle results) {
             RemoteInputCompatApi20.addResultsToIntent(remoteInputs, intent, results);
         }
+
+        @Override
+        public void addDataResultToIntent(RemoteInput remoteInput, Intent intent,
+                Map<String, Uri> results) {
+            RemoteInputCompatApi20.addDataResultToIntent(remoteInput, intent, results);
+        }
     }
 
     static {
@@ -273,8 +402,9 @@
         @Override
         public RemoteInput build(String resultKey,
                 CharSequence label, CharSequence[] choices, boolean allowFreeFormInput,
-                Bundle extras) {
-            return new RemoteInput(resultKey, label, choices, allowFreeFormInput, extras);
+                Bundle extras, Set<String> allowedDataTypes) {
+            return new RemoteInput(
+                    resultKey, label, choices, allowFreeFormInput, extras, allowedDataTypes);
         }
 
         @Override
diff --git a/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java b/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java
new file mode 100644
index 0000000..2fe2e92
--- /dev/null
+++ b/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java
@@ -0,0 +1,211 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.v4.content.pm;
+
+import android.annotation.TargetApi;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+
+/**
+ * Helper for accessing features in {@link android.content.pm.ShortcutInfo}
+ * introduced after API level 25 in a backwards compatible fashion.
+ */
+public class ShortcutInfoCompat {
+
+    private Context mContext;
+    private String mId;
+
+    private Intent[] mIntents;
+    private ComponentName mActivity;
+
+    private CharSequence mLabel;
+    private CharSequence mLongLabel;
+    private CharSequence mDisabledMessage;
+
+    private Bitmap mIconBitmap;
+    private int mIconId;
+
+    private ShortcutInfoCompat() { }
+
+    @TargetApi(25)
+    ShortcutInfo toShortcutInfo() {
+        ShortcutInfo.Builder builder = new ShortcutInfo.Builder(mContext, mId)
+                .setShortLabel(mLabel)
+                .setIntents(mIntents);
+        if (mIconId != 0) {
+            builder.setIcon(Icon.createWithResource(mContext, mIconId));
+        } else if (mIconBitmap != null) {
+            builder.setIcon(Icon.createWithBitmap(mIconBitmap));
+        }
+        if (!TextUtils.isEmpty(mLongLabel)) {
+            builder.setLongLabel(mLongLabel);
+        }
+        if (!TextUtils.isEmpty(mDisabledMessage)) {
+            builder.setDisabledMessage(mDisabledMessage);
+        }
+        if (mActivity != null) {
+            builder.setActivity(mActivity);
+        }
+        return builder.build();
+    }
+
+    Intent addToIntent(Intent outIntent) {
+        outIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, mIntents[mIntents.length - 1])
+                .putExtra(Intent.EXTRA_SHORTCUT_NAME, mLabel.toString());
+        if (mIconId != 0) {
+            outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
+                    Intent.ShortcutIconResource.fromContext(mContext, mIconId));
+        }
+        if (mIconBitmap != null) {
+            outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, mIconBitmap);
+        }
+        return outIntent;
+    }
+
+    /**
+     * Builder class for {@link ShortcutInfoCompat} objects.
+     */
+    public static class Builder {
+
+        private final ShortcutInfoCompat mInfo;
+
+        public Builder(@NonNull Context context, @NonNull String id) {
+            mInfo = new ShortcutInfoCompat();
+            mInfo.mContext = context;
+            mInfo.mId = id;
+        }
+
+        /**
+         * Sets the short title of a shortcut.
+         *
+         * <p>This is a mandatory field when publishing a new shortcut.
+         *
+         * <p>This field is intended to be a concise description of a shortcut.
+         *
+         * <p>The recommended maximum length is 10 characters.
+         */
+        @NonNull
+        public Builder setShortLabel(@NonNull CharSequence shortLabel) {
+            mInfo.mLabel = shortLabel;
+            return this;
+        }
+
+        /**
+         * Sets the text of a shortcut.
+         *
+         * <p>This field is intended to be more descriptive than the shortcut title. The launcher
+         * shows this instead of the short title when it has enough space.
+         *
+         * <p>The recommend maximum length is 25 characters.
+         */
+        @NonNull
+        public Builder setLongLabel(@NonNull CharSequence longLabel) {
+            mInfo.mLongLabel = longLabel;
+            return this;
+        }
+
+        /**
+         * Sets the message that should be shown when the user attempts to start a shortcut that
+         * is disabled.
+         *
+         * @see ShortcutInfo#getDisabledMessage()
+         */
+        @NonNull
+        public Builder setDisabledMessage(@NonNull CharSequence disabledMessage) {
+            mInfo.mDisabledMessage = disabledMessage;
+            return this;
+        }
+
+        /**
+         * Sets the intent of a shortcut.  Alternatively, {@link #setIntents(Intent[])} can be used
+         * to launch an activity with other activities in the back stack.
+         *
+         * <p>This is a mandatory field when publishing a new shortcut.
+         *
+         * <p>The given {@code intent} can contain extras, but these extras must contain values
+         * of primitive types in order for the system to persist these values.
+         */
+        @NonNull
+        public Builder setIntent(@NonNull Intent intent) {
+            return setIntents(new Intent[]{intent});
+        }
+
+        /**
+         * Sets multiple intents instead of a single intent, in order to launch an activity with
+         * other activities in back stack.  Use {@link android.app.TaskStackBuilder} to build
+         * intents. The last element in the list represents the only intent that doesn't place
+         * an activity on the back stack.
+         */
+        @NonNull
+        public Builder setIntents(@NonNull Intent[] intents) {
+            mInfo.mIntents = intents;
+            return this;
+        }
+
+        /**
+         * Sets an icon of a shortcut.
+         */
+        @NonNull
+        public Builder setIcon(@NonNull Bitmap icon) {
+            mInfo.mIconBitmap = icon;
+            return this;
+        }
+
+        /**
+         * Sets an icon of a shortcut.
+         */
+        @NonNull
+        public Builder setIcon(@DrawableRes int icon) {
+            mInfo.mIconId = icon;
+            return this;
+        }
+
+        /**
+         * Sets the target activity. A shortcut will be shown along with this activity's icon
+         * on the launcher.
+         *
+         * @see ShortcutInfo#getActivity()
+         * @see android.content.pm.ShortcutInfo.Builder#setActivity(ComponentName)
+         */
+        @NonNull
+        public Builder setActivity(@NonNull ComponentName activity) {
+            mInfo.mActivity = activity;
+            return this;
+        }
+
+        /**
+         * Sets an icon of a shortcut.
+         */
+        @NonNull
+        public ShortcutInfoCompat build() {
+            // Verify the arguments
+            if (TextUtils.isEmpty(mInfo.mLabel)) {
+                throw new IllegalArgumentException("Shortcut much have a non-empty label");
+            }
+            if (mInfo.mIntents == null || mInfo.mIntents.length == 0) {
+                throw new IllegalArgumentException("Shortcut much have an intent");
+            }
+            return mInfo;
+        }
+    }
+}
diff --git a/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java b/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
new file mode 100644
index 0000000..48d93ca
--- /dev/null
+++ b/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
@@ -0,0 +1,137 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.content.pm;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.os.BuildCompat;
+import android.text.TextUtils;
+
+/**
+ * Helper for accessing features in {@link android.content.pm.ShortcutManager}
+ * in a backwards compatible fashion.
+ */
+public class ShortcutManagerCompat {
+
+    @VisibleForTesting static final String ACTION_INSTALL_SHORTCUT =
+            "com.android.launcher.action.INSTALL_SHORTCUT";
+    @VisibleForTesting static final String INSTALL_SHORTCUT_PERMISSION =
+            "com.android.launcher.permission.INSTALL_SHORTCUT";
+
+    /**
+     * @return {@code true} if the launcher supports {@link #requestPinShortcut},
+     * {@code false} otherwise
+     */
+    public static boolean isRequestPinShortcutSupported(@NonNull Context context) {
+        if (BuildCompat.isAtLeastO()) {
+            return ShortcutManagerCompatApi26.isRequestPinShortcutSupported(context);
+        }
+
+        if (ContextCompat.checkSelfPermission(context, INSTALL_SHORTCUT_PERMISSION)
+                != PackageManager.PERMISSION_GRANTED) {
+            return false;
+        }
+        for (ResolveInfo info : context.getPackageManager().queryBroadcastReceivers(
+                new Intent(ACTION_INSTALL_SHORTCUT), 0)) {
+            String permission = info.activityInfo.permission;
+            if (TextUtils.isEmpty(permission) || INSTALL_SHORTCUT_PERMISSION.equals(permission)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Request to create a pinned shortcut.
+     * <p>On API <= 25 it creates a legacy shortcut with the provided icon, label and intent. For
+     * newer APIs it will create a {@link android.content.pm.ShortcutInfo} object which can be
+     * updated by the app.
+     *
+     * <p>Use {@link android.app.PendingIntent#getIntentSender()} to create a {@link IntentSender}.
+     *
+     * @param shortcut new shortcut to pin
+     * @param callback if not null, this intent will be sent when the shortcut is pinned
+     *
+     * @return {@code true} if the launcher supports this feature
+     *
+     * @see #isRequestPinShortcutSupported
+     * @see IntentSender
+     * @see android.app.PendingIntent#getIntentSender()
+     */
+    public static boolean requestPinShortcut(@NonNull final Context context,
+            @NonNull ShortcutInfoCompat shortcut, @Nullable final IntentSender callback) {
+        if (BuildCompat.isAtLeastO()) {
+            return ShortcutManagerCompatApi26.requestPinShortcut(context, shortcut, callback);
+        }
+
+        if (!isRequestPinShortcutSupported(context)) {
+            return false;
+        }
+        Intent intent = shortcut.addToIntent(new Intent(ACTION_INSTALL_SHORTCUT));
+
+        // If the callback is null, just send the broadcast
+        if (callback == null) {
+            context.sendBroadcast(intent);
+            return true;
+        }
+
+        // Otherwise send the callback when the intent has successfully been dispatched.
+        context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                try {
+                    callback.sendIntent(context, 0, null, null, null);
+                } catch (IntentSender.SendIntentException e) {
+                    // Ignore
+                }
+            }
+        }, null, Activity.RESULT_OK, null, null);
+        return true;
+    }
+
+    /**
+     * Returns an Intent which can be used by the launcher to pin shortcut.
+     * <p>This should be used by an Activity to set result in response to
+     * {@link Intent#ACTION_CREATE_SHORTCUT}.
+     *
+     * @param shortcut new shortcut to pin
+     * @return the intent that should be set as the result for the calling activity
+     *
+     * @see Intent#ACTION_CREATE_SHORTCUT
+     */
+    @NonNull
+    public static Intent createShortcutResultIntent(@NonNull Context context,
+            @NonNull ShortcutInfoCompat shortcut) {
+        Intent result = null;
+        if (BuildCompat.isAtLeastO()) {
+            result = ShortcutManagerCompatApi26.createShortcutResultIntent(context, shortcut);
+        }
+        if (result == null) {
+            result = new Intent();
+        }
+        return shortcut.addToIntent(result);
+    }
+}
diff --git a/compat/java/android/support/v4/internal/view/SupportMenuItem.java b/compat/java/android/support/v4/internal/view/SupportMenuItem.java
index a72ae21..015db96 100644
--- a/compat/java/android/support/v4/internal/view/SupportMenuItem.java
+++ b/compat/java/android/support/v4/internal/view/SupportMenuItem.java
@@ -205,4 +205,34 @@
      * @return This menu item instance for call chaining
      */
     SupportMenuItem setSupportOnActionExpandListener(MenuItemCompat.OnActionExpandListener listener);
+
+    /**
+     * Change the content description associated with this menu item.
+     *
+     * @param contentDescription The new content description.
+     * @return This menu item instance for call chaining.
+     */
+    SupportMenuItem setContentDescription(CharSequence contentDescription);
+
+    /**
+     * Retrieve the content description associated with this menu item.
+     *
+     * @return The content description.
+     */
+    CharSequence getContentDescription();
+
+    /**
+     * Change the tooltip text associated with this menu item.
+     *
+     * @param tooltipText The new tooltip text.
+     * @return This menu item instance for call chaining.
+     */
+    SupportMenuItem setTooltipText(CharSequence tooltipText);
+
+    /**
+     * Retrieve the tooltip text associated with this menu item.
+     *
+     * @return The tooltip text.
+     */
+    CharSequence getTooltipText();
 }
\ No newline at end of file
diff --git a/compat/java/android/support/v4/internal/view/TooltipCompat.java b/compat/java/android/support/v4/internal/view/TooltipCompat.java
new file mode 100644
index 0000000..37e208b
--- /dev/null
+++ b/compat/java/android/support/v4/internal/view/TooltipCompat.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.internal.view;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.support.annotation.RestrictTo;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.view.ViewCompat;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.Toast;
+
+/**
+ * Toast-based popup used to emulate a tooltip on platform versions prior to API 26.
+ * Unlike the platform version of the tooltip, it is invoked only by a long press, but not
+ * mouse hover.
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+public class TooltipCompat {
+
+    /**
+     * Set a tooltip on a view. The tooltip text will be displayed on long click,
+     * in a toast aligned with the view.
+     * @param view View to align to
+     * @param tooltipText Tooltip text
+     */
+    public static void setTooltipText(View view, final CharSequence tooltipText) {
+        if (TextUtils.isEmpty(tooltipText)) {
+            view.setOnLongClickListener(null);
+            view.setLongClickable(false);
+        } else {
+            view.setOnLongClickListener(new View.OnLongClickListener() {
+                @Override
+                public boolean onLongClick(View v) {
+                    showTooltipToast(v, tooltipText);
+                    return true;
+                }
+            });
+        }
+    }
+
+    private static void showTooltipToast(View anchor, CharSequence tooltipText) {
+        final Context context = anchor.getContext();
+        final Resources resources = context.getResources();
+        final int screenWidth = resources.getDisplayMetrics().widthPixels;
+        final int screenHeight = resources.getDisplayMetrics().heightPixels;
+
+        final Rect displayFrame = new Rect();
+        anchor.getWindowVisibleDisplayFrame(displayFrame);
+        if (displayFrame.left < 0 && displayFrame.top < 0) {
+            // No meaningful display frame, the anchor view is probably in a subpanel
+            // (such as a popup window). Use the screen frame as a reasonable approximation.
+            final int statusBarHeight;
+            int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
+            if (resourceId > 0) {
+                statusBarHeight = resources.getDimensionPixelSize(resourceId);
+            } else {
+                statusBarHeight = 0;
+            }
+            displayFrame.set(0, statusBarHeight, screenWidth, screenHeight);
+        }
+
+        final int[] anchorPos = new int[2];
+        anchor.getLocationOnScreen(anchorPos);
+        int referenceX = anchorPos[0] + anchor.getWidth() / 2;
+        if (ViewCompat.getLayoutDirection(anchor) == ViewCompat.LAYOUT_DIRECTION_LTR) {
+            referenceX = screenWidth - referenceX; // mirror
+        }
+        final int anchorTop = anchorPos[1];
+        Toast toast = Toast.makeText(context, tooltipText, Toast.LENGTH_SHORT);
+        if (anchorTop < displayFrame.height() * 0.8) {
+            // Show along the bottom of the anchor view.
+            toast.setGravity(Gravity.TOP | GravityCompat.END, referenceX,
+                    anchorTop + anchor.getHeight() - displayFrame.top);
+        } else {
+            // Show along the top of the anchor view.
+            toast.setGravity(Gravity.BOTTOM | GravityCompat.END, referenceX,
+                    displayFrame.bottom - anchorTop);
+        }
+        toast.show();
+    }
+}
diff --git a/compat/java/android/support/v4/os/AsyncTaskCompat.java b/compat/java/android/support/v4/os/AsyncTaskCompat.java
index 2423c73..0fb3c84 100644
--- a/compat/java/android/support/v4/os/AsyncTaskCompat.java
+++ b/compat/java/android/support/v4/os/AsyncTaskCompat.java
@@ -17,12 +17,16 @@
 package android.support.v4.os;
 
 import android.os.AsyncTask;
-import android.os.Build;
+
+import java.util.concurrent.Executor;
 
 /**
  * Helper for accessing features in {@link android.os.AsyncTask}
  * introduced after API level 4 in a backwards compatible fashion.
+ *
+ * @deprecated Use {@link android.os.AsyncTask} directly.
  */
+@Deprecated
 public final class AsyncTaskCompat {
 
     /**
@@ -32,21 +36,17 @@
      * @param task The {@link android.os.AsyncTask} to execute.
      * @param params The parameters of the task.
      * @return the instance of AsyncTask.
+     *
+     * @deprecated Use {@link android.os.AsyncTask#executeOnExecutor(Executor, Object[])} directly.
      */
+    @Deprecated
     public static <Params, Progress, Result> AsyncTask<Params, Progress, Result> executeParallel(
             AsyncTask<Params, Progress, Result> task,
             Params... params) {
         if (task == null) {
             throw new IllegalArgumentException("task can not be null");
         }
-
-        if (Build.VERSION.SDK_INT >= 11) {
-            // From API 11 onwards, we need to manually select the THREAD_POOL_EXECUTOR
-            AsyncTaskCompatHoneycomb.executeParallel(task, params);
-        } else {
-            // Before API 11, all tasks were run in parallel
-            task.execute(params);
-        }
+        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
 
         return task;
     }
diff --git a/compat/java/android/support/v4/util/ArraySet.java b/compat/java/android/support/v4/util/ArraySet.java
index d03dfd1..ae6c3e6 100644
--- a/compat/java/android/support/v4/util/ArraySet.java
+++ b/compat/java/android/support/v4/util/ArraySet.java
@@ -16,6 +16,9 @@
 
 package android.support.v4.util;
 
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.support.annotation.RestrictTo;
 import android.util.Log;
 
 import java.lang.reflect.Array;
@@ -405,6 +408,7 @@
      * The array must already be large enough to contain the item.
      * @hide
      */
+    @RestrictTo(LIBRARY_GROUP)
     public void append(E value) {
         final int index = mSize;
         final int hash = value == null ? 0
diff --git a/compat/java/android/support/v4/util/TimeUtils.java b/compat/java/android/support/v4/util/TimeUtils.java
index de75846..0174e3a 100644
--- a/compat/java/android/support/v4/util/TimeUtils.java
+++ b/compat/java/android/support/v4/util/TimeUtils.java
@@ -31,6 +31,7 @@
 @RestrictTo(LIBRARY_GROUP)
 public final class TimeUtils {
     /** @hide Field length that can hold 999 days of time */
+    @RestrictTo(LIBRARY_GROUP)
     public static final int HUNDRED_DAY_FIELD_LEN = 19;
 
     private static final int SECONDS_PER_MINUTE = 60;
@@ -149,6 +150,7 @@
     }
 
     /** @hide Just for debugging; not internationalized. */
+    @RestrictTo(LIBRARY_GROUP)
     public static void formatDuration(long duration, StringBuilder builder) {
         synchronized (sFormatSync) {
             int len = formatDurationLocked(duration, 0);
@@ -157,6 +159,7 @@
     }
 
     /** @hide Just for debugging; not internationalized. */
+    @RestrictTo(LIBRARY_GROUP)
     public static void formatDuration(long duration, PrintWriter pw, int fieldLen) {
         synchronized (sFormatSync) {
             int len = formatDurationLocked(duration, fieldLen);
@@ -165,11 +168,13 @@
     }
 
     /** @hide Just for debugging; not internationalized. */
+    @RestrictTo(LIBRARY_GROUP)
     public static void formatDuration(long duration, PrintWriter pw) {
         formatDuration(duration, pw, 0);
     }
 
     /** @hide Just for debugging; not internationalized. */
+    @RestrictTo(LIBRARY_GROUP)
     public static void formatDuration(long time, long now, PrintWriter pw) {
         if (time == 0) {
             pw.print("--");
diff --git a/compat/java/android/support/v4/view/GestureDetectorCompat.java b/compat/java/android/support/v4/view/GestureDetectorCompat.java
index 3809605..7b36166 100644
--- a/compat/java/android/support/v4/view/GestureDetectorCompat.java
+++ b/compat/java/android/support/v4/view/GestureDetectorCompat.java
@@ -251,159 +251,160 @@
             boolean handled = false;
 
             switch (action & MotionEventCompat.ACTION_MASK) {
-            case MotionEventCompat.ACTION_POINTER_DOWN:
-                mDownFocusX = mLastFocusX = focusX;
-                mDownFocusY = mLastFocusY = focusY;
-                // Cancel long press and taps
-                cancelTaps();
-                break;
+                case MotionEventCompat.ACTION_POINTER_DOWN:
+                    mDownFocusX = mLastFocusX = focusX;
+                    mDownFocusY = mLastFocusY = focusY;
+                    // Cancel long press and taps
+                    cancelTaps();
+                    break;
 
-            case MotionEventCompat.ACTION_POINTER_UP:
-                mDownFocusX = mLastFocusX = focusX;
-                mDownFocusY = mLastFocusY = focusY;
+                case MotionEventCompat.ACTION_POINTER_UP:
+                    mDownFocusX = mLastFocusX = focusX;
+                    mDownFocusY = mLastFocusY = focusY;
 
-                // Check the dot product of current velocities.
-                // If the pointer that left was opposing another velocity vector, clear.
-                mVelocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
-                final int upIndex = MotionEventCompat.getActionIndex(ev);
-                final int id1 = ev.getPointerId(upIndex);
-                final float x1 = VelocityTrackerCompat.getXVelocity(mVelocityTracker, id1);
-                final float y1 = VelocityTrackerCompat.getYVelocity(mVelocityTracker, id1);
-                for (int i = 0; i < count; i++) {
-                    if (i == upIndex) continue;
+                    // Check the dot product of current velocities.
+                    // If the pointer that left was opposing another velocity vector, clear.
+                    mVelocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
+                    final int upIndex = MotionEventCompat.getActionIndex(ev);
+                    final int id1 = ev.getPointerId(upIndex);
+                    final float x1 = mVelocityTracker.getXVelocity(id1);
+                    final float y1 = mVelocityTracker.getYVelocity(id1);
+                    for (int i = 0; i < count; i++) {
+                        if (i == upIndex) continue;
 
-                    final int id2 = ev.getPointerId(i);
-                    final float x = x1 * VelocityTrackerCompat.getXVelocity(mVelocityTracker, id2);
-                    final float y = y1 * VelocityTrackerCompat.getYVelocity(mVelocityTracker, id2);
+                        final int id2 = ev.getPointerId(i);
+                        final float x = x1 * mVelocityTracker.getXVelocity(id2);
+                        final float y = y1 * mVelocityTracker.getYVelocity(id2);
 
-                    final float dot = x + y;
-                    if (dot < 0) {
-                        mVelocityTracker.clear();
+                        final float dot = x + y;
+                        if (dot < 0) {
+                            mVelocityTracker.clear();
+                            break;
+                        }
+                    }
+                    break;
+
+                case MotionEvent.ACTION_DOWN:
+                    if (mDoubleTapListener != null) {
+                        boolean hadTapMessage = mHandler.hasMessages(TAP);
+                        if (hadTapMessage) mHandler.removeMessages(TAP);
+                        if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null)
+                                && hadTapMessage && isConsideredDoubleTap(
+                                        mCurrentDownEvent, mPreviousUpEvent, ev)) {
+                            // This is a second tap
+                            mIsDoubleTapping = true;
+                            // Give a callback with the first tap of the double-tap
+                            handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
+                            // Give a callback with down event of the double-tap
+                            handled |= mDoubleTapListener.onDoubleTapEvent(ev);
+                        } else {
+                            // This is a first tap
+                            mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
+                        }
+                    }
+
+                    mDownFocusX = mLastFocusX = focusX;
+                    mDownFocusY = mLastFocusY = focusY;
+                    if (mCurrentDownEvent != null) {
+                        mCurrentDownEvent.recycle();
+                    }
+                    mCurrentDownEvent = MotionEvent.obtain(ev);
+                    mAlwaysInTapRegion = true;
+                    mAlwaysInBiggerTapRegion = true;
+                    mStillDown = true;
+                    mInLongPress = false;
+                    mDeferConfirmSingleTap = false;
+
+                    if (mIsLongpressEnabled) {
+                        mHandler.removeMessages(LONG_PRESS);
+                        mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
+                                + TAP_TIMEOUT + LONGPRESS_TIMEOUT);
+                    }
+                    mHandler.sendEmptyMessageAtTime(SHOW_PRESS,
+                            mCurrentDownEvent.getDownTime() + TAP_TIMEOUT);
+                    handled |= mListener.onDown(ev);
+                    break;
+
+                case MotionEvent.ACTION_MOVE:
+                    if (mInLongPress) {
                         break;
                     }
-                }
-                break;
-
-            case MotionEvent.ACTION_DOWN:
-                if (mDoubleTapListener != null) {
-                    boolean hadTapMessage = mHandler.hasMessages(TAP);
-                    if (hadTapMessage) mHandler.removeMessages(TAP);
-                    if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
-                            isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {
-                        // This is a second tap
-                        mIsDoubleTapping = true;
-                        // Give a callback with the first tap of the double-tap
-                        handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
-                        // Give a callback with down event of the double-tap
+                    final float scrollX = mLastFocusX - focusX;
+                    final float scrollY = mLastFocusY - focusY;
+                    if (mIsDoubleTapping) {
+                        // Give the move events of the double-tap
                         handled |= mDoubleTapListener.onDoubleTapEvent(ev);
-                    } else {
-                        // This is a first tap
-                        mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
-                    }
-                }
-
-                mDownFocusX = mLastFocusX = focusX;
-                mDownFocusY = mLastFocusY = focusY;
-                if (mCurrentDownEvent != null) {
-                    mCurrentDownEvent.recycle();
-                }
-                mCurrentDownEvent = MotionEvent.obtain(ev);
-                mAlwaysInTapRegion = true;
-                mAlwaysInBiggerTapRegion = true;
-                mStillDown = true;
-                mInLongPress = false;
-                mDeferConfirmSingleTap = false;
-
-                if (mIsLongpressEnabled) {
-                    mHandler.removeMessages(LONG_PRESS);
-                    mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
-                            + TAP_TIMEOUT + LONGPRESS_TIMEOUT);
-                }
-                mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT);
-                handled |= mListener.onDown(ev);
-                break;
-
-            case MotionEvent.ACTION_MOVE:
-                if (mInLongPress) {
-                    break;
-                }
-                final float scrollX = mLastFocusX - focusX;
-                final float scrollY = mLastFocusY - focusY;
-                if (mIsDoubleTapping) {
-                    // Give the move events of the double-tap
-                    handled |= mDoubleTapListener.onDoubleTapEvent(ev);
-                } else if (mAlwaysInTapRegion) {
-                    final int deltaX = (int) (focusX - mDownFocusX);
-                    final int deltaY = (int) (focusY - mDownFocusY);
-                    int distance = (deltaX * deltaX) + (deltaY * deltaY);
-                    if (distance > mTouchSlopSquare) {
+                    } else if (mAlwaysInTapRegion) {
+                        final int deltaX = (int) (focusX - mDownFocusX);
+                        final int deltaY = (int) (focusY - mDownFocusY);
+                        int distance = (deltaX * deltaX) + (deltaY * deltaY);
+                        if (distance > mTouchSlopSquare) {
+                            handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
+                            mLastFocusX = focusX;
+                            mLastFocusY = focusY;
+                            mAlwaysInTapRegion = false;
+                            mHandler.removeMessages(TAP);
+                            mHandler.removeMessages(SHOW_PRESS);
+                            mHandler.removeMessages(LONG_PRESS);
+                        }
+                        if (distance > mTouchSlopSquare) {
+                            mAlwaysInBiggerTapRegion = false;
+                        }
+                    } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) {
                         handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
                         mLastFocusX = focusX;
                         mLastFocusY = focusY;
-                        mAlwaysInTapRegion = false;
+                    }
+                    break;
+
+                case MotionEvent.ACTION_UP:
+                    mStillDown = false;
+                    MotionEvent currentUpEvent = MotionEvent.obtain(ev);
+                    if (mIsDoubleTapping) {
+                        // Finally, give the up event of the double-tap
+                        handled |= mDoubleTapListener.onDoubleTapEvent(ev);
+                    } else if (mInLongPress) {
                         mHandler.removeMessages(TAP);
-                        mHandler.removeMessages(SHOW_PRESS);
-                        mHandler.removeMessages(LONG_PRESS);
-                    }
-                    if (distance > mTouchSlopSquare) {
-                        mAlwaysInBiggerTapRegion = false;
-                    }
-                } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) {
-                    handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
-                    mLastFocusX = focusX;
-                    mLastFocusY = focusY;
-                }
-                break;
+                        mInLongPress = false;
+                    } else if (mAlwaysInTapRegion) {
+                        handled = mListener.onSingleTapUp(ev);
+                        if (mDeferConfirmSingleTap && mDoubleTapListener != null) {
+                            mDoubleTapListener.onSingleTapConfirmed(ev);
+                        }
+                    } else {
+                        // A fling must travel the minimum tap distance
+                        final VelocityTracker velocityTracker = mVelocityTracker;
+                        final int pointerId = ev.getPointerId(0);
+                        velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
+                        final float velocityY = velocityTracker.getYVelocity(pointerId);
+                        final float velocityX = velocityTracker.getXVelocity(pointerId);
 
-            case MotionEvent.ACTION_UP:
-                mStillDown = false;
-                MotionEvent currentUpEvent = MotionEvent.obtain(ev);
-                if (mIsDoubleTapping) {
-                    // Finally, give the up event of the double-tap
-                    handled |= mDoubleTapListener.onDoubleTapEvent(ev);
-                } else if (mInLongPress) {
-                    mHandler.removeMessages(TAP);
-                    mInLongPress = false;
-                } else if (mAlwaysInTapRegion) {
-                    handled = mListener.onSingleTapUp(ev);
-                    if (mDeferConfirmSingleTap && mDoubleTapListener != null) {
-                        mDoubleTapListener.onSingleTapConfirmed(ev);
+                        if ((Math.abs(velocityY) > mMinimumFlingVelocity)
+                                || (Math.abs(velocityX) > mMinimumFlingVelocity)) {
+                            handled = mListener.onFling(
+                                    mCurrentDownEvent, ev, velocityX, velocityY);
+                        }
                     }
-                } else {
-                    // A fling must travel the minimum tap distance
-                    final VelocityTracker velocityTracker = mVelocityTracker;
-                    final int pointerId = ev.getPointerId(0);
-                    velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
-                    final float velocityY = VelocityTrackerCompat.getYVelocity(
-                            velocityTracker, pointerId);
-                    final float velocityX = VelocityTrackerCompat.getXVelocity(
-                            velocityTracker, pointerId);
-
-                    if ((Math.abs(velocityY) > mMinimumFlingVelocity)
-                            || (Math.abs(velocityX) > mMinimumFlingVelocity)){
-                        handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY);
+                    if (mPreviousUpEvent != null) {
+                        mPreviousUpEvent.recycle();
                     }
-                }
-                if (mPreviousUpEvent != null) {
-                    mPreviousUpEvent.recycle();
-                }
-                // Hold the event we obtained above - listeners may have changed the original.
-                mPreviousUpEvent = currentUpEvent;
-                if (mVelocityTracker != null) {
-                    // This may have been cleared when we called out to the
-                    // application above.
-                    mVelocityTracker.recycle();
-                    mVelocityTracker = null;
-                }
-                mIsDoubleTapping = false;
-                mDeferConfirmSingleTap = false;
-                mHandler.removeMessages(SHOW_PRESS);
-                mHandler.removeMessages(LONG_PRESS);
-                break;
+                    // Hold the event we obtained above - listeners may have changed the original.
+                    mPreviousUpEvent = currentUpEvent;
+                    if (mVelocityTracker != null) {
+                        // This may have been cleared when we called out to the
+                        // application above.
+                        mVelocityTracker.recycle();
+                        mVelocityTracker = null;
+                    }
+                    mIsDoubleTapping = false;
+                    mDeferConfirmSingleTap = false;
+                    mHandler.removeMessages(SHOW_PRESS);
+                    mHandler.removeMessages(LONG_PRESS);
+                    break;
 
-            case MotionEvent.ACTION_CANCEL:
-                cancel();
-                break;
+                case MotionEvent.ACTION_CANCEL:
+                    cancel();
+                    break;
             }
 
             return handled;
diff --git a/compat/java/android/support/v4/view/MenuItemCompat.java b/compat/java/android/support/v4/view/MenuItemCompat.java
index 7b57e26..f8f5909 100644
--- a/compat/java/android/support/v4/view/MenuItemCompat.java
+++ b/compat/java/android/support/v4/view/MenuItemCompat.java
@@ -18,6 +18,7 @@
 
 import android.os.Build;
 import android.support.v4.internal.view.SupportMenuItem;
+import android.support.v4.os.BuildCompat;
 import android.util.Log;
 import android.view.MenuItem;
 import android.view.View;
@@ -78,6 +79,10 @@
         boolean collapseActionView(MenuItem item);
         boolean isActionViewExpanded(MenuItem item);
         MenuItem setOnActionExpandListener(MenuItem item, OnActionExpandListener listener);
+        void setContentDescription(MenuItem item, CharSequence contentDescription);
+        CharSequence getContentDescription(MenuItem item);
+        void setTooltipText(MenuItem item, CharSequence tooltipText);
+        CharSequence getTooltipText(MenuItem item);
     }
 
     /**
@@ -151,6 +156,24 @@
         public MenuItem setOnActionExpandListener(MenuItem item, OnActionExpandListener listener) {
             return item;
         }
+
+        @Override
+        public void setContentDescription(MenuItem item, CharSequence contentDescription) {
+        }
+
+        @Override
+        public CharSequence getContentDescription(MenuItem item) {
+            return null;
+        }
+
+        @Override
+        public void setTooltipText(MenuItem item, CharSequence tooltipText) {
+        }
+
+        @Override
+        public CharSequence getTooltipText(MenuItem item) {
+            return null;
+        }
     }
 
     /**
@@ -196,6 +219,24 @@
         public MenuItem setOnActionExpandListener(MenuItem item, OnActionExpandListener listener) {
             return item;
         }
+
+        @Override
+        public void setContentDescription(MenuItem item, CharSequence contentDescription) {
+        }
+
+        @Override
+        public CharSequence getContentDescription(MenuItem item) {
+            return null;
+        }
+
+        @Override
+        public void setTooltipText(MenuItem item, CharSequence tooltipText) {
+        }
+
+        @Override
+        public CharSequence getTooltipText(MenuItem item) {
+            return null;
+        }
     }
 
     static class IcsMenuVersionImpl extends HoneycombMenuVersionImpl {
@@ -240,12 +281,36 @@
         }
     }
 
+    static class Api26MenuVersionImpl extends IcsMenuVersionImpl {
+        @Override
+        public void setContentDescription(MenuItem item, CharSequence contentDescription) {
+            MenuItemCompatApi26.setContentDescription(item, contentDescription);
+        }
+
+        @Override
+        public CharSequence getContentDescription(MenuItem item) {
+            return MenuItemCompatApi26.getContentDescription(item);
+        }
+
+        @Override
+        public void setTooltipText(MenuItem item, CharSequence tooltipText) {
+            MenuItemCompatApi26.setTooltipText(item, tooltipText);
+        }
+
+        @Override
+        public CharSequence getTooltipText(MenuItem item) {
+            return MenuItemCompatApi26.getTooltipText(item);
+        }
+    }
+
     /**
      * Select the correct implementation to use for the current platform.
      */
     static final MenuVersionImpl IMPL;
     static {
-        if (Build.VERSION.SDK_INT >= 14) {
+        if (BuildCompat.isAtLeastO()) {
+            IMPL = new Api26MenuVersionImpl();
+        } else if (Build.VERSION.SDK_INT >= 14) {
             IMPL = new IcsMenuVersionImpl();
         } else if (Build.VERSION.SDK_INT >= 11) {
             IMPL = new HoneycombMenuVersionImpl();
@@ -438,5 +503,57 @@
         return IMPL.setOnActionExpandListener(item, listener);
     }
 
+    /**
+     * Change the content description associated with this menu item.
+     *
+     * @param item item to change.
+     * @param contentDescription The new content description.
+     */
+    public static void setContentDescription(MenuItem item, CharSequence contentDescription) {
+        if (item instanceof SupportMenuItem) {
+            ((SupportMenuItem) item).setContentDescription(contentDescription);
+        } else {
+            IMPL.setContentDescription(item, contentDescription);
+        }
+    }
+
+    /**
+     * Retrieve the content description associated with this menu item.
+     *
+     * @return The content description.
+     */
+    public static CharSequence getContentDescription(MenuItem item) {
+        if (item instanceof SupportMenuItem) {
+            return ((SupportMenuItem) item).getContentDescription();
+        }
+        return IMPL.getContentDescription(item);
+    }
+
+    /**
+     * Change the tooltip text associated with this menu item.
+     *
+     * @param item item to change.
+     * @param tooltipText The new tooltip text
+     */
+    public static void setTooltipText(MenuItem item, CharSequence tooltipText) {
+        if (item instanceof SupportMenuItem) {
+            ((SupportMenuItem) item).setTooltipText(tooltipText);
+        } else {
+            IMPL.setTooltipText(item, tooltipText);
+        }
+    }
+
+    /**
+     * Retrieve the tooltip text associated with this menu item.
+     *
+     * @return The tooltip text.
+     */
+    public static CharSequence getTooltipText(MenuItem item) {
+        if (item instanceof SupportMenuItem) {
+            return ((SupportMenuItem) item).getTooltipText();
+        }
+        return IMPL.getTooltipText(item);
+    }
+
     private MenuItemCompat() {}
 }
diff --git a/compat/java/android/support/v4/view/VelocityTrackerCompat.java b/compat/java/android/support/v4/view/VelocityTrackerCompat.java
index 3a02c37..327f21a 100644
--- a/compat/java/android/support/v4/view/VelocityTrackerCompat.java
+++ b/compat/java/android/support/v4/view/VelocityTrackerCompat.java
@@ -21,74 +21,33 @@
 /**
  * Helper for accessing features in {@link VelocityTracker}
  * introduced after API level 4 in a backwards compatible fashion.
+ *
+ * @deprecated Use {@link VelocityTracker} directly.
  */
+@Deprecated
 public final class VelocityTrackerCompat {
     /**
-     * Interface for the full API.
-     */
-    interface VelocityTrackerVersionImpl {
-        public float getXVelocity(VelocityTracker tracker, int pointerId);
-        public float getYVelocity(VelocityTracker tracker, int pointerId);
-    }
-
-    /**
-     * Interface implementation that doesn't use anything about v4 APIs.
-     */
-    static class BaseVelocityTrackerVersionImpl implements VelocityTrackerVersionImpl {
-        @Override
-        public float getXVelocity(VelocityTracker tracker, int pointerId) {
-            return tracker.getXVelocity();
-        }
-        @Override
-        public float getYVelocity(VelocityTracker tracker, int pointerId) {
-            return tracker.getYVelocity();
-        }
-    }
-
-    /**
-     * Interface implementation for devices with at least v11 APIs.
-     */
-    static class HoneycombVelocityTrackerVersionImpl implements VelocityTrackerVersionImpl {
-        @Override
-        public float getXVelocity(VelocityTracker tracker, int pointerId) {
-            return VelocityTrackerCompatHoneycomb.getXVelocity(tracker, pointerId);
-        }
-        @Override
-        public float getYVelocity(VelocityTracker tracker, int pointerId) {
-            return VelocityTrackerCompatHoneycomb.getYVelocity(tracker, pointerId);
-        }
-    }
-
-    /**
-     * Select the correct implementation to use for the current platform.
-     */
-    static final VelocityTrackerVersionImpl IMPL;
-    static {
-        if (android.os.Build.VERSION.SDK_INT >= 11) {
-            IMPL = new HoneycombVelocityTrackerVersionImpl();
-        } else {
-            IMPL = new BaseVelocityTrackerVersionImpl();
-        }
-    }
-
-    // -------------------------------------------------------------------
-
-    /**
      * Call {@link VelocityTracker#getXVelocity(int)}.
      * If running on a pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} device,
      * returns {@link VelocityTracker#getXVelocity()}.
+     *
+     * @deprecated Use {@link VelocityTracker#getXVelocity(int)} directly.
      */
+    @Deprecated
     public static float getXVelocity(VelocityTracker tracker, int pointerId) {
-        return IMPL.getXVelocity(tracker, pointerId);
+        return tracker.getXVelocity(pointerId);
     }
 
     /**
      * Call {@link VelocityTracker#getYVelocity(int)}.
      * If running on a pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} device,
      * returns {@link VelocityTracker#getYVelocity()}.
+     *
+     * @deprecated Use {@link VelocityTracker#getYVelocity(int)} directly.
      */
+    @Deprecated
     public static float getYVelocity(VelocityTracker tracker, int pointerId) {
-        return IMPL.getYVelocity(tracker, pointerId);
+        return tracker.getYVelocity(pointerId);
     }
 
     private VelocityTrackerCompat() {}
diff --git a/compat/java/android/support/v4/view/ViewCompat.java b/compat/java/android/support/v4/view/ViewCompat.java
index 434b850..63a4819 100644
--- a/compat/java/android/support/v4/view/ViewCompat.java
+++ b/compat/java/android/support/v4/view/ViewCompat.java
@@ -18,6 +18,7 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
+import android.animation.ValueAnimator;
 import android.content.res.ColorStateList;
 import android.graphics.Matrix;
 import android.graphics.Paint;
@@ -31,6 +32,7 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
+import android.support.v4.internal.view.TooltipCompat;
 import android.support.v4.os.BuildCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
@@ -264,13 +266,19 @@
     /**
      * Bits of {@link #getMeasuredWidthAndState} and
      * {@link #getMeasuredWidthAndState} that provide the actual measured size.
+     *
+     * @deprecated Use {@link View#MEASURED_SIZE_MASK} directly.
      */
+    @Deprecated
     public static final int MEASURED_SIZE_MASK = 0x00ffffff;
 
     /**
      * Bits of {@link #getMeasuredWidthAndState} and
      * {@link #getMeasuredWidthAndState} that provide the additional state bits.
+     *
+     * @deprecated Use {@link View#MEASURED_STATE_MASK} directly.
      */
+    @Deprecated
     public static final int MEASURED_STATE_MASK = 0xff000000;
 
     /**
@@ -278,14 +286,20 @@
      * for functions that combine both width and height into a single int,
      * such as {@link #getMeasuredState} and the childState argument of
      * {@link #resolveSizeAndState(int, int, int)}.
+     *
+     * @deprecated Use {@link View#MEASURED_HEIGHT_STATE_SHIFT} directly.
      */
+    @Deprecated
     public static final int MEASURED_HEIGHT_STATE_SHIFT = 16;
 
     /**
      * Bit of {@link #getMeasuredWidthAndState} and
      * {@link #getMeasuredWidthAndState} that indicates the measured size
      * is smaller that the space the view would like to have.
+     *
+     * @deprecated Use {@link View#MEASURED_STATE_TOO_SMALL} directly.
      */
+    @Deprecated
     public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
 
     /**
@@ -304,6 +318,7 @@
     public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
 
     /** @hide */
+    @RestrictTo(LIBRARY_GROUP)
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(flag = true,
             value = {
@@ -389,19 +404,12 @@
         boolean isImportantForAccessibility(View view);
         boolean performAccessibilityAction(View view, int action, Bundle arguments);
         AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view);
-        float getAlpha(View view);
-        void setLayerType(View view, int layerType, Paint paint);
-        int getLayerType(View view);
         int getLabelFor(View view);
         void setLabelFor(View view, int id);
         void setLayerPaint(View view, Paint paint);
         int getLayoutDirection(View view);
         void setLayoutDirection(View view, int layoutDirection);
         ViewParent getParentForAccessibility(View view);
-        int resolveSizeAndState(int size, int measureSpec, int childMeasuredState);
-        int getMeasuredWidthAndState(View view);
-        int getMeasuredHeightAndState(View view);
-        int getMeasuredState(View view);
         int getAccessibilityLiveRegion(View view);
         void setAccessibilityLiveRegion(View view, int mode);
         int getPaddingStart(View view);
@@ -409,33 +417,9 @@
         void setPaddingRelative(View view, int start, int top, int end, int bottom);
         void dispatchStartTemporaryDetach(View view);
         void dispatchFinishTemporaryDetach(View view);
-        float getX(View view);
-        float getY(View view);
-        float getRotation(View view);
-        float getRotationX(View view);
-        float getRotationY(View view);
-        float getScaleX(View view);
-        float getScaleY(View view);
-        float getTranslationX(View view);
-        float getTranslationY(View view);
-        @Nullable Matrix getMatrix(View view);
         int getMinimumWidth(View view);
         int getMinimumHeight(View view);
         ViewPropertyAnimatorCompat animate(View view);
-        void setRotation(View view, float value);
-        void setRotationX(View view, float value);
-        void setRotationY(View view, float value);
-        void setScaleX(View view, float value);
-        void setScaleY(View view, float value);
-        void setTranslationX(View view, float value);
-        void setTranslationY(View view, float value);
-        void setX(View view, float value);
-        void setY(View view, float value);
-        void setAlpha(View view, float value);
-        void setPivotX(View view, float value);
-        void setPivotY(View view, float value);
-        float getPivotX(View view);
-        float getPivotY(View view);
         void setElevation(View view, float elevation);
         float getElevation(View view);
         void setTranslationZ(View view, float translationZ);
@@ -450,12 +434,9 @@
         boolean getFitsSystemWindows(View view);
         boolean hasOverlappingRendering(View view);
         void setFitsSystemWindows(View view, boolean fitSystemWindows);
-        void jumpDrawablesToCurrentState(View v);
         void setOnApplyWindowInsetsListener(View view, OnApplyWindowInsetsListener listener);
         WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets);
         WindowInsetsCompat dispatchApplyWindowInsets(View v, WindowInsetsCompat insets);
-        void setSaveFromParentEnabled(View view, boolean enabled);
-        void setActivated(View view, boolean activated);
         boolean isPaddingRelative(View view);
         void setBackground(View view, Drawable background);
         ColorStateList getBackgroundTintList(View view);
@@ -476,7 +457,6 @@
         boolean isInLayout(View view);
         boolean isLaidOut(View view);
         boolean isLayoutDirectionResolved(View view);
-        int combineMeasuredStates(int curState, int newState);
         float getZ(View view);
         void setZ(View view, float z);
         boolean isAttachedToWindow(View view);
@@ -488,6 +468,7 @@
         void offsetLeftAndRight(View view, int offset);
         void setPointerIcon(View view, PointerIconCompat pointerIcon);
         Display getDisplay(View view);
+        void setTooltipText(View view, CharSequence tooltipText);
     }
 
     static class BaseViewCompatImpl implements ViewCompatImpl {
@@ -578,18 +559,7 @@
         public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
             return null;
         }
-        @Override
-        public float getAlpha(View view) {
-            return 1.0f;
-        }
-        @Override
-        public void setLayerType(View view, int layerType, Paint paint) {
-            // No-op until layers became available (HC)
-        }
-        @Override
-        public int getLayerType(View view) {
-            return LAYER_TYPE_NONE;
-        }
+
         @Override
         public int getLabelFor(View view) {
             return 0;
@@ -619,26 +589,6 @@
         }
 
         @Override
-        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
-            return View.resolveSize(size, measureSpec);
-        }
-
-        @Override
-        public int getMeasuredWidthAndState(View view) {
-            return view.getMeasuredWidth();
-        }
-
-        @Override
-        public int getMeasuredHeightAndState(View view) {
-            return view.getMeasuredHeight();
-        }
-
-        @Override
-        public int getMeasuredState(View view) {
-            return 0;
-        }
-
-        @Override
         public int getAccessibilityLiveRegion(View view) {
             return ACCESSIBILITY_LIVE_REGION_NONE;
         }
@@ -715,56 +665,6 @@
         }
 
         @Override
-        public float getTranslationX(View view) {
-            return 0;
-        }
-
-        @Override
-        public float getTranslationY(View view) {
-            return 0;
-        }
-
-        @Override
-        public float getX(View view) {
-            return view.getLeft();
-        }
-
-        @Override
-        public float getY(View view) {
-            return view.getTop();
-        }
-
-        @Override
-        public float getRotation(View view) {
-            return 0;
-        }
-
-        @Override
-        public float getRotationX(View view) {
-            return 0;
-        }
-
-        @Override
-        public float getRotationY(View view) {
-            return 0;
-        }
-
-        @Override
-        public float getScaleX(View view) {
-            return 0;
-        }
-
-        @Override
-        public float getScaleY(View view) {
-            return 0;
-        }
-
-        @Override
-        public Matrix getMatrix(View view) {
-            return null;
-        }
-
-        @Override
         public int getMinimumWidth(View view) {
             return ViewCompatBase.getMinimumWidth(view);
         }
@@ -780,82 +680,13 @@
         }
 
         @Override
-        public void setRotation(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setTranslationX(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setTranslationY(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setAlpha(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setRotationX(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setRotationY(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setScaleX(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setScaleY(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setX(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setY(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setPivotX(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public void setPivotY(View view, float value) {
-            // noop
-        }
-
-        @Override
-        public float getPivotX(View view) {
-            return 0;
-        }
-
-        @Override
-        public float getPivotY(View view) {
-            return 0;
-        }
-
-        @Override
         public void setTransitionName(View view, String transitionName) {
+            ViewCompatBase.setTransitionName(view, transitionName);
         }
 
         @Override
         public String getTransitionName(View view) {
-            return null;
+            return ViewCompatBase.getTransitionName(view);
         }
 
         @Override
@@ -927,11 +758,6 @@
         }
 
         @Override
-        public void jumpDrawablesToCurrentState(View view) {
-            // Do nothing; API didn't exist.
-        }
-
-        @Override
         public void setOnApplyWindowInsetsListener(View view,
                 OnApplyWindowInsetsListener listener) {
             // noop
@@ -948,16 +774,6 @@
         }
 
         @Override
-        public void setSaveFromParentEnabled(View v, boolean enabled) {
-            // noop
-        }
-
-        @Override
-        public void setActivated(View view, boolean activated) {
-            // noop
-        }
-
-        @Override
         public boolean isPaddingRelative(View view) {
             return false;
         }
@@ -1103,11 +919,6 @@
         }
 
         @Override
-        public int combineMeasuredStates(int curState, int newState) {
-            return curState | newState;
-        }
-
-        @Override
         public float getZ(View view) {
             return getTranslationZ(view) + getElevation(view);
         }
@@ -1161,173 +972,27 @@
         public Display getDisplay(View view) {
             return ViewCompatBase.getDisplay(view);
         }
+
+        @Override
+        public void setTooltipText(View view, CharSequence tooltipText) {
+            TooltipCompat.setTooltipText(view, tooltipText);
+        }
     }
 
     static class HCViewCompatImpl extends BaseViewCompatImpl {
         @Override
         long getFrameTime() {
-            return ViewCompatHC.getFrameTime();
+            return ValueAnimator.getFrameDelay();
         }
-        @Override
-        public float getAlpha(View view) {
-            return ViewCompatHC.getAlpha(view);
-        }
-        @Override
-        public void setLayerType(View view, int layerType, Paint paint) {
-            ViewCompatHC.setLayerType(view, layerType, paint);
-        }
-        @Override
-        public int getLayerType(View view)  {
-            return ViewCompatHC.getLayerType(view);
-        }
+
         @Override
         public void setLayerPaint(View view, Paint paint) {
             // Make sure the paint is correct; this will be cheap if it's the same
             // instance as was used to call setLayerType earlier.
-            setLayerType(view, getLayerType(view), paint);
+            view.setLayerType(view.getLayerType(), paint);
             // This is expensive, but the only way to accomplish this before JB-MR1.
             view.invalidate();
         }
-        @Override
-        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
-            return ViewCompatHC.resolveSizeAndState(size, measureSpec, childMeasuredState);
-        }
-        @Override
-        public int getMeasuredWidthAndState(View view) {
-            return ViewCompatHC.getMeasuredWidthAndState(view);
-        }
-        @Override
-        public int getMeasuredHeightAndState(View view) {
-            return ViewCompatHC.getMeasuredHeightAndState(view);
-        }
-        @Override
-        public int getMeasuredState(View view) {
-            return ViewCompatHC.getMeasuredState(view);
-        }
-        @Override
-        public float getTranslationX(View view) {
-            return ViewCompatHC.getTranslationX(view);
-        }
-        @Override
-        public float getTranslationY(View view) {
-            return ViewCompatHC.getTranslationY(view);
-        }
-
-        @Override
-        public Matrix getMatrix(View view) {
-            return ViewCompatHC.getMatrix(view);
-        }
-
-        @Override
-        public void setTranslationX(View view, float value) {
-            ViewCompatHC.setTranslationX(view, value);
-        }
-        @Override
-        public void setTranslationY(View view, float value) {
-            ViewCompatHC.setTranslationY(view, value);
-        }
-        @Override
-        public void setAlpha(View view, float value) {
-            ViewCompatHC.setAlpha(view, value);
-        }
-        @Override
-        public void setX(View view, float value) {
-            ViewCompatHC.setX(view, value);
-        }
-        @Override
-        public void setY(View view, float value) {
-            ViewCompatHC.setY(view, value);
-        }
-        @Override
-        public void setRotation(View view, float value) {
-            ViewCompatHC.setRotation(view, value);
-        }
-        @Override
-        public void setRotationX(View view, float value) {
-            ViewCompatHC.setRotationX(view, value);
-        }
-        @Override
-        public void setRotationY(View view, float value) {
-            ViewCompatHC.setRotationY(view, value);
-        }
-        @Override
-        public void setScaleX(View view, float value) {
-            ViewCompatHC.setScaleX(view, value);
-        }
-        @Override
-        public void setScaleY(View view, float value) {
-            ViewCompatHC.setScaleY(view, value);
-        }
-        @Override
-        public void setPivotX(View view, float value) {
-            ViewCompatHC.setPivotX(view, value);
-        }
-        @Override
-        public void setPivotY(View view, float value) {
-            ViewCompatHC.setPivotY(view, value);
-        }
-        @Override
-        public float getX(View view) {
-            return ViewCompatHC.getX(view);
-        }
-
-        @Override
-        public float getY(View view) {
-            return ViewCompatHC.getY(view);
-        }
-
-        @Override
-        public float getRotation(View view) {
-            return ViewCompatHC.getRotation(view);
-        }
-
-        @Override
-        public float getRotationX(View view) {
-            return ViewCompatHC.getRotationX(view);
-        }
-
-        @Override
-        public float getRotationY(View view) {
-            return ViewCompatHC.getRotationY(view);
-        }
-
-        @Override
-        public float getScaleX(View view) {
-            return ViewCompatHC.getScaleX(view);
-        }
-
-        @Override
-        public float getScaleY(View view) {
-            return ViewCompatHC.getScaleY(view);
-        }
-
-        @Override
-        public float getPivotX(View view) {
-            return ViewCompatHC.getPivotX(view);
-        }
-        @Override
-        public float getPivotY(View view) {
-            return ViewCompatHC.getPivotY(view);
-        }
-        @Override
-        public void jumpDrawablesToCurrentState(View view) {
-            ViewCompatHC.jumpDrawablesToCurrentState(view);
-        }
-
-        @Override
-        public void setSaveFromParentEnabled(View view, boolean enabled) {
-            ViewCompatHC.setSaveFromParentEnabled(view, enabled);
-        }
-
-        @Override
-        public void setActivated(View view, boolean activated) {
-            ViewCompatHC.setActivated(view, activated);
-        }
-
-        @Override
-        public int combineMeasuredStates(int curState, int newState) {
-            return ViewCompatHC.combineMeasuredStates(curState, newState);
-        }
 
         @Override
         public void offsetLeftAndRight(View view, int offset) {
@@ -1809,16 +1474,35 @@
 
     static class Api24ViewCompatImpl extends MarshmallowViewCompatImpl {
         @Override
+        public void dispatchStartTemporaryDetach(View view) {
+            ViewCompatApi24.dispatchStartTemporaryDetach(view);
+        }
+
+        @Override
+        public void dispatchFinishTemporaryDetach(View view) {
+            ViewCompatApi24.dispatchFinishTemporaryDetach(view);
+        }
+
+        @Override
         public void setPointerIcon(View view, PointerIconCompat pointerIconCompat) {
             ViewCompatApi24.setPointerIcon(view,
                     pointerIconCompat != null ? pointerIconCompat.getPointerIcon() : null);
         }
     }
 
+    static class Api26ViewCompatImpl extends Api24ViewCompatImpl {
+        @Override
+        public void setTooltipText(View view, CharSequence tooltipText) {
+            ViewCompatApi26.setTooltipText(view, tooltipText);
+        }
+    }
+
     static final ViewCompatImpl IMPL;
     static {
         final int version = android.os.Build.VERSION.SDK_INT;
-        if (BuildCompat.isAtLeastN()) {
+        if (BuildCompat.isAtLeastO()) {
+            IMPL = new Api26ViewCompatImpl();
+        } else if (version >= 24) {
             IMPL = new Api24ViewCompatImpl();
         } else if (version >= 23) {
             IMPL = new MarshmallowViewCompatImpl();
@@ -2250,11 +1934,14 @@
      * The opacity of the view. This is a value from 0 to 1, where 0 means the view is
      * completely transparent and 1 means the view is completely opaque.
      *
-     * <p>By default this is 1.0f. Prior to API 11, the returned value is always 1.0f.
+     * <p>By default this is 1.0f.
      * @return The opacity of the view.
+     *
+     * @deprecated Use {@link View#getAlpha()} directly.
      */
+    @Deprecated
     public static float getAlpha(View view) {
-        return IMPL.getAlpha(view);
+        return view.getAlpha();
     }
 
     /**
@@ -2288,9 +1975,12 @@
      * @param paint The paint used to compose the layer. This argument is optional
      *        and can be null. It is ignored when the layer type is
      *        {@link #LAYER_TYPE_NONE}
+     *
+     * @deprecated Use {@link View#setLayerType(int, Paint)} directly.
      */
+    @Deprecated
     public static void setLayerType(View view, @LayerType int layerType, Paint paint) {
-        IMPL.setLayerType(view, layerType, paint);
+        view.setLayerType(layerType, paint);
     }
 
     /**
@@ -2308,11 +1998,14 @@
      * @see #LAYER_TYPE_NONE
      * @see #LAYER_TYPE_SOFTWARE
      * @see #LAYER_TYPE_HARDWARE
+     *
+     * @deprecated Use {@link View#getLayerType()} directly.
      */
+    @Deprecated
     @LayerType
     public static int getLayerType(View view) {
         //noinspection ResourceType
-        return IMPL.getLayerType(view);
+        return view.getLayerType();
     }
 
     /**
@@ -2444,9 +2137,12 @@
      * @param measureSpec Constraints imposed by the parent
      * @return Size information bit mask as defined by
      * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
+     *
+     * @deprecated Use {@link View#resolveSizeAndState(int, int, int)} directly.
      */
+    @Deprecated
     public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
-        return IMPL.resolveSizeAndState(size, measureSpec, childMeasuredState);
+        return View.resolveSizeAndState(size, measureSpec, childMeasuredState);
     }
 
     /**
@@ -2458,9 +2154,12 @@
      * {@link android.view.View#getWidth()} to see how wide a view is after layout.
      *
      * @return The measured width of this view as a bit mask.
+     *
+     * @deprecated Use {@link View#getMeasuredWidth()} directly.
      */
+    @Deprecated
     public static int getMeasuredWidthAndState(View view) {
-        return IMPL.getMeasuredWidthAndState(view);
+        return view.getMeasuredWidthAndState();
     }
 
     /**
@@ -2472,9 +2171,12 @@
      * {@link android.view.View#getHeight()} to see how wide a view is after layout.
      *
      * @return The measured width of this view as a bit mask.
+     *
+     * @deprecated Use {@link View#getMeasuredHeightAndState()} directly.
      */
+    @Deprecated
     public static int getMeasuredHeightAndState(View view) {
-        return IMPL.getMeasuredHeightAndState(view);
+        return view.getMeasuredHeightAndState();
     }
 
     /**
@@ -2483,9 +2185,12 @@
      * The width component is in the regular bits {@link #MEASURED_STATE_MASK}
      * and the height component is at the shifted bits
      * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}.
+     *
+     * @deprecated Use {@link View#getMeasuredState()} directly.
      */
+    @Deprecated
     public static int getMeasuredState(View view) {
-        return IMPL.getMeasuredState(view);
+        return view.getMeasuredState();
     }
 
     /**
@@ -2495,9 +2200,12 @@
      * @param newState The new view state to combine.
      * @return Returns a new integer reflecting the combination of the two
      * states.
+     *
+     * @deprecated Use {@link View#combineMeasuredStates(int, int)} directly.
      */
+    @Deprecated
     public static int combineMeasuredStates(int curState, int newState) {
-        return IMPL.combineMeasuredStates(curState, newState);
+        return View.combineMeasuredStates(curState, newState);
     }
 
     /**
@@ -2606,12 +2314,13 @@
      * This position is post-layout, in addition to wherever the object's
      * layout placed it.
      *
-     * <p>Prior to API 11 this will return 0.</p>
-     *
      * @return The horizontal position of this view relative to its left position, in pixels.
+     *
+     * @deprecated Use {@link View#getTranslationX()} directly.
      */
+    @Deprecated
     public static float getTranslationX(View view) {
-        return IMPL.getTranslationX(view);
+        return view.getTranslationX();
     }
 
     /**
@@ -2619,19 +2328,19 @@
      * This position is post-layout, in addition to wherever the object's
      * layout placed it.
      *
-     * <p>Prior to API 11 this will return 0.</p>
-     *
      * @return The vertical position of this view relative to its top position, in pixels.
+     *
+     * @deprecated Use {@link View#getTranslationY()} directly.
      */
+    @Deprecated
     public static float getTranslationY(View view) {
-        return IMPL.getTranslationY(view);
+        return view.getTranslationY();
     }
 
     /**
      * The transform matrix of this view, which is calculated based on the current
      * rotation, scale, and pivot properties.
      * <p>
-     * Prior to 11, this method will return {@code null}.
      *
      * @param view The view whose Matrix will be returned
      * @return The current transform matrix for the view
@@ -2641,10 +2350,13 @@
      * @see #getScaleY(View)
      * @see #getPivotX(View)
      * @see #getPivotY(View)
+     *
+     * @deprecated Use {@link View#getMatrix()} directly.
      */
+    @Deprecated
     @Nullable
     public static Matrix getMatrix(View view) {
-        return IMPL.getMatrix(view);
+        return view.getMatrix();
     }
 
     /**
@@ -2686,13 +2398,14 @@
      * This effectively positions the object post-layout, in addition to wherever the object's
      * layout placed it.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The horizontal position of this view relative to its left position,
      * in pixels.
+     *
+     * @deprecated Use {@link View#setTranslationX(float)} directly.
      */
+    @Deprecated
     public static void setTranslationX(View view, float value) {
-        IMPL.setTranslationX(view, value);
+        view.setTranslationX(value);
     }
 
     /**
@@ -2700,15 +2413,16 @@
      * This effectively positions the object post-layout, in addition to wherever the object's
      * layout placed it.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The vertical position of this view relative to its top position,
      * in pixels.
      *
      * @attr name android:translationY
+     *
+     * @deprecated Use {@link View#setTranslationY(float)} directly.
      */
+    @Deprecated
     public static void setTranslationY(View view, float value) {
-        IMPL.setTranslationY(view, value);
+        view.setTranslationY(value);
     }
 
     /**
@@ -2719,12 +2433,13 @@
      * performance implications, especially for large views. It is best to use the alpha property
      * sparingly and transiently, as in the case of fading animations.</p>
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The opacity of the view.
+     *
+     * @deprecated Use {@link View#setAlpha(float)} directly.
      */
+    @Deprecated
     public static void setAlpha(View view, @FloatRange(from=0.0, to=1.0) float value) {
-        IMPL.setAlpha(view, value);
+        view.setAlpha(value);
     }
 
     /**
@@ -2733,12 +2448,13 @@
      * the x value passed in and the current left property of the view as determined
      * by the layout bounds.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The visual x position of this view, in pixels.
+     *
+     * @deprecated Use {@link View#setX(float)} directly.
      */
+    @Deprecated
     public static void setX(View view, float value) {
-        IMPL.setX(view, value);
+        view.setX(value);
     }
 
     /**
@@ -2747,24 +2463,26 @@
      * the y value passed in and the current top property of the view as determined by the
      * layout bounds.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The visual y position of this view, in pixels.
+     *
+     * @deprecated Use {@link View#setY(float)} directly.
      */
+    @Deprecated
     public static void setY(View view, float value) {
-        IMPL.setY(view, value);
+        view.setY(value);
     }
 
     /**
      * Sets the degrees that the view is rotated around the pivot point. Increasing values
      * result in clockwise rotation.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The degrees of rotation.
+     *
+     * @deprecated Use {@link View#setRotation(float)} directly.
      */
+    @Deprecated
     public static void setRotation(View view, float value) {
-        IMPL.setRotation(view, value);
+        view.setRotation(value);
     }
 
     /**
@@ -2772,12 +2490,13 @@
      * Increasing values result in clockwise rotation from the viewpoint of looking down the
      * x axis.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The degrees of X rotation.
+     *
+     * @deprecated Use {@link View#setRotationX(float)} directly.
      */
+    @Deprecated
     public static void setRotationX(View view, float value) {
-        IMPL.setRotationX(view, value);
+        view.setRotationX(value);
     }
 
     /**
@@ -2785,47 +2504,50 @@
      * Increasing values result in counter-clockwise rotation from the viewpoint of looking
      * down the y axis.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The degrees of Y rotation.
+     *
+     * @deprecated Use {@link View#setRotationY(float)} directly.
      */
+    @Deprecated
     public static void setRotationY(View view, float value) {
-        IMPL.setRotationY(view, value);
+        view.setRotationY(value);
     }
 
     /**
      * Sets the amount that the view is scaled in x around the pivot point, as a proportion of
      * the view's unscaled width. A value of 1 means that no scaling is applied.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The scaling factor.
+     *
+     * @deprecated Use {@link View#setScaleX(float)} directly.
      */
+    @Deprecated
     public static void setScaleX(View view, float value) {
-        IMPL.setScaleX(view, value);
+        view.setScaleX(value);
     }
 
     /**
      * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of
      * the view's unscaled width. A value of 1 means that no scaling is applied.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The scaling factor.
+     *
+     * @deprecated Use {@link View#setScaleY(float)} directly.
      */
+    @Deprecated
     public static void setScaleY(View view, float value) {
-        IMPL.setScaleY(view, value);
+        view.setScaleY(value);
     }
 
     /**
      * The x location of the point around which the view is
      * {@link #setRotation(View, float) rotated} and {@link #setScaleX(View, float) scaled}.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
+     * @deprecated Use {@link View#getPivotX()} directly.
      */
+    @Deprecated
     public static float getPivotX(View view) {
-        return IMPL.getPivotX(view);
+        return view.getPivotX();
     }
 
     /**
@@ -2835,24 +2557,26 @@
      * Setting this property disables this behavior and causes the view to use only the
      * explicitly set pivotX and pivotY values.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The x location of the pivot point.
+     *
+     * @deprecated Use {@link View#setPivotX(float)} directly.
      */
+    @Deprecated
     public static void setPivotX(View view, float value) {
-        IMPL.setPivotX(view, value);
+        view.setPivotX(value);
     }
 
     /**
      * The y location of the point around which the view is {@link #setRotation(View,
      * float) rotated} and {@link #setScaleY(View, float) scaled}.
      *
-     * <p>Prior to API 11 this will return 0.</p>
-     *
      * @return The y location of the pivot point.
+     *
+     * @deprecated Use {@link View#getPivotY()} directly.
      */
+    @Deprecated
     public static float getPivotY(View view) {
-        return IMPL.getPivotY(view);
+        return view.getPivotY();
     }
 
     /**
@@ -2862,40 +2586,69 @@
      * Setting this property disables this behavior and causes the view to use only the
      * explicitly set pivotX and pivotY values.
      *
-     * <p>Prior to API 11 this will have no effect.</p>
-     *
      * @param value The y location of the pivot point.
+     *
+     * @deprecated Use {@link View#setPivotX(float)} directly.
      */
+    @Deprecated
     public static void setPivotY(View view, float value) {
-        IMPL.setPivotY(view, value);
+        view.setPivotY(value);
     }
 
+    /**
+     * @deprecated Use {@link View#getRotation()} directly.
+     */
+    @Deprecated
     public static float getRotation(View view) {
-        return IMPL.getRotation(view);
+        return view.getRotation();
     }
 
+    /**
+     * @deprecated Use {@link View#getRotationX()} directly.
+     */
+    @Deprecated
     public static float getRotationX(View view) {
-        return IMPL.getRotationX(view);
+        return view.getRotationX();
     }
 
+    /**
+     * @deprecated Use {@link View#getRotationY()} directly.
+     */
+    @Deprecated
     public static float getRotationY(View view) {
-        return IMPL.getRotationY(view);
+        return view.getRotationY();
     }
 
+    /**
+     * @deprecated Use {@link View#getScaleX()} directly.
+     */
+    @Deprecated
     public static float getScaleX(View view) {
-        return IMPL.getScaleX(view);
+        return view.getScaleX();
     }
 
+    /**
+     * @deprecated Use {@link View#getScaleY()} directly.
+     */
+    @Deprecated
     public static float getScaleY(View view) {
-        return IMPL.getScaleY(view);
+        return view.getScaleY();
     }
 
+    /**
+     * @deprecated Use {@link View#getX()} directly.
+     */
+    @Deprecated
     public static float getX(View view) {
-        return IMPL.getX(view);
+        return view.getX();
     }
 
+    /**
+     * @deprecated Use {@link View#getY()} directly.
+     */
+    @Deprecated
     public static float getY(View view) {
-        return IMPL.getY(view);
+        return view.getY();
     }
 
     /**
@@ -3007,9 +2760,12 @@
      * <p>
      * On API 21 and above, also calls <code>StateListAnimator#jumpToCurrentState()</code>
      * if there is a StateListAnimator attached to this view.
+     *
+     * @deprecated Use {@link View#jumpDrawablesToCurrentState()} directly.
      */
+    @Deprecated
     public static void jumpDrawablesToCurrentState(View v) {
-        IMPL.jumpDrawablesToCurrentState(v);
+        v.jumpDrawablesToCurrentState();
     }
 
     /**
@@ -3060,9 +2816,12 @@
      *
      * @param enabled Set to false to <em>disable</em> state saving, or true
      * (the default) to allow it.
+     *
+     * @deprecated Use {@link View#setSaveFromParentEnabled(boolean)} directly.
      */
+    @Deprecated
     public static void setSaveFromParentEnabled(View v, boolean enabled) {
-        IMPL.setSaveFromParentEnabled(v, enabled);
+        v.setSaveFromParentEnabled(enabled);
     }
 
     /**
@@ -3073,9 +2832,12 @@
      * user can move views in and out of.
      *
      * @param activated true if the view must be activated, false otherwise
+     *
+     * @deprecated Use {@link View#setActivated(boolean)} directly.
      */
+    @Deprecated
     public static void setActivated(View view, boolean activated) {
-        IMPL.setActivated(view, activated);
+        view.setActivated(activated);
     }
 
     /**
@@ -3581,5 +3343,20 @@
         return IMPL.getDisplay(view);
     }
 
+    /**
+     * Sets the tooltip for the view.
+     * <p>
+     * Compatibility:
+     * <ul>
+     * <li>API &lt; 26: Sets or clears (when tooltip is null) the view's OnLongClickListener.
+     * Creates a Toast on long click.
+     * </ul>
+     *
+     * @param tooltipText the tooltip text
+     */
+    public static void setTooltipText(@NonNull View view, @Nullable CharSequence tooltipText) {
+        IMPL.setTooltipText(view, tooltipText);
+    }
+
     protected ViewCompat() {}
 }
diff --git a/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java b/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
index b92c14d..ace663d 100644
--- a/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
+++ b/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
@@ -519,7 +519,7 @@
 
         @Override
         public void withLayer(ViewPropertyAnimatorCompat vpa, View view) {
-            vpa.mOldLayerType = ViewCompat.getLayerType(view);
+            vpa.mOldLayerType = view.getLayerType();
             ViewPropertyAnimatorCompatICS.setListener(view, new MyVpaListener(vpa));
         }
 
@@ -537,7 +537,7 @@
                 mAnimEndCalled = false;
 
                 if (mVpa.mOldLayerType >= 0) {
-                    ViewCompat.setLayerType(view, ViewCompat.LAYER_TYPE_HARDWARE, null);
+                    view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                 }
                 if (mVpa.mStartAction != null) {
                     Runnable startAction = mVpa.mStartAction;
@@ -557,7 +557,7 @@
             @Override
             public void onAnimationEnd(View view) {
                 if (mVpa.mOldLayerType >= 0) {
-                    ViewCompat.setLayerType(view, mVpa.mOldLayerType, null);
+                    view.setLayerType(mVpa.mOldLayerType, null);
                     mVpa.mOldLayerType = -1;
                 }
                 if (Build.VERSION.SDK_INT >= 16 || !mAnimEndCalled) {
@@ -1252,20 +1252,20 @@
 
     /**
      * The View associated with this ViewPropertyAnimator will have its
-     * {@link ViewCompat#setLayerType(View, int, android.graphics.Paint) layer type} set to
-     * {@link ViewCompat#LAYER_TYPE_HARDWARE} for the duration of the next animation.
-     * As stated in the documentation for {@link ViewCompat#LAYER_TYPE_HARDWARE},
+     * {@link View#setLayerType(int, android.graphics.Paint) layer type} set to
+     * {@link View#LAYER_TYPE_HARDWARE} for the duration of the next animation.
+     * As stated in the documentation for {@link View#LAYER_TYPE_HARDWARE},
      * the actual type of layer used internally depends on the runtime situation of the
      * view. If the activity and this view are hardware-accelerated, then the layer will be
      * accelerated as well. If the activity or the view is not accelerated, then the layer will
-     * effectively be the same as {@link ViewCompat#LAYER_TYPE_SOFTWARE}.
+     * effectively be the same as {@link View#LAYER_TYPE_SOFTWARE}.
      *
      * <p>This state is not persistent, either on the View or on this ViewPropertyAnimator: the
      * layer type of the View will be restored when the animation ends to what it was when this
      * method was called, and this setting on ViewPropertyAnimator is only valid for the next
      * animation. Note that calling this method and then independently setting the layer type of
      * the View (by a direct call to
-     * {@link ViewCompat#setLayerType(View, int, android.graphics.Paint)}) will result in some
+     * {@link View#setLayerType(int, android.graphics.Paint)}) will result in some
      * inconsistency, including having the layer type restored to its pre-withLayer()
      * value when the animation ends.</p>
      *
diff --git a/compat/java/android/support/v4/widget/TextViewCompatGingerbread.java b/compat/java/android/support/v4/widget/TextViewCompatGingerbread.java
index 656fae9..76c8179 100644
--- a/compat/java/android/support/v4/widget/TextViewCompatGingerbread.java
+++ b/compat/java/android/support/v4/widget/TextViewCompatGingerbread.java
@@ -24,10 +24,8 @@
 import java.lang.reflect.Field;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(9)
-@TargetApi(9)
 class TextViewCompatGingerbread {
 
     private static final String LOG_TAG = "TextViewCompatGingerbread";
diff --git a/compat/jellybean-mr1/android/support/v4/content/res/ConfigurationHelperJellybeanMr1.java b/compat/jellybean-mr1/android/support/v4/content/res/ConfigurationHelperJellybeanMr1.java
index eecc581..623c0b4 100644
--- a/compat/jellybean-mr1/android/support/v4/content/res/ConfigurationHelperJellybeanMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/content/res/ConfigurationHelperJellybeanMr1.java
@@ -19,10 +19,8 @@
 import android.content.res.Resources;
 import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(17)
-@TargetApi(17)
 class ConfigurationHelperJellybeanMr1 {
     static int getDensityDpi(@NonNull Resources resources) {
         return resources.getConfiguration().densityDpi;
diff --git a/compat/jellybean-mr1/android/support/v4/graphics/drawable/DrawableCompatJellybeanMr1.java b/compat/jellybean-mr1/android/support/v4/graphics/drawable/DrawableCompatJellybeanMr1.java
index d8da519..24c610f 100644
--- a/compat/jellybean-mr1/android/support/v4/graphics/drawable/DrawableCompatJellybeanMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/graphics/drawable/DrawableCompatJellybeanMr1.java
@@ -18,7 +18,6 @@
 
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.Log;
 
 import java.lang.reflect.Method;
@@ -28,7 +27,6 @@
  */
 
 @RequiresApi(17)
-@TargetApi(17)
 class DrawableCompatJellybeanMr1 {
 
     private static final String TAG = "DrawableCompatJellybeanMr1";
diff --git a/compat/jellybean-mr1/android/support/v4/hardware/display/DisplayManagerJellybeanMr1.java b/compat/jellybean-mr1/android/support/v4/hardware/display/DisplayManagerJellybeanMr1.java
index 9cb5637..fdcc0e9 100644
--- a/compat/jellybean-mr1/android/support/v4/hardware/display/DisplayManagerJellybeanMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/hardware/display/DisplayManagerJellybeanMr1.java
@@ -16,13 +16,11 @@
 
 package android.support.v4.hardware.display;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 import android.view.Display;
 
 @RequiresApi(17)
-@TargetApi(17)
 final class DisplayManagerJellybeanMr1 {
     public static Object getDisplayManager(Context context) {
         return context.getSystemService(Context.DISPLAY_SERVICE);
diff --git a/compat/jellybean-mr1/android/support/v4/text/TextUtilsCompatJellybeanMr1.java b/compat/jellybean-mr1/android/support/v4/text/TextUtilsCompatJellybeanMr1.java
index ad354e7..b9ac180 100644
--- a/compat/jellybean-mr1/android/support/v4/text/TextUtilsCompatJellybeanMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/text/TextUtilsCompatJellybeanMr1.java
@@ -19,7 +19,6 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.text.TextUtils;
 
 import java.util.Locale;
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(17)
-@TargetApi(17)
 class TextUtilsCompatJellybeanMr1 {
     @NonNull
     public static String htmlEncode(@NonNull String s) {
diff --git a/compat/jellybean-mr1/android/support/v4/view/GravityCompatJellybeanMr1.java b/compat/jellybean-mr1/android/support/v4/view/GravityCompatJellybeanMr1.java
index efb1d77..3c3dae4 100644
--- a/compat/jellybean-mr1/android/support/v4/view/GravityCompatJellybeanMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/view/GravityCompatJellybeanMr1.java
@@ -19,11 +19,9 @@
 
 import android.graphics.Rect;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.Gravity;
 
 @RequiresApi(17)
-@TargetApi(17)
 class GravityCompatJellybeanMr1 {
 
     public static int getAbsoluteGravity(int gravity, int layoutDirection) {
diff --git a/compat/jellybean-mr1/android/support/v4/view/MarginLayoutParamsCompatJellybeanMr1.java b/compat/jellybean-mr1/android/support/v4/view/MarginLayoutParamsCompatJellybeanMr1.java
index c446abd..7e544bc 100644
--- a/compat/jellybean-mr1/android/support/v4/view/MarginLayoutParamsCompatJellybeanMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/view/MarginLayoutParamsCompatJellybeanMr1.java
@@ -18,11 +18,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.ViewGroup;
 
 @RequiresApi(17)
-@TargetApi(17)
 class MarginLayoutParamsCompatJellybeanMr1 {
     public static int getMarginStart(ViewGroup.MarginLayoutParams lp) {
         return lp.getMarginStart();
diff --git a/compat/jellybean-mr1/android/support/v4/view/ViewCompatJellybeanMr1.java b/compat/jellybean-mr1/android/support/v4/view/ViewCompatJellybeanMr1.java
index 79b5ce2..ed2b19f 100644
--- a/compat/jellybean-mr1/android/support/v4/view/ViewCompatJellybeanMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/view/ViewCompatJellybeanMr1.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.view;
 
-import android.annotation.TargetApi;
 import android.graphics.Paint;
 import android.support.annotation.RequiresApi;
 import android.view.Display;
@@ -27,7 +26,6 @@
  */
 
 @RequiresApi(17)
-@TargetApi(17)
 class ViewCompatJellybeanMr1 {
 
     public static int getLabelFor(View view) {
diff --git a/compat/jellybean-mr1/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellybeanMr1.java b/compat/jellybean-mr1/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellybeanMr1.java
index aa20646..c81e6e4 100644
--- a/compat/jellybean-mr1/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellybeanMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellybeanMr1.java
@@ -17,12 +17,10 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 @RequiresApi(17)
-@TargetApi(17)
 class AccessibilityNodeInfoCompatJellybeanMr1 {
 
     public static void setLabelFor(Object info, View labeled) {
diff --git a/compat/jellybean-mr1/android/support/v4/widget/TextViewCompatJbMr1.java b/compat/jellybean-mr1/android/support/v4/widget/TextViewCompatJbMr1.java
index c8dbf98..a200da2 100644
--- a/compat/jellybean-mr1/android/support/v4/widget/TextViewCompatJbMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/widget/TextViewCompatJbMr1.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
@@ -25,7 +24,6 @@
 import android.widget.TextView;
 
 @RequiresApi(17)
-@TargetApi(17)
 class TextViewCompatJbMr1 {
 
     public static void setCompoundDrawablesRelative(@NonNull TextView textView,
diff --git a/compat/jellybean-mr2/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatJellyBeanMr2.java b/compat/jellybean-mr2/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatJellyBeanMr2.java
index acc72b1..484db20 100644
--- a/compat/jellybean-mr2/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatJellyBeanMr2.java
+++ b/compat/jellybean-mr2/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatJellyBeanMr2.java
@@ -18,14 +18,12 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * ICS implementation of the new APIs in AccessibilityServiceInfo.
  */
 
 @RequiresApi(18)
-@TargetApi(18)
 class AccessibilityServiceInfoCompatJellyBeanMr2 {
 
     public static int getCapabilities(AccessibilityServiceInfo info) {
diff --git a/compat/jellybean-mr2/android/support/v4/app/BundleCompatJellybeanMR2.java b/compat/jellybean-mr2/android/support/v4/app/BundleCompatJellybeanMR2.java
index 598ff31..7d439cb 100644
--- a/compat/jellybean-mr2/android/support/v4/app/BundleCompatJellybeanMR2.java
+++ b/compat/jellybean-mr2/android/support/v4/app/BundleCompatJellybeanMR2.java
@@ -16,16 +16,18 @@
 
 package android.support.v4.app;
 
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
 import android.os.Bundle;
 import android.os.IBinder;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
+import android.support.annotation.RestrictTo;
 
 /**
  * @hide
  */
+@RestrictTo(LIBRARY_GROUP)
 @RequiresApi(18)
-@TargetApi(18)
 class BundleCompatJellybeanMR2 {
     public static IBinder getBinder(Bundle bundle, String key) {
         return bundle.getBinder(key);
diff --git a/compat/jellybean-mr2/android/support/v4/graphics/BitmapCompatJellybeanMR2.java b/compat/jellybean-mr2/android/support/v4/graphics/BitmapCompatJellybeanMR2.java
index 20739d1..abf4dde 100644
--- a/compat/jellybean-mr2/android/support/v4/graphics/BitmapCompatJellybeanMR2.java
+++ b/compat/jellybean-mr2/android/support/v4/graphics/BitmapCompatJellybeanMR2.java
@@ -17,10 +17,8 @@
 
 import android.graphics.Bitmap;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(18)
-@TargetApi(18)
 class BitmapCompatJellybeanMR2 {
     public static boolean hasMipMap(Bitmap bitmap) {
         return bitmap.hasMipMap();
diff --git a/compat/jellybean-mr2/android/support/v4/os/TraceJellybeanMR2.java b/compat/jellybean-mr2/android/support/v4/os/TraceJellybeanMR2.java
index a41816d..bc29ad8 100644
--- a/compat/jellybean-mr2/android/support/v4/os/TraceJellybeanMR2.java
+++ b/compat/jellybean-mr2/android/support/v4/os/TraceJellybeanMR2.java
@@ -15,10 +15,8 @@
 
 import android.os.Trace;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(18)
-@TargetApi(18)
 class TraceJellybeanMR2 {
     public static void beginSection(String section) {
         Trace.beginSection(section);
diff --git a/compat/jellybean-mr2/android/support/v4/view/ViewCompatJellybeanMr2.java b/compat/jellybean-mr2/android/support/v4/view/ViewCompatJellybeanMr2.java
index 46c5d4e..d3403c6 100644
--- a/compat/jellybean-mr2/android/support/v4/view/ViewCompatJellybeanMr2.java
+++ b/compat/jellybean-mr2/android/support/v4/view/ViewCompatJellybeanMr2.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Rect;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 
 /**
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(18)
-@TargetApi(18)
 class ViewCompatJellybeanMr2 {
 
     public static Rect getClipBounds(View view) {
diff --git a/compat/jellybean-mr2/android/support/v4/view/ViewGroupCompatJellybeanMR2.java b/compat/jellybean-mr2/android/support/v4/view/ViewGroupCompatJellybeanMR2.java
index e1c8532..184ef6c 100644
--- a/compat/jellybean-mr2/android/support/v4/view/ViewGroupCompatJellybeanMR2.java
+++ b/compat/jellybean-mr2/android/support/v4/view/ViewGroupCompatJellybeanMR2.java
@@ -18,11 +18,9 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.ViewGroup;
 
 @RequiresApi(18)
-@TargetApi(18)
 class ViewGroupCompatJellybeanMR2 {
     public static int getLayoutMode(ViewGroup group) {
         return group.getLayoutMode();
diff --git a/compat/jellybean-mr2/android/support/v4/view/ViewPropertyAnimatorCompatJellybeanMr2.java b/compat/jellybean-mr2/android/support/v4/view/ViewPropertyAnimatorCompatJellybeanMr2.java
index 14e76a9..e285f23 100644
--- a/compat/jellybean-mr2/android/support/v4/view/ViewPropertyAnimatorCompatJellybeanMr2.java
+++ b/compat/jellybean-mr2/android/support/v4/view/ViewPropertyAnimatorCompatJellybeanMr2.java
@@ -16,12 +16,10 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.animation.Interpolator;
 
 @RequiresApi(18)
-@TargetApi(18)
 class ViewPropertyAnimatorCompatJellybeanMr2 {
     public static Interpolator getInterpolator(View view) {
         return (Interpolator) view.animate().getInterpolator();
diff --git a/compat/jellybean-mr2/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellybeanMr2.java b/compat/jellybean-mr2/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellybeanMr2.java
index 82bfa11..02e8ca0 100644
--- a/compat/jellybean-mr2/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellybeanMr2.java
+++ b/compat/jellybean-mr2/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellybeanMr2.java
@@ -17,13 +17,11 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 import java.util.List;
 
 @RequiresApi(18)
-@TargetApi(18)
 class AccessibilityNodeInfoCompatJellybeanMr2 {
 
     public static void setViewIdResourceName(Object info, String viewId) {
diff --git a/compat/jellybean-mr2/android/support/v4/widget/TextViewCompatJbMr2.java b/compat/jellybean-mr2/android/support/v4/widget/TextViewCompatJbMr2.java
index d80725b..b2377c7 100644
--- a/compat/jellybean-mr2/android/support/v4/widget/TextViewCompatJbMr2.java
+++ b/compat/jellybean-mr2/android/support/v4/widget/TextViewCompatJbMr2.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.NonNull;
@@ -25,7 +24,6 @@
 import android.widget.TextView;
 
 @RequiresApi(18)
-@TargetApi(18)
 class TextViewCompatJbMr2 {
 
     public static void setCompoundDrawablesRelative(@NonNull TextView textView,
diff --git a/compat/jellybean/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatJellyBean.java b/compat/jellybean/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatJellyBean.java
index d42cefc..ec1bb7e 100644
--- a/compat/jellybean/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatJellyBean.java
+++ b/compat/jellybean/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompatJellyBean.java
@@ -19,14 +19,12 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.content.pm.PackageManager;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * JB implementation of the new APIs in AccessibilityServiceInfo.
  */
 
 @RequiresApi(16)
-@TargetApi(16)
 class AccessibilityServiceInfoCompatJellyBean {
 
     public static String loadDescription(AccessibilityServiceInfo info, PackageManager pm) {
diff --git a/compat/jellybean/android/support/v4/app/ActivityCompatJB.java b/compat/jellybean/android/support/v4/app/ActivityCompatJB.java
index ad1c9aa..e749a93 100644
--- a/compat/jellybean/android/support/v4/app/ActivityCompatJB.java
+++ b/compat/jellybean/android/support/v4/app/ActivityCompatJB.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Intent;
 import android.content.IntentSender;
@@ -24,7 +23,6 @@
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(16)
-@TargetApi(16)
 class ActivityCompatJB {
     public static void startActivityForResult(Activity activity, Intent intent, int requestCode, Bundle options) {
         activity.startActivityForResult(intent, requestCode, options);
diff --git a/compat/jellybean/android/support/v4/app/ActivityOptionsCompatJB.java b/compat/jellybean/android/support/v4/app/ActivityOptionsCompatJB.java
index 1655c4b..e5800e2 100644
--- a/compat/jellybean/android/support/v4/app/ActivityOptionsCompatJB.java
+++ b/compat/jellybean/android/support/v4/app/ActivityOptionsCompatJB.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.ActivityOptions;
 import android.content.Context;
 import android.graphics.Bitmap;
@@ -25,7 +24,6 @@
 import android.view.View;
 
 @RequiresApi(16)
-@TargetApi(16)
 class ActivityOptionsCompatJB {
 
     public static ActivityOptionsCompatJB makeCustomAnimation(Context context,
diff --git a/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java b/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java
index c50e5f0..de117c1 100644
--- a/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java
+++ b/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -33,7 +32,6 @@
 import java.util.List;
 
 @RequiresApi(16)
-@TargetApi(16)
 class NotificationCompatJellybean {
     public static final String TAG = "NotificationCompat";
 
@@ -41,6 +39,7 @@
     static final String EXTRA_LOCAL_ONLY = "android.support.localOnly";
     static final String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
     static final String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
+    static final String EXTRA_DATA_ONLY_REMOTE_INPUTS = "android.support.dataRemoteInputs";
     static final String EXTRA_GROUP_KEY = "android.support.groupKey";
     static final String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
     static final String EXTRA_SORT_KEY = "android.support.sortKey";
@@ -53,6 +52,7 @@
     private static final String KEY_ACTION_INTENT = "actionIntent";
     private static final String KEY_EXTRAS = "extras";
     private static final String KEY_REMOTE_INPUTS = "remoteInputs";
+    private static final String KEY_DATA_ONLY_REMOTE_INPUTS = "dataOnlyRemoteInputs";
     private static final String KEY_ALLOW_GENERATED_REPLIES = "allowGeneratedReplies";
 
     private static final Object sExtrasLock = new Object();
@@ -262,15 +262,19 @@
             RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory, int icon,
             CharSequence title, PendingIntent actionIntent, Bundle extras) {
         RemoteInputCompatBase.RemoteInput[] remoteInputs = null;
+        RemoteInputCompatBase.RemoteInput[] dataOnlyRemoteInputs = null;
         boolean allowGeneratedReplies = false;
         if (extras != null) {
             remoteInputs = RemoteInputCompatJellybean.fromBundleArray(
                     BundleUtil.getBundleArrayFromBundle(extras, EXTRA_REMOTE_INPUTS),
                     remoteInputFactory);
+            dataOnlyRemoteInputs = RemoteInputCompatJellybean.fromBundleArray(
+                    BundleUtil.getBundleArrayFromBundle(extras, EXTRA_DATA_ONLY_REMOTE_INPUTS),
+                    remoteInputFactory);
             allowGeneratedReplies = extras.getBoolean(EXTRA_ALLOW_GENERATED_REPLIES);
         }
         return factory.build(icon, title, actionIntent, extras, remoteInputs,
-                allowGeneratedReplies);
+                dataOnlyRemoteInputs, allowGeneratedReplies);
     }
 
     public static Bundle writeActionAndGetExtras(
@@ -281,6 +285,10 @@
             actionExtras.putParcelableArray(EXTRA_REMOTE_INPUTS,
                     RemoteInputCompatJellybean.toBundleArray(action.getRemoteInputs()));
         }
+        if (action.getDataOnlyRemoteInputs() != null) {
+            actionExtras.putParcelableArray(EXTRA_DATA_ONLY_REMOTE_INPUTS,
+                    RemoteInputCompatJellybean.toBundleArray(action.getDataOnlyRemoteInputs()));
+        }
         actionExtras.putBoolean(EXTRA_ALLOW_GENERATED_REPLIES,
                 action.getAllowGeneratedReplies());
         return actionExtras;
@@ -392,7 +400,11 @@
                 bundle.getBundle(KEY_EXTRAS),
                 RemoteInputCompatJellybean.fromBundleArray(
                         BundleUtil.getBundleArrayFromBundle(bundle, KEY_REMOTE_INPUTS),
-                        remoteInputFactory), allowGeneratedReplies);
+                        remoteInputFactory),
+                RemoteInputCompatJellybean.fromBundleArray(
+                        BundleUtil.getBundleArrayFromBundle(bundle, KEY_DATA_ONLY_REMOTE_INPUTS),
+                        remoteInputFactory),
+                allowGeneratedReplies);
     }
 
     public static ArrayList<Parcelable> getParcelableArrayListForActions(
diff --git a/compat/jellybean/android/support/v4/app/RemoteInputCompatJellybean.java b/compat/jellybean/android/support/v4/app/RemoteInputCompatJellybean.java
index 2fa9adc..558a42b 100644
--- a/compat/jellybean/android/support/v4/app/RemoteInputCompatJellybean.java
+++ b/compat/jellybean/android/support/v4/app/RemoteInputCompatJellybean.java
@@ -19,12 +19,17 @@
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
 @RequiresApi(16)
-@TargetApi(16)
 class RemoteInputCompatJellybean {
     /** Label used to denote the clip data type used for remote input transport */
     public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
@@ -32,19 +37,32 @@
     /** Extra added to a clip data intent object to hold the results bundle. */
     public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
 
+    /** Extra added to a clip data intent object to hold the data results bundle. */
+    private static final String EXTRA_DATA_TYPE_RESULTS_DATA =
+            "android.remoteinput.dataTypeResultsData";
+
     private static final String KEY_RESULT_KEY = "resultKey";
     private static final String KEY_LABEL = "label";
     private static final String KEY_CHOICES = "choices";
     private static final String KEY_ALLOW_FREE_FORM_INPUT = "allowFreeFormInput";
     private static final String KEY_EXTRAS = "extras";
+    private static final String KEY_ALLOWED_DATA_TYPES = "allowedDataTypes";
 
     static RemoteInputCompatBase.RemoteInput fromBundle(Bundle data,
             RemoteInputCompatBase.RemoteInput.Factory factory) {
+        ArrayList<String> allowedDataTypesAsList = data.getStringArrayList(KEY_ALLOWED_DATA_TYPES);
+        Set<String> allowedDataTypes = new HashSet<>();
+        if (allowedDataTypesAsList != null) {
+            for (String type : allowedDataTypesAsList) {
+                allowedDataTypes.add(type);
+            }
+        }
         return factory.build(data.getString(KEY_RESULT_KEY),
                 data.getCharSequence(KEY_LABEL),
                 data.getCharSequenceArray(KEY_CHOICES),
                 data.getBoolean(KEY_ALLOW_FREE_FORM_INPUT),
-                data.getBundle(KEY_EXTRAS));
+                data.getBundle(KEY_EXTRAS),
+                allowedDataTypes);
     }
 
     static Bundle toBundle(RemoteInputCompatBase.RemoteInput remoteInput) {
@@ -54,6 +72,15 @@
         data.putCharSequenceArray(KEY_CHOICES, remoteInput.getChoices());
         data.putBoolean(KEY_ALLOW_FREE_FORM_INPUT, remoteInput.getAllowFreeFormInput());
         data.putBundle(KEY_EXTRAS, remoteInput.getExtras());
+
+        Set<String> allowedDataTypes = remoteInput.getAllowedDataTypes();
+        if (allowedDataTypes != null && !allowedDataTypes.isEmpty()) {
+            ArrayList<String> allowedDataTypesAsList = new ArrayList<>(allowedDataTypes.size());
+            for (String type : allowedDataTypes) {
+                allowedDataTypesAsList.add(type);
+            }
+            data.putStringArrayList(KEY_ALLOWED_DATA_TYPES, allowedDataTypesAsList);
+        }
         return data;
     }
 
@@ -81,6 +108,92 @@
     }
 
     static Bundle getResultsFromIntent(Intent intent) {
+        Intent clipDataIntent = getClipDataIntentFromIntent(intent);
+        if (clipDataIntent == null) {
+            return null;
+        }
+        return clipDataIntent.getExtras().getParcelable(EXTRA_RESULTS_DATA);
+    }
+
+    static Map<String, Uri> getDataResultsFromIntent(Intent intent, String remoteInputResultKey) {
+        Intent clipDataIntent = getClipDataIntentFromIntent(intent);
+        if (clipDataIntent == null) {
+            return null;
+        }
+        Map<String, Uri> results = new HashMap<>();
+        Bundle extras = clipDataIntent.getExtras();
+        for (String key : extras.keySet()) {
+            if (key.startsWith(EXTRA_DATA_TYPE_RESULTS_DATA)) {
+                String mimeType = key.substring(EXTRA_DATA_TYPE_RESULTS_DATA.length());
+                if (mimeType == null || mimeType.isEmpty()) {
+                    continue;
+                }
+                Bundle bundle = clipDataIntent.getBundleExtra(key);
+                String uriStr = bundle.getString(remoteInputResultKey);
+                if (uriStr == null || uriStr.isEmpty()) {
+                    continue;
+                }
+                results.put(mimeType, Uri.parse(uriStr));
+            }
+        }
+        return results.isEmpty() ? null : results;
+    }
+
+    static void addResultsToIntent(RemoteInputCompatBase.RemoteInput[] remoteInputs, Intent intent,
+            Bundle results) {
+        Intent clipDataIntent = getClipDataIntentFromIntent(intent);
+        if (clipDataIntent == null) {
+            clipDataIntent = new Intent();  // First time we've added a result.
+        }
+        Bundle resultsBundle = clipDataIntent.getBundleExtra(EXTRA_RESULTS_DATA);
+        if (resultsBundle == null) {
+            resultsBundle = new Bundle();
+        }
+        for (RemoteInputCompatBase.RemoteInput remoteInput : remoteInputs) {
+            Object result = results.get(remoteInput.getResultKey());
+            if (result instanceof CharSequence) {
+                resultsBundle.putCharSequence(remoteInput.getResultKey(), (CharSequence) result);
+            }
+        }
+        clipDataIntent.putExtra(EXTRA_RESULTS_DATA, resultsBundle);
+        intent.setClipData(ClipData.newIntent(RESULTS_CLIP_LABEL, clipDataIntent));
+    }
+
+    /**
+     * Same as {@link #addResultsToIntent} but for setting data results.
+     * @param remoteInput The remote input for which results are being provided
+     * @param intent The intent to add remote input results to. The {@link ClipData}
+     *               field of the intent will be modified to contain the results.
+     * @param results A map of mime type to the Uri result for that mime type.
+     */
+    public static void addDataResultToIntent(RemoteInput remoteInput, Intent intent,
+            Map<String, Uri> results) {
+        Intent clipDataIntent = getClipDataIntentFromIntent(intent);
+        if (clipDataIntent == null) {
+            clipDataIntent = new Intent();  // First time we've added a result.
+        }
+        for (Map.Entry<String, Uri> entry : results.entrySet()) {
+            String mimeType = entry.getKey();
+            Uri uri = entry.getValue();
+            if (mimeType == null) {
+                continue;
+            }
+            Bundle resultsBundle =
+                    clipDataIntent.getBundleExtra(getExtraResultsKeyForData(mimeType));
+            if (resultsBundle == null) {
+                resultsBundle = new Bundle();
+            }
+            resultsBundle.putString(remoteInput.getResultKey(), uri.toString());
+            clipDataIntent.putExtra(getExtraResultsKeyForData(mimeType), resultsBundle);
+        }
+        intent.setClipData(ClipData.newIntent(RESULTS_CLIP_LABEL, clipDataIntent));
+    }
+
+    private static String getExtraResultsKeyForData(String mimeType) {
+        return EXTRA_DATA_TYPE_RESULTS_DATA + mimeType;
+    }
+
+    private static Intent getClipDataIntentFromIntent(Intent intent) {
         ClipData clipData = intent.getClipData();
         if (clipData == null) {
             return null;
@@ -89,23 +202,9 @@
         if (!clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_INTENT)) {
             return null;
         }
-        if (clipDescription.getLabel().equals(RESULTS_CLIP_LABEL)) {
-            return clipData.getItemAt(0).getIntent().getExtras().getParcelable(EXTRA_RESULTS_DATA);
+        if (!clipDescription.getLabel().equals(RESULTS_CLIP_LABEL)) {
+            return null;
         }
-        return null;
-    }
-
-    static void addResultsToIntent(RemoteInputCompatBase.RemoteInput[] remoteInputs, Intent intent,
-            Bundle results) {
-        Bundle resultsBundle = new Bundle();
-        for (RemoteInputCompatBase.RemoteInput remoteInput : remoteInputs) {
-            Object result = results.get(remoteInput.getResultKey());
-            if (result instanceof CharSequence) {
-                resultsBundle.putCharSequence(remoteInput.getResultKey(), (CharSequence) result);
-            }
-        }
-        Intent clipIntent = new Intent();
-        clipIntent.putExtra(EXTRA_RESULTS_DATA, resultsBundle);
-        intent.setClipData(ClipData.newIntent(RESULTS_CLIP_LABEL, clipIntent));
+        return clipData.getItemAt(0).getIntent();
     }
 }
diff --git a/compat/jellybean/android/support/v4/app/ShareCompatJB.java b/compat/jellybean/android/support/v4/app/ShareCompatJB.java
index 58eaa23..e65f952 100644
--- a/compat/jellybean/android/support/v4/app/ShareCompatJB.java
+++ b/compat/jellybean/android/support/v4/app/ShareCompatJB.java
@@ -16,12 +16,10 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.text.Html;
 
 @RequiresApi(16)
-@TargetApi(16)
 class ShareCompatJB {
     public static String escapeHtml(CharSequence html) {
         return Html.escapeHtml(html);
diff --git a/compat/jellybean/android/support/v4/content/ContentResolverCompatJellybean.java b/compat/jellybean/android/support/v4/content/ContentResolverCompatJellybean.java
index ea4d610..7744d70 100644
--- a/compat/jellybean/android/support/v4/content/ContentResolverCompatJellybean.java
+++ b/compat/jellybean/android/support/v4/content/ContentResolverCompatJellybean.java
@@ -21,10 +21,8 @@
 import android.net.Uri;
 import android.os.OperationCanceledException;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(16)
-@TargetApi(16)
 class ContentResolverCompatJellybean {
 
     public static Cursor query(ContentResolver resolver, Uri uri, String[] projection,
diff --git a/compat/jellybean/android/support/v4/content/ContextCompatJellybean.java b/compat/jellybean/android/support/v4/content/ContextCompatJellybean.java
index c00a971..2f57640 100644
--- a/compat/jellybean/android/support/v4/content/ContextCompatJellybean.java
+++ b/compat/jellybean/android/support/v4/content/ContextCompatJellybean.java
@@ -20,10 +20,8 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(16)
-@TargetApi(16)
 class ContextCompatJellybean {
 
     public static void startActivities(Context context, Intent[] intents, Bundle options) {
diff --git a/compat/jellybean/android/support/v4/net/ConnectivityManagerCompatJellyBean.java b/compat/jellybean/android/support/v4/net/ConnectivityManagerCompatJellyBean.java
index 64272b8..7e47298 100644
--- a/compat/jellybean/android/support/v4/net/ConnectivityManagerCompatJellyBean.java
+++ b/compat/jellybean/android/support/v4/net/ConnectivityManagerCompatJellyBean.java
@@ -18,14 +18,12 @@
 
 import android.net.ConnectivityManager;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * Implementation of ConnectivityManagerCompat that can use Jellybean APIs.
  */
 
 @RequiresApi(16)
-@TargetApi(16)
 class ConnectivityManagerCompatJellyBean {
     public static boolean isActiveNetworkMetered(ConnectivityManager cm) {
         return cm.isActiveNetworkMetered();
diff --git a/compat/jellybean/android/support/v4/os/CancellationSignalCompatJellybean.java b/compat/jellybean/android/support/v4/os/CancellationSignalCompatJellybean.java
index 127fdbf..344a26a 100644
--- a/compat/jellybean/android/support/v4/os/CancellationSignalCompatJellybean.java
+++ b/compat/jellybean/android/support/v4/os/CancellationSignalCompatJellybean.java
@@ -17,10 +17,8 @@
 package android.support.v4.os;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(16)
-@TargetApi(16)
 class CancellationSignalCompatJellybean {
     public static Object create() {
         return new android.os.CancellationSignal();
diff --git a/compat/jellybean/android/support/v4/view/AccessibilityDelegateCompatJellyBean.java b/compat/jellybean/android/support/v4/view/AccessibilityDelegateCompatJellyBean.java
index e588892..c8c9fb0 100644
--- a/compat/jellybean/android/support/v4/view/AccessibilityDelegateCompatJellyBean.java
+++ b/compat/jellybean/android/support/v4/view/AccessibilityDelegateCompatJellyBean.java
@@ -18,7 +18,6 @@
 
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.View.AccessibilityDelegate;
 import android.view.ViewGroup;
@@ -31,7 +30,6 @@
  */
 
 @RequiresApi(16)
-@TargetApi(16)
 class AccessibilityDelegateCompatJellyBean {
 
     public interface AccessibilityDelegateBridgeJellyBean {
diff --git a/compat/jellybean/android/support/v4/view/ViewCompatJB.java b/compat/jellybean/android/support/v4/view/ViewCompatJB.java
index ccf34ba..ae3b0c8 100644
--- a/compat/jellybean/android/support/v4/view/ViewCompatJB.java
+++ b/compat/jellybean/android/support/v4/view/ViewCompatJB.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.view;
 
-import android.annotation.TargetApi;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
@@ -27,7 +26,6 @@
  * Jellybean-specific View API access
  */
 @RequiresApi(16)
-@TargetApi(16)
 class ViewCompatJB {
 
     public static boolean hasTransientState(View view) {
diff --git a/compat/jellybean/android/support/v4/view/ViewPropertyAnimatorCompatJB.java b/compat/jellybean/android/support/v4/view/ViewPropertyAnimatorCompatJB.java
index 8e327fe..67a7b45 100644
--- a/compat/jellybean/android/support/v4/view/ViewPropertyAnimatorCompatJB.java
+++ b/compat/jellybean/android/support/v4/view/ViewPropertyAnimatorCompatJB.java
@@ -17,12 +17,10 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.view.View;
 
 @RequiresApi(16)
-@TargetApi(16)
 class ViewPropertyAnimatorCompatJB {
 
     public static void withStartAction(View view, Runnable runnable) {
diff --git a/compat/jellybean/android/support/v4/view/accessibility/AccessibilityEventCompatJellyBean.java b/compat/jellybean/android/support/v4/view/accessibility/AccessibilityEventCompatJellyBean.java
index 9c9ef09..673c2d2 100644
--- a/compat/jellybean/android/support/v4/view/accessibility/AccessibilityEventCompatJellyBean.java
+++ b/compat/jellybean/android/support/v4/view/accessibility/AccessibilityEventCompatJellyBean.java
@@ -17,11 +17,9 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityEvent;
 
 @RequiresApi(16)
-@TargetApi(16)
 class AccessibilityEventCompatJellyBean {
     public static void setMovementGranularity(AccessibilityEvent event, int granularity) {
         event.setMovementGranularity(granularity);
diff --git a/compat/jellybean/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellyBean.java b/compat/jellybean/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellyBean.java
index a095b10..37fe9f4 100644
--- a/compat/jellybean/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellyBean.java
+++ b/compat/jellybean/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatJellyBean.java
@@ -18,7 +18,6 @@
 
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 
@@ -27,7 +26,6 @@
  */
 
 @RequiresApi(16)
-@TargetApi(16)
 class AccessibilityNodeInfoCompatJellyBean {
 
     public static void addChild(Object info, View child, int virtualDescendantId) {
diff --git a/compat/jellybean/android/support/v4/view/accessibility/AccessibilityNodeProviderCompatJellyBean.java b/compat/jellybean/android/support/v4/view/accessibility/AccessibilityNodeProviderCompatJellyBean.java
index 195e2f3..3fd5f14 100644
--- a/compat/jellybean/android/support/v4/view/accessibility/AccessibilityNodeProviderCompatJellyBean.java
+++ b/compat/jellybean/android/support/v4/view/accessibility/AccessibilityNodeProviderCompatJellyBean.java
@@ -18,7 +18,6 @@
 
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
 
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(16)
-@TargetApi(16)
 class AccessibilityNodeProviderCompatJellyBean {
     interface AccessibilityNodeInfoBridge {
         public Object createAccessibilityNodeInfo(int virtualViewId);
diff --git a/compat/jellybean/android/support/v4/view/accessibility/AccessibilityRecordCompatJellyBean.java b/compat/jellybean/android/support/v4/view/accessibility/AccessibilityRecordCompatJellyBean.java
index e5a51b7..3beddc6 100644
--- a/compat/jellybean/android/support/v4/view/accessibility/AccessibilityRecordCompatJellyBean.java
+++ b/compat/jellybean/android/support/v4/view/accessibility/AccessibilityRecordCompatJellyBean.java
@@ -17,7 +17,6 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.accessibility.AccessibilityRecord;
 
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(16)
-@TargetApi(16)
 class AccessibilityRecordCompatJellyBean {
 
     public static void setSource(Object record, View root, int virtualDescendantId) {
diff --git a/compat/jellybean/android/support/v4/widget/TextViewCompatJb.java b/compat/jellybean/android/support/v4/widget/TextViewCompatJb.java
index 4fd4c4e..82a98c5 100644
--- a/compat/jellybean/android/support/v4/widget/TextViewCompatJb.java
+++ b/compat/jellybean/android/support/v4/widget/TextViewCompatJb.java
@@ -16,12 +16,10 @@
 
 package android.support.v4.widget;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.widget.TextView;
 
 @RequiresApi(16)
-@TargetApi(16)
 class TextViewCompatJb {
     static int getMaxLines(TextView textView) {
         return textView.getMaxLines();
diff --git a/compat/kitkat/android/support/v4/app/ActivityManagerCompatKitKat.java b/compat/kitkat/android/support/v4/app/ActivityManagerCompatKitKat.java
index f14b553..098c581 100644
--- a/compat/kitkat/android/support/v4/app/ActivityManagerCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/app/ActivityManagerCompatKitKat.java
@@ -18,10 +18,8 @@
 
 import android.app.ActivityManager;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(19)
-@TargetApi(19)
 class ActivityManagerCompatKitKat {
     public static boolean isLowRamDevice(ActivityManager am) {
         return am.isLowRamDevice();
diff --git a/transition/api23/android/support/transition/TransitionApi23.java b/compat/kitkat/android/support/v4/app/AlarmManagerCompatKitKat.java
similarity index 66%
copy from transition/api23/android/support/transition/TransitionApi23.java
copy to compat/kitkat/android/support/v4/app/AlarmManagerCompatKitKat.java
index 0df0ec5..4340bd9 100644
--- a/transition/api23/android/support/transition/TransitionApi23.java
+++ b/compat/kitkat/android/support/v4/app/AlarmManagerCompatKitKat.java
@@ -13,20 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package android.support.v4.app;
 
-package android.support.transition;
-
-import android.annotation.TargetApi;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
 import android.support.annotation.RequiresApi;
 
-@RequiresApi(23)
-@TargetApi(23)
-class TransitionApi23 extends TransitionKitKat {
+@RequiresApi(19)
+class AlarmManagerCompatKitKat {
 
-    @Override
-    public TransitionImpl removeTarget(int targetId) {
-        mTransition.removeTarget(targetId);
-        return this;
+    static void setExact(AlarmManager alarmManager, int type, long triggerAtMillis,
+            PendingIntent operation) {
+        alarmManager.setExact(type, triggerAtMillis, operation);
     }
-
 }
diff --git a/compat/kitkat/android/support/v4/app/NotificationCompatKitKat.java b/compat/kitkat/android/support/v4/app/NotificationCompatKitKat.java
index 5b11daf..c48d9ec 100644
--- a/compat/kitkat/android/support/v4/app/NotificationCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/app/NotificationCompatKitKat.java
@@ -22,7 +22,6 @@
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.util.SparseArray;
 import android.widget.RemoteViews;
 
@@ -30,7 +29,6 @@
 import java.util.List;
 
 @RequiresApi(19)
-@TargetApi(19)
 class NotificationCompatKitKat {
     public static class Builder implements NotificationBuilderWithBuilderAccessor,
             NotificationBuilderWithActions {
diff --git a/compat/kitkat/android/support/v4/app/NotificationManagerCompatKitKat.java b/compat/kitkat/android/support/v4/app/NotificationManagerCompatKitKat.java
index 24bacba..623db04 100644
--- a/compat/kitkat/android/support/v4/app/NotificationManagerCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/app/NotificationManagerCompatKitKat.java
@@ -19,14 +19,12 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 @RequiresApi(19)
-@TargetApi(19)
 class NotificationManagerCompatKitKat {
     private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
     private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
diff --git a/compat/kitkat/android/support/v4/content/ContextCompatKitKat.java b/compat/kitkat/android/support/v4/content/ContextCompatKitKat.java
index 6c1bc91..67d06a7 100644
--- a/compat/kitkat/android/support/v4/content/ContextCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/content/ContextCompatKitKat.java
@@ -18,12 +18,10 @@
 
 import android.content.Context;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import java.io.File;
 
 @RequiresApi(19)
-@TargetApi(19)
 class ContextCompatKitKat {
     public static File[] getExternalCacheDirs(Context context) {
         return context.getExternalCacheDirs();
diff --git a/compat/kitkat/android/support/v4/graphics/BitmapCompatKitKat.java b/compat/kitkat/android/support/v4/graphics/BitmapCompatKitKat.java
index ba05a32..d54c1aa 100644
--- a/compat/kitkat/android/support/v4/graphics/BitmapCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/graphics/BitmapCompatKitKat.java
@@ -17,14 +17,12 @@
 
 import android.graphics.Bitmap;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * Implementation of BitmapCompat that can use KitKat APIs.
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class BitmapCompatKitKat {
 
     static int getAllocationByteCount(Bitmap bitmap) {
diff --git a/compat/kitkat/android/support/v4/graphics/drawable/DrawableCompatKitKat.java b/compat/kitkat/android/support/v4/graphics/drawable/DrawableCompatKitKat.java
index b63ea3f..e5cee20 100644
--- a/compat/kitkat/android/support/v4/graphics/drawable/DrawableCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/graphics/drawable/DrawableCompatKitKat.java
@@ -18,14 +18,12 @@
 
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 /**
  * Implementation of drawable compatibility that can call KitKat APIs.
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class DrawableCompatKitKat {
     public static void setAutoMirrored(Drawable drawable, boolean mirrored) {
         drawable.setAutoMirrored(mirrored);
diff --git a/compat/kitkat/android/support/v4/graphics/drawable/DrawableWrapperKitKat.java b/compat/kitkat/android/support/v4/graphics/drawable/DrawableWrapperKitKat.java
index b758563..6eb3d2b 100644
--- a/compat/kitkat/android/support/v4/graphics/drawable/DrawableWrapperKitKat.java
+++ b/compat/kitkat/android/support/v4/graphics/drawable/DrawableWrapperKitKat.java
@@ -21,10 +21,8 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 @RequiresApi(19)
-@TargetApi(19)
 class DrawableWrapperKitKat extends DrawableWrapperHoneycomb {
 
     DrawableWrapperKitKat(Drawable drawable) {
diff --git a/compat/kitkat/android/support/v4/os/EnvironmentCompatKitKat.java b/compat/kitkat/android/support/v4/os/EnvironmentCompatKitKat.java
index b835950..c31acf6 100644
--- a/compat/kitkat/android/support/v4/os/EnvironmentCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/os/EnvironmentCompatKitKat.java
@@ -18,12 +18,10 @@
 
 import android.os.Environment;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 
 import java.io.File;
 
 @RequiresApi(19)
-@TargetApi(19)
 class EnvironmentCompatKitKat {
     public static String getStorageState(File path) {
         return Environment.getStorageState(path);
diff --git a/compat/kitkat/android/support/v4/view/ScaleGestureDetectorCompatKitKat.java b/compat/kitkat/android/support/v4/view/ScaleGestureDetectorCompatKitKat.java
index 7e873e4..36ede1b 100644
--- a/compat/kitkat/android/support/v4/view/ScaleGestureDetectorCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/view/ScaleGestureDetectorCompatKitKat.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.ScaleGestureDetector;
 
 /**
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class ScaleGestureDetectorCompatKitKat {
 
     private ScaleGestureDetectorCompatKitKat() {
diff --git a/compat/kitkat/android/support/v4/view/ViewCompatKitKat.java b/compat/kitkat/android/support/v4/view/ViewCompatKitKat.java
index d864e7b..221c2dd 100644
--- a/compat/kitkat/android/support/v4/view/ViewCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/view/ViewCompatKitKat.java
@@ -17,7 +17,6 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 
 /**
@@ -25,7 +24,6 @@
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class ViewCompatKitKat {
     public static int getAccessibilityLiveRegion(View view) {
         return view.getAccessibilityLiveRegion();
diff --git a/compat/kitkat/android/support/v4/view/ViewParentCompatKitKat.java b/compat/kitkat/android/support/v4/view/ViewParentCompatKitKat.java
index 5a00d0c..78761a4 100644
--- a/compat/kitkat/android/support/v4/view/ViewParentCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/view/ViewParentCompatKitKat.java
@@ -17,12 +17,10 @@
 package android.support.v4.view;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.ViewParent;
 
 @RequiresApi(19)
-@TargetApi(19)
 class ViewParentCompatKitKat {
     public static void notifySubtreeAccessibilityStateChanged(ViewParent parent, View child,
             View source, int changeType) {
diff --git a/compat/kitkat/android/support/v4/view/ViewPropertyAnimatorCompatKK.java b/compat/kitkat/android/support/v4/view/ViewPropertyAnimatorCompatKK.java
index f507a89..aa35239 100644
--- a/compat/kitkat/android/support/v4/view/ViewPropertyAnimatorCompatKK.java
+++ b/compat/kitkat/android/support/v4/view/ViewPropertyAnimatorCompatKK.java
@@ -16,12 +16,10 @@
 package android.support.v4.view;
 
 import android.animation.ValueAnimator;
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.view.View;
 
 @RequiresApi(19)
-@TargetApi(19)
 class ViewPropertyAnimatorCompatKK {
 
     public static void setUpdateListener(final View view,
diff --git a/compat/kitkat/android/support/v4/view/accessibility/AccessibilityEventCompatKitKat.java b/compat/kitkat/android/support/v4/view/accessibility/AccessibilityEventCompatKitKat.java
index 55e2faa..dbabe2f 100644
--- a/compat/kitkat/android/support/v4/view/accessibility/AccessibilityEventCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/view/accessibility/AccessibilityEventCompatKitKat.java
@@ -17,11 +17,9 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityEvent;
 
 @RequiresApi(19)
-@TargetApi(19)
 class AccessibilityEventCompatKitKat {
     public static  void setContentChangeTypes(AccessibilityEvent event, int changeTypes) {
         event.setContentChangeTypes(changeTypes);
diff --git a/compat/kitkat/android/support/v4/view/accessibility/AccessibilityManagerCompatKitKat.java b/compat/kitkat/android/support/v4/view/accessibility/AccessibilityManagerCompatKitKat.java
index cc94249..b8d742c 100644
--- a/compat/kitkat/android/support/v4/view/accessibility/AccessibilityManagerCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/view/accessibility/AccessibilityManagerCompatKitKat.java
@@ -17,7 +17,6 @@
 package android.support.v4.view.accessibility;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener;
 
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class AccessibilityManagerCompatKitKat {
 
     public static class TouchExplorationStateChangeListenerWrapper
diff --git a/compat/kitkat/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatKitKat.java b/compat/kitkat/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatKitKat.java
index 7bb8b1e..5855c0e 100644
--- a/compat/kitkat/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatKitKat.java
@@ -18,7 +18,6 @@
 
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 /**
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class AccessibilityNodeInfoCompatKitKat {
     private static final byte TRAIT_UNSET = -1;
     private static final String TRAITS_KEY =
diff --git a/compat/kitkat/android/support/v4/view/accessibility/AccessibilityNodeProviderCompatKitKat.java b/compat/kitkat/android/support/v4/view/accessibility/AccessibilityNodeProviderCompatKitKat.java
index a2bbbdc..892c48a 100644
--- a/compat/kitkat/android/support/v4/view/accessibility/AccessibilityNodeProviderCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/view/accessibility/AccessibilityNodeProviderCompatKitKat.java
@@ -18,7 +18,6 @@
 
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
 
@@ -29,7 +28,6 @@
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class AccessibilityNodeProviderCompatKitKat {
     interface AccessibilityNodeInfoBridge {
         public Object createAccessibilityNodeInfo(int virtualViewId);
diff --git a/compat/kitkat/android/support/v4/widget/ListPopupWindowCompatKitKat.java b/compat/kitkat/android/support/v4/widget/ListPopupWindowCompatKitKat.java
index 9678dba..1e11ea3 100644
--- a/compat/kitkat/android/support/v4/widget/ListPopupWindowCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/widget/ListPopupWindowCompatKitKat.java
@@ -17,7 +17,6 @@
 package android.support.v4.widget;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.view.View.OnTouchListener;
 import android.widget.ListPopupWindow;
@@ -27,7 +26,6 @@
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class ListPopupWindowCompatKitKat {
     public static OnTouchListener createDragToOpenListener(Object listPopupWindow, View src) {
         return ((ListPopupWindow) listPopupWindow).createDragToOpenListener(src);
diff --git a/compat/kitkat/android/support/v4/widget/ListViewCompatKitKat.java b/compat/kitkat/android/support/v4/widget/ListViewCompatKitKat.java
index ab2ff53..5dcc5b2 100644
--- a/compat/kitkat/android/support/v4/widget/ListViewCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/widget/ListViewCompatKitKat.java
@@ -17,11 +17,9 @@
 package android.support.v4.widget;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.widget.ListView;
 
 @RequiresApi(19)
-@TargetApi(19)
 class ListViewCompatKitKat {
     static void scrollListBy(final ListView listView, int y) {
         listView.scrollListBy(y);
diff --git a/compat/kitkat/android/support/v4/widget/PopupMenuCompatKitKat.java b/compat/kitkat/android/support/v4/widget/PopupMenuCompatKitKat.java
index da7bc7e..ed2b78c 100644
--- a/compat/kitkat/android/support/v4/widget/PopupMenuCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/widget/PopupMenuCompatKitKat.java
@@ -17,7 +17,6 @@
 package android.support.v4.widget;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View.OnTouchListener;
 import android.widget.PopupMenu;
 
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class PopupMenuCompatKitKat {
     public static OnTouchListener getDragToOpenListener(Object popupMenu) {
         return ((PopupMenu) popupMenu).getDragToOpenListener();
diff --git a/compat/kitkat/android/support/v4/widget/PopupWindowCompatKitKat.java b/compat/kitkat/android/support/v4/widget/PopupWindowCompatKitKat.java
index 20b0af4..887301f 100644
--- a/compat/kitkat/android/support/v4/widget/PopupWindowCompatKitKat.java
+++ b/compat/kitkat/android/support/v4/widget/PopupWindowCompatKitKat.java
@@ -17,7 +17,6 @@
 package android.support.v4.widget;
 
 import android.support.annotation.RequiresApi;
-import android.annotation.TargetApi;
 import android.view.View;
 import android.widget.PopupWindow;
 
@@ -26,7 +25,6 @@
  */
 
 @RequiresApi(19)
-@TargetApi(19)
 class PopupWindowCompatKitKat {
     public static void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff,
             int gravity) {
diff --git a/compat/tests/AndroidManifest.xml b/compat/tests/AndroidManifest.xml
index 8b44567..8a510ae 100644
--- a/compat/tests/AndroidManifest.xml
+++ b/compat/tests/AndroidManifest.xml
@@ -18,13 +18,14 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.compat.test">
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                       android.support.test.espresso, android.support.test.espresso.idling"/>
 
     <uses-permission android:name="android.permission.VIBRATE"/>
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
+    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
 
     <application
             android:supportsRtl="true"
diff --git a/compat/tests/java/android/support/v4/app/NotificationCompatTest.java b/compat/tests/java/android/support/v4/app/NotificationCompatTest.java
index 9978959..5b2a79b 100644
--- a/compat/tests/java/android/support/v4/app/NotificationCompatTest.java
+++ b/compat/tests/java/android/support/v4/app/NotificationCompatTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
@@ -27,6 +28,7 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v4.BaseInstrumentationTestCase;
+import android.support.v4.os.BuildCompat;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -34,12 +36,15 @@
 
 
 @RunWith(AndroidJUnit4.class)
+@SmallTest
 public class NotificationCompatTest extends BaseInstrumentationTestCase<TestSupportActivity> {
+    private static final String TEXT_RESULT_KEY = "text";
+    private static final String DATA_RESULT_KEY = "data";
 
     Context mContext;
 
     public NotificationCompatTest() {
-      super(TestSupportActivity.class);
+        super(TestSupportActivity.class);
     }
 
     @Before
@@ -47,18 +52,29 @@
         mContext = mActivityTestRule.getActivity();
     }
 
-    @SmallTest
+    @Test
+    public void testNotificationChannel() throws Throwable {
+        String channelId = "new ID";
+        Notification n  = new NotificationCompat.Builder(mActivityTestRule.getActivity())
+                .setChannel(channelId)
+                .build();
+        if (BuildCompat.isAtLeastO()) {
+            assertEquals(channelId, NotificationCompat.getChannel(n));
+        } else {
+            assertNull(NotificationCompat.getChannel(n));
+        }
+    }
+
     @Test
     public void testNotificationActionBuilder_copiesRemoteInputs() throws Throwable {
         NotificationCompat.Action a = newActionBuilder()
-                .addRemoteInput(new RemoteInput("a", "b", null, false, null)).build();
+                .addRemoteInput(new RemoteInput("a", "b", null, false, null, null)).build();
 
         NotificationCompat.Action aCopy = new NotificationCompat.Action.Builder(a).build();
 
         assertSame(a.getRemoteInputs()[0], aCopy.getRemoteInputs()[0]);
     }
 
-    @SmallTest
     @Test
     public void testNotificationActionBuilder_copiesAllowGeneratedReplies() throws Throwable {
         NotificationCompat.Action a = newActionBuilder()
@@ -69,7 +85,6 @@
         assertEquals(a.getAllowGeneratedReplies(), aCopy.getAllowGeneratedReplies());
     }
 
-    @SmallTest
     @Test
     public void testNotificationActionBuilder_defaultAllowGeneratedRepliesTrue() throws Throwable {
         NotificationCompat.Action a = newActionBuilder().build();
@@ -77,7 +92,6 @@
         assertTrue(a.getAllowGeneratedReplies());
     }
 
-    @SmallTest
     @Test
     public void testNotificationAction_defaultAllowGeneratedRepliesTrue() throws Throwable {
         NotificationCompat.Action a = new NotificationCompat.Action(0, null, null);
@@ -85,7 +99,6 @@
         assertTrue(a.getAllowGeneratedReplies());
     }
 
-    @SmallTest
     @Test
     public void testNotificationActionBuilder_setAllowGeneratedRepliesFalse() throws Throwable {
         NotificationCompat.Action a = newActionBuilder()
@@ -95,7 +108,6 @@
     }
 
     @SdkSuppress(minSdkVersion = 17)
-    @SmallTest
     @Test
     public void testNotificationWearableExtenderAction_setAllowGeneratedRepliesTrue()
             throws Throwable {
@@ -109,7 +121,6 @@
     }
 
     @SdkSuppress(minSdkVersion = 17)
-    @SmallTest
     @Test
     public void testNotificationWearableExtenderAction_setAllowGeneratedRepliesFalse()
             throws Throwable {
@@ -136,9 +147,47 @@
         assertTrue(new NotificationCompat.WearableExtender(notification).getActions().size() == 0);
     }
 
-    private NotificationCompat.Action.Builder newActionBuilder() {
+    @Test
+    public void testNotificationActionBuilder_setDataOnlyRemoteInput() throws Throwable {
+        NotificationCompat.Action a = newActionBuilder()
+                .addRemoteInput(newDataOnlyRemoteInput()).build();
+        RemoteInput[] textInputs = a.getRemoteInputs();
+        assertTrue(textInputs == null || textInputs.length == 0);
+        verifyRemoteInputArrayHasSingleResult(a.getDataOnlyRemoteInputs(), DATA_RESULT_KEY);
+    }
+
+    @Test
+    public void testNotificationActionBuilder_setTextAndDataOnlyRemoteInput() throws Throwable {
+        NotificationCompat.Action a = newActionBuilder()
+                .addRemoteInput(newDataOnlyRemoteInput())
+                .addRemoteInput(newTextRemoteInput())
+                .build();
+
+        verifyRemoteInputArrayHasSingleResult(a.getRemoteInputs(), TEXT_RESULT_KEY);
+        verifyRemoteInputArrayHasSingleResult(a.getDataOnlyRemoteInputs(), DATA_RESULT_KEY);
+    }
+
+    private static RemoteInput newDataOnlyRemoteInput() {
+        return new RemoteInput.Builder(DATA_RESULT_KEY)
+            .setAllowFreeFormInput(false)
+            .setAllowDataType("mimeType", true)
+            .build();
+    }
+
+    private static RemoteInput newTextRemoteInput() {
+        return new RemoteInput.Builder(TEXT_RESULT_KEY).build();  // allowFreeForm defaults to true
+    }
+
+    private static void verifyRemoteInputArrayHasSingleResult(
+            RemoteInput[] remoteInputs, String expectedResultKey) {
+        assertTrue(remoteInputs != null && remoteInputs.length == 1);
+        assertEquals(expectedResultKey, remoteInputs[0].getResultKey());
+    }
+
+    private static NotificationCompat.Action.Builder newActionBuilder() {
         return new NotificationCompat.Action.Builder(0, "title", null);
     }
+
     private NotificationCompat.Builder newNotificationBuilder() {
         return new NotificationCompat.Builder(mContext)
                 .setSmallIcon(0)
diff --git a/compat/tests/java/android/support/v4/app/RemoteInputTest.java b/compat/tests/java/android/support/v4/app/RemoteInputTest.java
new file mode 100644
index 0000000..08fdf0e
--- /dev/null
+++ b/compat/tests/java/android/support/v4/app/RemoteInputTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.app;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.BaseInstrumentationTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RemoteInputTest extends BaseInstrumentationTestCase<TestSupportActivity> {
+    private static final String RESULT_KEY = "result_key";  // value doesn't matter
+    private static final String MIME_TYPE = "mimeType";  // value doesn't matter
+
+    public RemoteInputTest() {
+        super(TestSupportActivity.class);
+    }
+
+    @Test
+    public void testRemoteInputBuilder_setDataOnly() throws Throwable {
+        RemoteInput input = newDataOnlyRemoteInput();
+
+        assertTrue(input.isDataOnly());
+        assertFalse(input.getAllowFreeFormInput());
+        assertTrue(input.getChoices() == null || input.getChoices().length == 0);
+        assertEquals(1, input.getAllowedDataTypes().size());
+        assertTrue(input.getAllowedDataTypes().contains(MIME_TYPE));
+    }
+
+    @Test
+    public void testRemoteInputBuilder_setTextOnly() throws Throwable {
+        RemoteInput input = newTextRemoteInput();
+
+        assertFalse(input.isDataOnly());
+        assertTrue(input.getAllowFreeFormInput());
+        assertTrue(input.getChoices() == null || input.getChoices().length == 0);
+        assertTrue(input.getAllowedDataTypes() == null || input.getAllowedDataTypes().isEmpty());
+    }
+
+    @Test
+    public void testRemoteInputBuilder_setChoicesOnly() throws Throwable {
+        RemoteInput input = newChoicesOnlyRemoteInput();
+
+        assertFalse(input.isDataOnly());
+        assertFalse(input.getAllowFreeFormInput());
+        assertTrue(input.getChoices() != null && input.getChoices().length > 0);
+        assertTrue(input.getAllowedDataTypes() == null || input.getAllowedDataTypes().isEmpty());
+    }
+
+    @Test
+    public void testRemoteInputBuilder_setDataAndTextAndChoices() throws Throwable {
+        CharSequence[] choices = new CharSequence[2];
+        choices[0] = "first";
+        choices[1] = "second";
+        RemoteInput input =
+                new RemoteInput.Builder(RESULT_KEY)
+                .setChoices(choices)
+                .setAllowDataType(MIME_TYPE, true)
+                .build();
+
+        assertFalse(input.isDataOnly());
+        assertTrue(input.getAllowFreeFormInput());
+        assertTrue(input.getChoices() != null && input.getChoices().length > 0);
+        assertEquals(1, input.getAllowedDataTypes().size());
+        assertTrue(input.getAllowedDataTypes().contains(MIME_TYPE));
+    }
+
+    @Test
+    public void testRemoteInputBuilder_addAndGetDataResultsFromIntent() throws Throwable {
+        Uri uri = Uri.parse("Some Uri");
+        RemoteInput input = newDataOnlyRemoteInput();
+        Intent intent = new Intent();
+        Map<String, Uri> putResults = new HashMap<>();
+        putResults.put(MIME_TYPE, uri);
+        RemoteInput.addDataResultToIntent(input, intent, putResults);
+
+        verifyIntentHasDataResults(intent, uri);
+    }
+
+    @Test
+    public void testRemoteInputBuilder_addAndGetTextResultsFromIntent() throws Throwable {
+        CharSequence charSequence = "value doesn't matter";
+        RemoteInput input = newTextRemoteInput();
+        Intent intent = new Intent();
+        Bundle putResults = new Bundle();
+        putResults.putCharSequence(input.getResultKey(), charSequence);
+        RemoteInput[] arr = new RemoteInput[1];
+        arr[0] = input;
+        RemoteInput.addResultsToIntent(arr, intent, putResults);
+
+        verifyIntentHasTextResults(intent, charSequence);
+    }
+
+    @SdkSuppress(minSdkVersion = 17)
+    @Test
+    public void testRemoteInputBuilder_addAndGetDataAndTextResultsFromIntentDataFirst()
+            throws Throwable {
+        CharSequence charSequence = "value doesn't matter";
+        Uri uri = Uri.parse("Some Uri");
+        RemoteInput input =
+                new RemoteInput.Builder(RESULT_KEY)
+                .setAllowDataType(MIME_TYPE, true)
+                .build();
+        Intent intent = new Intent();
+
+        Map<String, Uri> dataResults = new HashMap<>();
+        dataResults.put(MIME_TYPE, uri);
+        RemoteInput.addDataResultToIntent(input, intent, dataResults);
+
+        Bundle textResults = new Bundle();
+        textResults.putCharSequence(input.getResultKey(), charSequence);
+        RemoteInput[] arr = new RemoteInput[1];
+        arr[0] = input;
+        RemoteInput.addResultsToIntent(arr, intent, textResults);
+
+        verifyIntentHasTextResults(intent, charSequence);
+        verifyIntentHasDataResults(intent, uri);
+    }
+
+    @SdkSuppress(minSdkVersion = 17)
+    @Test
+    public void testRemoteInputBuilder_addAndGetDataAndTextResultsFromIntentTextFirst()
+            throws Throwable {
+        CharSequence charSequence = "value doesn't matter";
+        Uri uri = Uri.parse("Some Uri");
+        RemoteInput input =
+                new RemoteInput.Builder(RESULT_KEY)
+                .setAllowDataType(MIME_TYPE, true)
+                .build();
+        Intent intent = new Intent();
+
+        Bundle textResults = new Bundle();
+        textResults.putCharSequence(input.getResultKey(), charSequence);
+        RemoteInput[] arr = new RemoteInput[1];
+        arr[0] = input;
+        RemoteInput.addResultsToIntent(arr, intent, textResults);
+
+        Map<String, Uri> dataResults = new HashMap<>();
+        dataResults.put(MIME_TYPE, uri);
+        RemoteInput.addDataResultToIntent(input, intent, dataResults);
+
+        verifyIntentHasTextResults(intent, charSequence);
+        verifyIntentHasDataResults(intent, uri);
+    }
+
+    private static void verifyIntentHasTextResults(Intent intent, CharSequence expected) {
+        Bundle getResults = RemoteInput.getResultsFromIntent(intent);
+        assertNotNull(getResults);
+        assertTrue(getResults.containsKey(RESULT_KEY));
+        assertEquals(expected, getResults.getCharSequence(RESULT_KEY, "default"));
+    }
+
+    private static void verifyIntentHasDataResults(Intent intent, Uri expectedUri) {
+        Map<String, Uri> getResults = RemoteInput.getDataResultsFromIntent(intent, RESULT_KEY);
+        assertNotNull(getResults);
+        assertEquals(1, getResults.size());
+        assertTrue(getResults.containsKey(MIME_TYPE));
+        assertEquals(expectedUri, getResults.get(MIME_TYPE));
+    }
+
+    private static RemoteInput newTextRemoteInput() {
+        return new RemoteInput.Builder(RESULT_KEY).build();  // allowFreeForm defaults to true
+    }
+
+    private static RemoteInput newChoicesOnlyRemoteInput() {
+        CharSequence[] choices = new CharSequence[2];
+        choices[0] = "first";
+        choices[1] = "second";
+        return new RemoteInput.Builder(RESULT_KEY)
+            .setAllowFreeFormInput(false)
+            .setChoices(choices)
+            .build();
+    }
+
+    private static RemoteInput newDataOnlyRemoteInput() {
+        return new RemoteInput.Builder(RESULT_KEY)
+            .setAllowFreeFormInput(false)
+            .setAllowDataType(MIME_TYPE, true)
+            .build();
+    }
+}
diff --git a/compat/tests/java/android/support/v4/content/pm/ShortcutManagerCompatTest.java b/compat/tests/java/android/support/v4/content/pm/ShortcutManagerCompatTest.java
new file mode 100644
index 0000000..54a17c6
--- /dev/null
+++ b/compat/tests/java/android/support/v4/content/pm/ShortcutManagerCompatTest.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.content.pm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.TargetApi;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.graphics.Bitmap;
+import android.support.test.filters.LargeTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.BaseInstrumentationTestCase;
+import android.support.v4.app.TestSupportActivity;
+import android.support.v4.os.BuildCompat;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class ShortcutManagerCompatTest extends BaseInstrumentationTestCase<TestSupportActivity> {
+
+    Context mContext;
+    ShortcutInfoCompat mInfoCompat;
+
+    public ShortcutManagerCompatTest() {
+        super(TestSupportActivity.class);
+    }
+
+    @Before
+    public void setup() {
+        mContext = spy(mActivityTestRule.getActivity());
+        mInfoCompat = new ShortcutInfoCompat.Builder(mContext, "test-id")
+                .setIcon(Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888))
+                .setShortLabel("Test shortcut")
+                .setIntent(new Intent("Dummy"))
+                .build();
+    }
+
+    @Test
+    @SmallTest
+    @TargetApi(26)
+    public void testIsRequestPinShortcutSupported_v26() throws Throwable {
+        if (!BuildCompat.isAtLeastO()) {
+            return;
+        }
+
+        ShortcutManager mockShortcutManager = mock(ShortcutManager.class);
+        doReturn(mockShortcutManager).when(mContext).getSystemService(eq(Context.SHORTCUT_SERVICE));
+        when(mockShortcutManager.isRequestPinShortcutSupported()).thenReturn(true, false, true);
+
+        assertTrue(ShortcutManagerCompat.isRequestPinShortcutSupported(mContext));
+        assertFalse(ShortcutManagerCompat.isRequestPinShortcutSupported(mContext));
+        assertTrue(ShortcutManagerCompat.isRequestPinShortcutSupported(mContext));
+        verify(mockShortcutManager, times(3)).isRequestPinShortcutSupported();
+    }
+
+    @Test
+    @SmallTest
+    @TargetApi(26)
+    public void testRequestPinShortcut_v26()  throws Throwable {
+        if (!BuildCompat.isAtLeastO()) {
+            return;
+        }
+
+        ShortcutManager mockShortcutManager = mock(ShortcutManager.class);
+        doReturn(mockShortcutManager).when(mContext).getSystemService(eq(Context.SHORTCUT_SERVICE));
+        when(mockShortcutManager.requestPinShortcut(
+                any(ShortcutInfo.class), any(IntentSender.class))).thenReturn(true);
+
+        assertTrue(ShortcutManagerCompat.requestPinShortcut(mContext, mInfoCompat, null));
+        ArgumentCaptor<ShortcutInfo> captor = ArgumentCaptor.forClass(ShortcutInfo.class);
+        verify(mockShortcutManager, times(1)).requestPinShortcut(captor.capture(),
+                (IntentSender) isNull());
+        assertEquals("test-id", captor.getValue().getId());
+    }
+
+    @Test
+    @SmallTest
+    @TargetApi(26)
+    public void testCreateShortcutResultIntent_v26()  throws Throwable {
+        if (!BuildCompat.isAtLeastO()) {
+            return;
+        }
+
+        ShortcutManager mockShortcutManager = mock(ShortcutManager.class);
+        doReturn(mockShortcutManager).when(mContext).getSystemService(eq(Context.SHORTCUT_SERVICE));
+
+        when(mockShortcutManager.createShortcutResultIntent(any(ShortcutInfo.class)))
+                .thenReturn(new Intent("some-dummy-action"));
+
+        Intent result = ShortcutManagerCompat.createShortcutResultIntent(mContext, mInfoCompat);
+        verifyLegacyIntent(result);
+        assertEquals("some-dummy-action", result.getAction());
+
+        ArgumentCaptor<ShortcutInfo> captor = ArgumentCaptor.forClass(ShortcutInfo.class);
+        verify(mockShortcutManager, times(1)).createShortcutResultIntent(captor.capture());
+        assertEquals("test-id", captor.getValue().getId());
+    }
+
+    @SmallTest
+    @Test
+    public void testIsRequestPinShortcutSupported_v4() throws Throwable {
+        if (BuildCompat.isAtLeastO()) {
+            return;
+        }
+        setMockPm(mockResolveInfo(null));
+        assertTrue(ShortcutManagerCompat.isRequestPinShortcutSupported(mContext));
+
+        // We do not have the permission
+        setMockPm(mockResolveInfo("com.android.permission.something-we-dont-have"));
+        assertFalse(ShortcutManagerCompat.isRequestPinShortcutSupported(mContext));
+
+        // There are no receivers
+        setMockPm();
+        assertFalse(ShortcutManagerCompat.isRequestPinShortcutSupported(mContext));
+
+        // At least one receiver is supported
+        setMockPm(mockResolveInfo("com.android.permission.something-we-dont-have"),
+                mockResolveInfo(null));
+        assertTrue(ShortcutManagerCompat.isRequestPinShortcutSupported(mContext));
+
+        // We have the permission
+        setMockPm(mockResolveInfo(ShortcutManagerCompat.INSTALL_SHORTCUT_PERMISSION));
+        assertTrue(ShortcutManagerCompat.isRequestPinShortcutSupported(mContext));
+    }
+
+    @LargeTest
+    @Test
+    public void testRequestPinShortcut_v4_noCallback()  throws Throwable {
+        if (BuildCompat.isAtLeastO()) {
+            return;
+        }
+
+        setMockPm(mockResolveInfo(null));
+
+        BlockingBroadcastReceiver receiver =
+                new BlockingBroadcastReceiver(ShortcutManagerCompat.ACTION_INSTALL_SHORTCUT);
+        assertTrue(ShortcutManagerCompat.requestPinShortcut(mContext, mInfoCompat, null));
+        verifyLegacyIntent(receiver.blockingGetIntent());
+    }
+
+    @MediumTest
+    @Test
+    public void testRequestPinShortcut_v4_withCallback()  throws Throwable {
+        if (BuildCompat.isAtLeastO()) {
+            return;
+        }
+
+        setMockPm(mockResolveInfo(null));
+
+        BlockingBroadcastReceiver receiver =
+                new BlockingBroadcastReceiver(ShortcutManagerCompat.ACTION_INSTALL_SHORTCUT);
+        BlockingBroadcastReceiver callback =
+                new BlockingBroadcastReceiver("shortcut-callback");
+
+        assertTrue(ShortcutManagerCompat.requestPinShortcut(mContext, mInfoCompat,
+                PendingIntent.getBroadcast(mContext, 0, new Intent("shortcut-callback"),
+                        PendingIntent.FLAG_ONE_SHOT).getIntentSender()));
+        verifyLegacyIntent(receiver.blockingGetIntent());
+        assertNotNull(callback.blockingGetIntent());
+    }
+
+    @SmallTest
+    @Test
+    public void testCreateShortcutResultIntent_v4() throws Throwable {
+        if (BuildCompat.isAtLeastO()) {
+            return;
+        }
+
+        verifyLegacyIntent(ShortcutManagerCompat.createShortcutResultIntent(mContext, mInfoCompat));
+    }
+
+    private void verifyLegacyIntent(Intent intent) {
+        assertNotNull(intent);
+        assertEquals("Test shortcut", intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME));
+        assertEquals("Dummy", ((Intent) intent.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT))
+                .getAction());
+    }
+
+    private void setMockPm(ResolveInfo... infos) {
+        PackageManager pm = mock(PackageManager.class);
+        when(pm.queryBroadcastReceivers(any(Intent.class), anyInt()))
+                .thenReturn(Arrays.asList(infos));
+        reset(mContext);
+        doReturn(pm).when(mContext).getPackageManager();
+    }
+
+    private ResolveInfo mockResolveInfo(String permission) {
+        ActivityInfo aInfo = new ActivityInfo();
+        aInfo.packageName = mContext.getPackageName();
+        aInfo.permission = permission;
+        ResolveInfo rInfo = new ResolveInfo();
+        rInfo.activityInfo = aInfo;
+        return rInfo;
+    }
+
+    private class BlockingBroadcastReceiver extends BroadcastReceiver {
+
+        private final CountDownLatch mLatch = new CountDownLatch(1);
+        private Intent mIntent;
+
+        BlockingBroadcastReceiver(String action) {
+            mContext.registerReceiver(this, new IntentFilter(action));
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mIntent = intent;
+            mLatch.countDown();
+        }
+
+        public Intent blockingGetIntent() throws InterruptedException {
+            mLatch.await(5, TimeUnit.SECONDS);
+            mContext.unregisterReceiver(this);
+            return mIntent;
+        }
+    }
+}
diff --git a/compat/tests/java/android/support/v4/view/PointerIconCompatTest.java b/compat/tests/java/android/support/v4/view/PointerIconCompatTest.java
new file mode 100644
index 0000000..901c7ea
--- /dev/null
+++ b/compat/tests/java/android/support/v4/view/PointerIconCompatTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.v4.view;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.support.compat.test.R;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.BaseInstrumentationTestCase;
+import android.view.PointerIcon;
+import android.view.View;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class PointerIconCompatTest extends BaseInstrumentationTestCase<ViewCompatActivity> {
+
+    private View mView;
+    private Activity mActivity;
+
+    public PointerIconCompatTest() {
+        super(ViewCompatActivity.class);
+    }
+
+    @Before
+    public void setUp() {
+        mActivity = mActivityTestRule.getActivity();
+        mView = mActivity.findViewById(R.id.view);
+    }
+
+    private void compareSystemIcon(int type, int compatType) {
+        ViewCompat.setPointerIcon(mView, PointerIconCompat.getSystemIcon(mActivity, compatType));
+        assertEquals(PointerIcon.getSystemIcon(mActivity, type), mView.getPointerIcon());
+    }
+
+    @Test
+    @UiThreadTest
+    public void testSystemIcon() {
+        compareSystemIcon(PointerIcon.TYPE_ALIAS, PointerIconCompat.TYPE_ALIAS);
+        compareSystemIcon(PointerIcon.TYPE_ALL_SCROLL, PointerIconCompat.TYPE_ALL_SCROLL);
+        compareSystemIcon(PointerIcon.TYPE_ARROW, PointerIconCompat.TYPE_ARROW);
+        compareSystemIcon(PointerIcon.TYPE_CELL, PointerIconCompat.TYPE_CELL);
+        compareSystemIcon(PointerIcon.TYPE_CONTEXT_MENU, PointerIconCompat.TYPE_CONTEXT_MENU);
+        compareSystemIcon(PointerIcon.TYPE_COPY, PointerIconCompat.TYPE_COPY);
+        compareSystemIcon(PointerIcon.TYPE_CROSSHAIR, PointerIconCompat.TYPE_CROSSHAIR);
+        compareSystemIcon(PointerIcon.TYPE_DEFAULT, PointerIconCompat.TYPE_DEFAULT);
+        compareSystemIcon(PointerIcon.TYPE_GRAB, PointerIconCompat.TYPE_GRAB);
+        compareSystemIcon(PointerIcon.TYPE_GRABBING, PointerIconCompat.TYPE_GRABBING);
+        compareSystemIcon(PointerIcon.TYPE_HAND, PointerIconCompat.TYPE_HAND);
+        compareSystemIcon(PointerIcon.TYPE_HELP, PointerIconCompat.TYPE_HELP);
+        compareSystemIcon(PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW,
+                PointerIconCompat.TYPE_HORIZONTAL_DOUBLE_ARROW);
+        compareSystemIcon(PointerIcon.TYPE_NO_DROP, PointerIconCompat.TYPE_NO_DROP);
+        compareSystemIcon(PointerIcon.TYPE_NULL, PointerIconCompat.TYPE_NULL);
+        compareSystemIcon(PointerIcon.TYPE_TEXT, PointerIconCompat.TYPE_TEXT);
+        compareSystemIcon(PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW,
+                PointerIconCompat.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW);
+        compareSystemIcon(PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW,
+                PointerIconCompat.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW);
+        compareSystemIcon(PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW,
+                PointerIconCompat.TYPE_VERTICAL_DOUBLE_ARROW);
+        compareSystemIcon(PointerIcon.TYPE_VERTICAL_TEXT,
+                PointerIconCompat.TYPE_VERTICAL_TEXT);
+        compareSystemIcon(PointerIcon.TYPE_WAIT, PointerIconCompat.TYPE_WAIT);
+        compareSystemIcon(PointerIcon.TYPE_ZOOM_IN, PointerIconCompat.TYPE_ZOOM_IN);
+        compareSystemIcon(PointerIcon.TYPE_ZOOM_OUT, PointerIconCompat.TYPE_ZOOM_OUT);
+    }
+
+    @Test
+    @UiThreadTest
+    public void testNullIcon() {
+        ViewCompat.setPointerIcon(mView, null);
+        assertNull(mView.getPointerIcon());
+    }
+
+    @Test
+    @UiThreadTest
+    public void testBitmapIcon() {
+        Bitmap bitmap = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
+        ViewCompat.setPointerIcon(mView, PointerIconCompat.create(bitmap, 0, 0));
+        assertNotNull(mView.getPointerIcon());
+    }
+
+    @Test
+    @UiThreadTest
+    public void testResourceIcon() {
+        ViewCompat.setPointerIcon(mView,
+                PointerIconCompat.load(mActivity.getResources(), R.drawable.pointer_icon));
+        assertNotNull(mView.getPointerIcon());
+    }
+}
diff --git a/compat/tests/java/android/support/v4/view/ViewCompatTest.java b/compat/tests/java/android/support/v4/view/ViewCompatTest.java
index f107fd5..730260d 100644
--- a/compat/tests/java/android/support/v4/view/ViewCompatTest.java
+++ b/compat/tests/java/android/support/v4/view/ViewCompatTest.java
@@ -69,4 +69,11 @@
         assertNull(display);
     }
 
+    @Test
+    public void testTransitionName() {
+        final View view = new View(mActivityTestRule.getActivity());
+        ViewCompat.setTransitionName(view, "abc");
+        assertEquals("abc", ViewCompat.getTransitionName(view));
+    }
+
 }
diff --git a/transition/AndroidManifest-make.xml b/compat/tests/res/drawable/pointer_icon.xml
similarity index 77%
rename from transition/AndroidManifest-make.xml
rename to compat/tests/res/drawable/pointer_icon.xml
index 672e1b1..afb5a1a 100644
--- a/transition/AndroidManifest-make.xml
+++ b/compat/tests/res/drawable/pointer_icon.xml
@@ -13,8 +13,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.transition">
-    <uses-sdk android:minSdkVersion="14"/>
-    <application />
-</manifest>
+
+<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
+    android:bitmap="@drawable/test_drawable"
+    android:hotSpotX="16dp"
+    android:hotSpotY="16dp" />
diff --git a/core-ui/Android.mk b/core-ui/Android.mk
index eb9acca..9e4ad0e 100644
--- a/core-ui/Android.mk
+++ b/core-ui/Android.mk
@@ -27,13 +27,11 @@
 LOCAL_MODULE := android-support-core-ui
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := \
-    $(call all-java-files-under,honeycomb) \
     $(call all-java-files-under,ics) \
     $(call all-java-files-under,jellybean-mr2) \
     $(call all-java-files-under,api21) \
     $(call all-java-files-under,java)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-annotations
diff --git a/core-ui/AndroidManifest-make.xml b/core-ui/AndroidManifest-make.xml
deleted file mode 100644
index 9bcc44e..0000000
--- a/core-ui/AndroidManifest-make.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.support.coreui">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreui"/>
-    <application />
-</manifest>
diff --git a/core-ui/AndroidManifest.xml b/core-ui/AndroidManifest.xml
index 5357112..61eba66 100644
--- a/core-ui/AndroidManifest.xml
+++ b/core-ui/AndroidManifest.xml
@@ -16,7 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.coreui">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreui"/>
+    <uses-sdk android:minSdkVersion="14" tools:overrideLibrary="android.support.coreui"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/core-ui/api21/android/support/v4/widget/DrawerLayoutCompatApi21.java b/core-ui/api21/android/support/v4/widget/DrawerLayoutCompatApi21.java
index ff2e93d..f0612d1 100644
--- a/core-ui/api21/android/support/v4/widget/DrawerLayoutCompatApi21.java
+++ b/core-ui/api21/android/support/v4/widget/DrawerLayoutCompatApi21.java
@@ -17,7 +17,6 @@
 
 package android.support.v4.widget;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -31,7 +30,6 @@
  * Provides functionality for DrawerLayout unique to API 21
  */
 @RequiresApi(21)
-@TargetApi(21)
 class DrawerLayoutCompatApi21 {
 
     private static final int[] THEME_ATTRS = {
diff --git a/core-ui/build.gradle b/core-ui/build.gradle
index 0b94a96..c40022d 100644
--- a/core-ui/build.gradle
+++ b/core-ui/build.gradle
@@ -1,107 +1,46 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'support-core-ui'
 
 dependencies {
     compile project(':support-annotations')
     compile project(':support-compat')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile 'org.mockito:mockito-core:1.9.5'
-    androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
-    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
-    testCompile 'junit:junit:4.12'
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
-                'honeycomb',
                 'ics',
                 'jellybean-mr2',
                 'api21',
                 'java'
         ]
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/java'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
     }
 
     buildTypes.all {
         consumerProguardFiles 'proguard-rules.pro'
     }
 
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
-
     testOptions {
         unitTests.returnDefaultValues = true
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-        exclude('android/content/pm/**')
-        exclude('android/service/media/**')
-    }
-
-    artifacts.add('archives', sourcesJarTask);
+supportLibrary {
+    name 'Android Support Library v4'
+    inceptionYear '2011'
+    description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
 }
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Library v4'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/core-ui/honeycomb/android/support/v4/app/ActionBarDrawerToggleHoneycomb.java b/core-ui/ics/android/support/v4/app/ActionBarDrawerToggleIcs.java
similarity index 97%
rename from core-ui/honeycomb/android/support/v4/app/ActionBarDrawerToggleHoneycomb.java
rename to core-ui/ics/android/support/v4/app/ActionBarDrawerToggleIcs.java
index bd4fd97..7826f86 100644
--- a/core-ui/honeycomb/android/support/v4/app/ActionBarDrawerToggleHoneycomb.java
+++ b/core-ui/ics/android/support/v4/app/ActionBarDrawerToggleIcs.java
@@ -14,11 +14,9 @@
  * limitations under the License.
  */
 
-
 package android.support.v4.app;
 
 import android.R;
-import android.annotation.TargetApi;
 import android.app.ActionBar;
 import android.app.Activity;
 import android.content.res.TypedArray;
@@ -39,9 +37,8 @@
  * in an action bar without some really gross hacks. Since the MR2 SDK is not published as of
  * this writing, the new API is accessed via reflection here if available.
  */
-@RequiresApi(11)
-@TargetApi(11)
-class ActionBarDrawerToggleHoneycomb {
+@RequiresApi(14)
+class ActionBarDrawerToggleIcs {
     private static final String TAG = "ActionBarDrawerToggleHoneycomb";
 
     private static final int[] THEME_ATTRS = new int[] {
diff --git a/core-ui/ics/android/support/v4/view/PagerTitleStripIcs.java b/core-ui/ics/android/support/v4/view/PagerTitleStripIcs.java
index c8e70bd..c6c29b4 100644
--- a/core-ui/ics/android/support/v4/view/PagerTitleStripIcs.java
+++ b/core-ui/ics/android/support/v4/view/PagerTitleStripIcs.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.view;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 import android.text.method.SingleLineTransformationMethod;
@@ -26,7 +25,6 @@
 import java.util.Locale;
 
 @RequiresApi(14)
-@TargetApi(14)
 class PagerTitleStripIcs {
     public static void setSingleLineAllCaps(TextView text) {
         text.setTransformationMethod(new SingleLineAllCapsTransform(text.getContext()));
diff --git a/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java b/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
index 4c99341..f1ed0cf 100644
--- a/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
+++ b/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
@@ -17,7 +17,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -111,56 +110,31 @@
         Object setActionBarDescription(Object info, Activity activity, int contentDescRes);
     }
 
-    private static class ActionBarDrawerToggleImplBase implements ActionBarDrawerToggleImpl {
-        ActionBarDrawerToggleImplBase() {
-        }
-
-        @Override
-        public Drawable getThemeUpIndicator(Activity activity) {
-            return null;
-        }
-
-        @Override
-        public Object setActionBarUpIndicator(Object info, Activity activity,
-                Drawable themeImage, int contentDescRes) {
-            // No action bar to set.
-            return info;
-        }
-
-        @Override
-        public Object setActionBarDescription(Object info, Activity activity, int contentDescRes) {
-            // No action bar to set
-            return info;
-        }
-    }
-
     @RequiresApi(11)
-    @TargetApi(11)
-    private static class ActionBarDrawerToggleImplHC implements ActionBarDrawerToggleImpl {
-        ActionBarDrawerToggleImplHC() {
+    private static class ActionBarDrawerToggleImplIcs implements ActionBarDrawerToggleImpl {
+        ActionBarDrawerToggleImplIcs() {
         }
 
         @Override
         public Drawable getThemeUpIndicator(Activity activity) {
-            return ActionBarDrawerToggleHoneycomb.getThemeUpIndicator(activity);
+            return ActionBarDrawerToggleIcs.getThemeUpIndicator(activity);
         }
 
         @Override
         public Object setActionBarUpIndicator(Object info, Activity activity,
                 Drawable themeImage, int contentDescRes) {
-            return ActionBarDrawerToggleHoneycomb.setActionBarUpIndicator(info, activity,
+            return ActionBarDrawerToggleIcs.setActionBarUpIndicator(info, activity,
                     themeImage, contentDescRes);
         }
 
         @Override
         public Object setActionBarDescription(Object info, Activity activity, int contentDescRes) {
-            return ActionBarDrawerToggleHoneycomb.setActionBarDescription(info, activity,
+            return ActionBarDrawerToggleIcs.setActionBarDescription(info, activity,
                     contentDescRes);
         }
     }
 
     @RequiresApi(18)
-    @TargetApi(18)
     private static class ActionBarDrawerToggleImplJellybeanMR2
             implements ActionBarDrawerToggleImpl {
         ActionBarDrawerToggleImplJellybeanMR2() {
@@ -188,13 +162,10 @@
     private static final ActionBarDrawerToggleImpl IMPL;
 
     static {
-        final int version = Build.VERSION.SDK_INT;
-        if (version >= 18) {
+        if (Build.VERSION.SDK_INT >= 18) {
             IMPL = new ActionBarDrawerToggleImplJellybeanMR2();
-        } else if (version >= 11) {
-            IMPL = new ActionBarDrawerToggleImplHC();
         } else {
-            IMPL = new ActionBarDrawerToggleImplBase();
+            IMPL = new ActionBarDrawerToggleImplIcs();
         }
     }
 
diff --git a/core-ui/java/android/support/v4/view/PagerTitleStrip.java b/core-ui/java/android/support/v4/view/PagerTitleStrip.java
index d569cd4..695e793 100644
--- a/core-ui/java/android/support/v4/view/PagerTitleStrip.java
+++ b/core-ui/java/android/support/v4/view/PagerTitleStrip.java
@@ -27,6 +27,7 @@
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.Gravity;
+import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.widget.TextView;
@@ -454,9 +455,9 @@
             height = Math.max(minHeight, textHeight + heightPadding);
         }
 
-        final int childState = ViewCompat.getMeasuredState(mCurrText);
-        final int measuredHeight = ViewCompat.resolveSizeAndState(height, heightMeasureSpec,
-                childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
+        final int childState = mCurrText.getMeasuredState();
+        final int measuredHeight = View.resolveSizeAndState(height, heightMeasureSpec,
+                childState << View.MEASURED_HEIGHT_STATE_SHIFT);
         setMeasuredDimension(widthSize, measuredHeight);
     }
 
diff --git a/core-ui/java/android/support/v4/view/ViewPager.java b/core-ui/java/android/support/v4/view/ViewPager.java
index 47d224f..c897789 100644
--- a/core-ui/java/android/support/v4/view/ViewPager.java
+++ b/core-ui/java/android/support/v4/view/ViewPager.java
@@ -60,7 +60,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -241,7 +240,6 @@
     private List<OnAdapterChangeListener> mAdapterChangeListeners;
     private PageTransformer mPageTransformer;
     private int mPageTransformerLayerType;
-    private Method mSetChildrenDrawingOrderEnabled;
 
     private static final int DRAW_ORDER_DEFAULT = 0;
     private static final int DRAW_ORDER_FORWARD = 1;
@@ -751,22 +749,20 @@
      * the scroll position is changed. This allows the application to apply custom property
      * transformations to each page, overriding the default sliding behavior.
      *
-     * <p><em>Note:</em> Prior to Android 3.0 the property animation APIs did not exist.
-     * As a result, setting a PageTransformer prior to Android 3.0 (API 11) will have no effect.
-     * By default, calling this method will cause contained pages to use
-     * {@link ViewCompat#LAYER_TYPE_HARDWARE}. This layer type allows custom alpha transformations,
+     * <p><em>Note:</em> By default, calling this method will cause contained pages to use
+     * {@link View#LAYER_TYPE_HARDWARE}. This layer type allows custom alpha transformations,
      * but it will cause issues if any of your pages contain a {@link android.view.SurfaceView}
      * and you have not called {@link android.view.SurfaceView#setZOrderOnTop(boolean)} to put that
      * {@link android.view.SurfaceView} above your app content. To disable this behavior, call
      * {@link #setPageTransformer(boolean,PageTransformer,int)} and pass
-     * {@link ViewCompat#LAYER_TYPE_NONE} for {@code pageLayerType}.</p>
+     * {@link View#LAYER_TYPE_NONE} for {@code pageLayerType}.</p>
      *
      * @param reverseDrawingOrder true if the supplied PageTransformer requires page views
      *                            to be drawn from last to first instead of first to last.
      * @param transformer PageTransformer that will modify each page's animation properties
      */
     public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) {
-        setPageTransformer(reverseDrawingOrder, transformer, ViewCompat.LAYER_TYPE_HARDWARE);
+        setPageTransformer(reverseDrawingOrder, transformer, View.LAYER_TYPE_HARDWARE);
     }
 
     /**
@@ -774,51 +770,27 @@
      * the scroll position is changed. This allows the application to apply custom property
      * transformations to each page, overriding the default sliding behavior.
      *
-     * <p><em>Note:</em> Prior to Android 3.0 ({@link Build.VERSION_CODES#HONEYCOMB API 11}),
-     * the property animation APIs did not exist. As a result, setting a PageTransformer prior
-     * to API 11 will have no effect.</p>
-     *
      * @param reverseDrawingOrder true if the supplied PageTransformer requires page views
      *                            to be drawn from last to first instead of first to last.
      * @param transformer PageTransformer that will modify each page's animation properties
      * @param pageLayerType View layer type that should be used for ViewPager pages. It should be
-     *                      either {@link ViewCompat#LAYER_TYPE_HARDWARE},
-     *                      {@link ViewCompat#LAYER_TYPE_SOFTWARE}, or
-     *                      {@link ViewCompat#LAYER_TYPE_NONE}.
+     *                      either {@link View#LAYER_TYPE_HARDWARE},
+     *                      {@link View#LAYER_TYPE_SOFTWARE}, or
+     *                      {@link View#LAYER_TYPE_NONE}.
      */
     public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer,
             int pageLayerType) {
-        if (Build.VERSION.SDK_INT >= 11) {
-            final boolean hasTransformer = transformer != null;
-            final boolean needsPopulate = hasTransformer != (mPageTransformer != null);
-            mPageTransformer = transformer;
-            setChildrenDrawingOrderEnabledCompat(hasTransformer);
-            if (hasTransformer) {
-                mDrawingOrder = reverseDrawingOrder ? DRAW_ORDER_REVERSE : DRAW_ORDER_FORWARD;
-                mPageTransformerLayerType = pageLayerType;
-            } else {
-                mDrawingOrder = DRAW_ORDER_DEFAULT;
-            }
-            if (needsPopulate) populate();
+        final boolean hasTransformer = transformer != null;
+        final boolean needsPopulate = hasTransformer != (mPageTransformer != null);
+        mPageTransformer = transformer;
+        setChildrenDrawingOrderEnabled(hasTransformer);
+        if (hasTransformer) {
+            mDrawingOrder = reverseDrawingOrder ? DRAW_ORDER_REVERSE : DRAW_ORDER_FORWARD;
+            mPageTransformerLayerType = pageLayerType;
+        } else {
+            mDrawingOrder = DRAW_ORDER_DEFAULT;
         }
-    }
-
-    void setChildrenDrawingOrderEnabledCompat(boolean enable) {
-        if (Build.VERSION.SDK_INT >= 7) {
-            if (mSetChildrenDrawingOrderEnabled == null) {
-                try {
-                    mSetChildrenDrawingOrderEnabled = ViewGroup.class.getDeclaredMethod(
-                            "setChildrenDrawingOrderEnabled", new Class[] { Boolean.TYPE });
-                } catch (NoSuchMethodException e) {
-                    Log.e(TAG, "Can't find setChildrenDrawingOrderEnabled", e);
-                }
-            }
-            try {
-                mSetChildrenDrawingOrderEnabled.invoke(this, enable);
-            } catch (Exception e) {
-                Log.e(TAG, "Error changing children drawing order", e);
-            }
-        }
+        if (needsPopulate) populate();
     }
 
     @Override
@@ -2035,8 +2007,8 @@
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             final int layerType = enable
-                    ? mPageTransformerLayerType : ViewCompat.LAYER_TYPE_NONE;
-            ViewCompat.setLayerType(getChildAt(i), layerType, null);
+                    ? mPageTransformerLayerType : View.LAYER_TYPE_NONE;
+            getChildAt(i).setLayerType(layerType, null);
         }
     }
 
@@ -2266,8 +2238,7 @@
                 if (mIsBeingDragged) {
                     final VelocityTracker velocityTracker = mVelocityTracker;
                     velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                    int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(
-                            velocityTracker, mActivePointerId);
+                    int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);
                     mPopulatePending = true;
                     final int width = getClientWidth();
                     final int scrollX = getScrollX();
@@ -2575,8 +2546,7 @@
         if (mAdapter != null) {
             final VelocityTracker velocityTracker = mVelocityTracker;
             velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-            int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(
-                    velocityTracker, mActivePointerId);
+            int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);
             mPopulatePending = true;
             final int width = getClientWidth();
             final int scrollX = getScrollX();
diff --git a/core-ui/java/android/support/v4/widget/CircleImageView.java b/core-ui/java/android/support/v4/widget/CircleImageView.java
index e582882..24a175d 100644
--- a/core-ui/java/android/support/v4/widget/CircleImageView.java
+++ b/core-ui/java/android/support/v4/widget/CircleImageView.java
@@ -26,6 +26,7 @@
 import android.graphics.drawable.shapes.OvalShape;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.view.ViewCompat;
+import android.view.View;
 import android.view.animation.Animation;
 import android.widget.ImageView;
 
@@ -62,7 +63,7 @@
         } else {
             OvalShape oval = new OvalShadow(mShadowRadius);
             circle = new ShapeDrawable(oval);
-            ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, circle.getPaint());
+            setLayerType(View.LAYER_TYPE_SOFTWARE, circle.getPaint());
             circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset,
                     KEY_SHADOW_COLOR);
             final int padding = mShadowRadius;
diff --git a/core-ui/java/android/support/v4/widget/NestedScrollView.java b/core-ui/java/android/support/v4/widget/NestedScrollView.java
index 44cc043..da44ccb 100644
--- a/core-ui/java/android/support/v4/widget/NestedScrollView.java
+++ b/core-ui/java/android/support/v4/widget/NestedScrollView.java
@@ -35,7 +35,6 @@
 import android.support.v4.view.NestedScrollingParent;
 import android.support.v4.view.NestedScrollingParentHelper;
 import android.support.v4.view.ScrollingView;
-import android.support.v4.view.VelocityTrackerCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
@@ -834,8 +833,7 @@
                 if (mIsBeingDragged) {
                     final VelocityTracker velocityTracker = mVelocityTracker;
                     velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                    int initialVelocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker,
-                            mActivePointerId);
+                    int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
 
                     if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
                         flingWithNestedDispatch(-initialVelocity);
diff --git a/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java b/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
index 1e5479b..00b5bd0 100644
--- a/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
+++ b/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
@@ -985,11 +985,11 @@
                 lp.dimPaint = new Paint();
             }
             lp.dimPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_OVER));
-            if (ViewCompat.getLayerType(v) != ViewCompat.LAYER_TYPE_HARDWARE) {
-                ViewCompat.setLayerType(v, ViewCompat.LAYER_TYPE_HARDWARE, lp.dimPaint);
+            if (v.getLayerType() != View.LAYER_TYPE_HARDWARE) {
+                v.setLayerType(View.LAYER_TYPE_HARDWARE, lp.dimPaint);
             }
             invalidateChildRegion(v);
-        } else if (ViewCompat.getLayerType(v) != ViewCompat.LAYER_TYPE_NONE) {
+        } else if (v.getLayerType() != View.LAYER_TYPE_NONE) {
             if (lp.dimPaint != null) {
                 lp.dimPaint.setColorFilter(null);
             }
@@ -1654,7 +1654,7 @@
         @Override
         public void run() {
             if (mChildView.getParent() == SlidingPaneLayout.this) {
-                ViewCompat.setLayerType(mChildView, ViewCompat.LAYER_TYPE_NONE, null);
+                mChildView.setLayerType(View.LAYER_TYPE_NONE, null);
                 invalidateChildRegion(mChildView);
             }
             mPostedRunnables.remove(this);
diff --git a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
index 107b9e0..4f5b6f1 100644
--- a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
+++ b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
@@ -205,8 +205,7 @@
         if (mScale) {
             setAnimationProgress(0 /* animation complete and view is hidden */);
         } else {
-            setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCurrentTargetOffsetTop,
-                    true /* requires update */);
+            setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCurrentTargetOffsetTop);
         }
         mCurrentTargetOffsetTop = mCircleView.getTop();
     }
@@ -396,13 +395,6 @@
     }
 
     /**
-     * Pre API 11, alpha is used to make the progress circle appear instead of scale.
-     */
-    private boolean isAlphaUsedForScale() {
-        return android.os.Build.VERSION.SDK_INT < 11;
-    }
-
-    /**
      * Notify the widget that refresh state has changed. Do not call this when
      * refresh is triggered by a swipe gesture.
      *
@@ -418,8 +410,7 @@
             } else {
                 endTarget = mSpinnerOffsetEnd;
             }
-            setTargetOffsetTopAndBottom(endTarget - mCurrentTargetOffsetTop,
-                    true /* requires update */);
+            setTargetOffsetTopAndBottom(endTarget - mCurrentTargetOffsetTop);
             mNotify = false;
             startScaleUpAnimation(mRefreshListener);
         } else {
@@ -455,12 +446,8 @@
      * @param progress
      */
     void setAnimationProgress(float progress) {
-        if (isAlphaUsedForScale()) {
-            setColorViewAlpha((int) (progress * MAX_ALPHA));
-        } else {
-            ViewCompat.setScaleX(mCircleView, progress);
-            ViewCompat.setScaleY(mCircleView, progress);
-        }
+        mCircleView.setScaleX(progress);
+        mCircleView.setScaleY(progress);
     }
 
     private void setRefreshing(boolean refreshing, final boolean notify) {
@@ -489,23 +476,15 @@
         mCircleView.startAnimation(mScaleDownAnimation);
     }
 
-    @SuppressLint("NewApi")
     private void startProgressAlphaStartAnimation() {
         mAlphaStartAnimation = startAlphaAnimation(mProgress.getAlpha(), STARTING_PROGRESS_ALPHA);
     }
 
-    @SuppressLint("NewApi")
     private void startProgressAlphaMaxAnimation() {
         mAlphaMaxAnimation = startAlphaAnimation(mProgress.getAlpha(), MAX_ALPHA);
     }
 
-    @SuppressLint("NewApi")
     private Animation startAlphaAnimation(final int startingAlpha, final int endingAlpha) {
-        // Pre API 11, alpha is used in place of scale. Don't also use it to
-        // show the trigger point.
-        if (mScale && isAlphaUsedForScale()) {
-            return null;
-        }
         Animation alpha = new Animation() {
             @Override
             public void applyTransformation(float interpolatedTime, Transformation t) {
@@ -683,18 +662,7 @@
         if (mChildScrollUpCallback != null) {
             return mChildScrollUpCallback.canChildScrollUp(this, mTarget);
         }
-        if (android.os.Build.VERSION.SDK_INT < 14) {
-            if (mTarget instanceof AbsListView) {
-                final AbsListView absListView = (AbsListView) mTarget;
-                return absListView.getChildCount() > 0
-                        && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
-                                .getTop() < absListView.getPaddingTop());
-            } else {
-                return ViewCompat.canScrollVertically(mTarget, -1) || mTarget.getScrollY() > 0;
-            }
-        } else {
-            return ViewCompat.canScrollVertically(mTarget, -1);
-        }
+        return ViewCompat.canScrollVertically(mTarget, -1);
     }
 
     /**
@@ -725,7 +693,7 @@
 
         switch (action) {
             case MotionEvent.ACTION_DOWN:
-                setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCircleView.getTop(), true);
+                setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCircleView.getTop());
                 mActivePointerId = ev.getPointerId(0);
                 mIsBeingDragged = false;
 
@@ -953,8 +921,8 @@
             mCircleView.setVisibility(View.VISIBLE);
         }
         if (!mScale) {
-            ViewCompat.setScaleX(mCircleView, 1f);
-            ViewCompat.setScaleY(mCircleView, 1f);
+            mCircleView.setScaleX(1f);
+            mCircleView.setScaleY(1f);
         }
 
         if (mScale) {
@@ -978,7 +946,7 @@
 
         float rotation = (-0.25f + .4f * adjustedPercent + tensionPercent * 2) * .5f;
         mProgress.setProgressRotation(rotation);
-        setTargetOffsetTopAndBottom(targetY - mCurrentTargetOffsetTop, true /* requires update */);
+        setTargetOffsetTopAndBottom(targetY - mCurrentTargetOffsetTop);
     }
 
     private void finishSpinner(float overscrollTop) {
@@ -1144,7 +1112,7 @@
             }
             targetTop = (mFrom + (int) ((endTarget - mFrom) * interpolatedTime));
             int offset = targetTop - mCircleView.getTop();
-            setTargetOffsetTopAndBottom(offset, false /* requires update */);
+            setTargetOffsetTopAndBottom(offset);
             mProgress.setArrowScale(1 - interpolatedTime);
         }
     };
@@ -1153,7 +1121,7 @@
         int targetTop = 0;
         targetTop = (mFrom + (int) ((mOriginalOffsetTop - mFrom) * interpolatedTime));
         int offset = targetTop - mCircleView.getTop();
-        setTargetOffsetTopAndBottom(offset, false /* requires update */);
+        setTargetOffsetTopAndBottom(offset);
     }
 
     private final Animation mAnimateToStartPosition = new Animation() {
@@ -1167,11 +1135,7 @@
     private void startScaleDownReturnToStartAnimation(int from,
             Animation.AnimationListener listener) {
         mFrom = from;
-        if (isAlphaUsedForScale()) {
-            mStartingScale = mProgress.getAlpha();
-        } else {
-            mStartingScale = ViewCompat.getScaleX(mCircleView);
-        }
+        mStartingScale = mCircleView.getScaleX();
         mScaleDownToStartAnimation = new Animation() {
             @Override
             public void applyTransformation(float interpolatedTime, Transformation t) {
@@ -1188,13 +1152,10 @@
         mCircleView.startAnimation(mScaleDownToStartAnimation);
     }
 
-    void setTargetOffsetTopAndBottom(int offset, boolean requiresUpdate) {
+    void setTargetOffsetTopAndBottom(int offset) {
         mCircleView.bringToFront();
         ViewCompat.offsetTopAndBottom(mCircleView, offset);
         mCurrentTargetOffsetTop = mCircleView.getTop();
-        if (requiresUpdate && android.os.Build.VERSION.SDK_INT < 11) {
-            invalidate();
-        }
     }
 
     private void onSecondaryPointerUp(MotionEvent ev) {
diff --git a/core-ui/java/android/support/v4/widget/ViewDragHelper.java b/core-ui/java/android/support/v4/widget/ViewDragHelper.java
index 171e292..5833708 100644
--- a/core-ui/java/android/support/v4/widget/ViewDragHelper.java
+++ b/core-ui/java/android/support/v4/widget/ViewDragHelper.java
@@ -19,7 +19,6 @@
 
 import android.content.Context;
 import android.support.v4.view.MotionEventCompat;
-import android.support.v4.view.VelocityTrackerCompat;
 import android.support.v4.view.ViewCompat;
 import android.util.Log;
 import android.view.MotionEvent;
@@ -570,8 +569,8 @@
         }
 
         return forceSettleCapturedViewAt(finalLeft, finalTop,
-                (int) VelocityTrackerCompat.getXVelocity(mVelocityTracker, mActivePointerId),
-                (int) VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId));
+                (int) mVelocityTracker.getXVelocity(mActivePointerId),
+                (int) mVelocityTracker.getYVelocity(mActivePointerId));
     }
 
     /**
@@ -703,8 +702,8 @@
         }
 
         mScroller.fling(mCapturedView.getLeft(), mCapturedView.getTop(),
-                (int) VelocityTrackerCompat.getXVelocity(mVelocityTracker, mActivePointerId),
-                (int) VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId),
+                (int) mVelocityTracker.getXVelocity(mActivePointerId),
+                (int) mVelocityTracker.getYVelocity(mActivePointerId),
                 minLeft, maxLeft, minTop, maxTop);
 
         setDragState(STATE_SETTLING);
@@ -1405,10 +1404,10 @@
     private void releaseViewForPointerUp() {
         mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
         final float xvel = clampMag(
-                VelocityTrackerCompat.getXVelocity(mVelocityTracker, mActivePointerId),
+                mVelocityTracker.getXVelocity(mActivePointerId),
                 mMinVelocity, mMaxVelocity);
         final float yvel = clampMag(
-                VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId),
+                mVelocityTracker.getYVelocity(mActivePointerId),
                 mMinVelocity, mMaxVelocity);
         dispatchViewReleased(xvel, yvel);
     }
diff --git a/core-ui/jellybean-mr2/android/support/v4/app/ActionBarDrawerToggleJellybeanMR2.java b/core-ui/jellybean-mr2/android/support/v4/app/ActionBarDrawerToggleJellybeanMR2.java
index f4dba39..40d180c 100644
--- a/core-ui/jellybean-mr2/android/support/v4/app/ActionBarDrawerToggleJellybeanMR2.java
+++ b/core-ui/jellybean-mr2/android/support/v4/app/ActionBarDrawerToggleJellybeanMR2.java
@@ -18,7 +18,6 @@
 package android.support.v4.app;
 
 import android.R;
-import android.annotation.TargetApi;
 import android.app.ActionBar;
 import android.app.Activity;
 import android.content.Context;
@@ -27,7 +26,6 @@
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(18)
-@TargetApi(18)
 class ActionBarDrawerToggleJellybeanMR2 {
     private static final String TAG = "ActionBarDrawerToggleImplJellybeanMR2";
 
diff --git a/core-ui/tests/AndroidManifest.xml b/core-ui/tests/AndroidManifest.xml
index 7c39d4d..30afa2c 100644
--- a/core-ui/tests/AndroidManifest.xml
+++ b/core-ui/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.coreui.test">
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                       android.support.test.espresso, android.support.test.espresso.idling"/>
diff --git a/core-ui/tests/java/android/support/v4/view/BaseViewPagerTest.java b/core-ui/tests/java/android/support/v4/view/BaseViewPagerTest.java
index 0631299..dfa7a22 100644
--- a/core-ui/tests/java/android/support/v4/view/BaseViewPagerTest.java
+++ b/core-ui/tests/java/android/support/v4/view/BaseViewPagerTest.java
@@ -61,8 +61,8 @@
 import android.graphics.Color;
 import android.support.coreui.test.R;
 import android.support.test.espresso.ViewAction;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
-import android.support.test.filters.SmallTest;
 import android.support.v4.BaseInstrumentationTestCase;
 import android.support.v4.testutils.TestUtilsMatchers;
 import android.text.TextUtils;
@@ -282,13 +282,13 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testPageSelectionsImmediate() {
         verifyPageSelections(false);
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testPageSelectionsSmooth() {
         verifyPageSelections(true);
     }
@@ -355,7 +355,7 @@
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     public void testPageSwipes() {
         verifyPageChangeViewActions(wrap(swipeLeft()), wrap(swipeRight()));
     }
@@ -367,7 +367,7 @@
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testPageSwipesComposite() {
         assertEquals("Initial state", 0, mViewPager.getCurrentItem());
 
@@ -425,13 +425,13 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testPageContentImmediate() {
         verifyPageContent(false);
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testPageContentSmooth() {
         verifyPageContent(true);
     }
@@ -504,13 +504,13 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testAdapterChangeImmediate() {
         verifyAdapterChange(false);
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testAdapterChangeSmooth() {
         verifyAdapterChange(true);
     }
@@ -603,13 +603,13 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testPagerStripImmediate() {
         verifyPagerStrip(false);
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testPagerStripSmooth() {
         verifyPagerStrip(true);
     }
@@ -660,7 +660,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testPageScrollStateChangedImmediate() {
         // Note that all the actions tested in this method are immediate (no scrolling) and
         // as such we test that we do not get any calls to onPageScrollStateChanged in any of them
@@ -984,7 +984,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testPageScrollPositionChangesImmediate() {
         // Scroll one page to the right
         verifyScrollCallbacksToHigherPage(scrollRight(false), 1);
diff --git a/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java b/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java
index 4a10559..cdbc2cb 100644
--- a/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java
+++ b/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java
@@ -34,6 +34,7 @@
 
 import android.support.coreui.test.R;
 import android.support.test.espresso.action.ViewActions;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.v4.BaseInstrumentationTestCase;
@@ -141,7 +142,7 @@
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testSwipeDownToRefreshInitiallyDisabled() throws Throwable {
         mActivityTestRule.runOnUiThread(new Runnable() {
             @Override
diff --git a/core-utils/Android.mk b/core-utils/Android.mk
index a65a2cd..d3f113e 100644
--- a/core-utils/Android.mk
+++ b/core-utils/Android.mk
@@ -37,7 +37,6 @@
     $(call all-java-files-under,api24) \
     $(call all-java-files-under,java)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-annotations
diff --git a/core-utils/AndroidManifest-make.xml b/core-utils/AndroidManifest-make.xml
deleted file mode 100644
index 586a28e..0000000
--- a/core-utils/AndroidManifest-make.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.support.coreutils">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreutils"/>
-    <application />
-</manifest>
diff --git a/core-utils/AndroidManifest.xml b/core-utils/AndroidManifest.xml
index 03ff3b4..b3b404b 100644
--- a/core-utils/AndroidManifest.xml
+++ b/core-utils/AndroidManifest.xml
@@ -16,7 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.coreutils">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreutils"/>
+    <uses-sdk android:minSdkVersion="14" tools:overrideLibrary="android.support.coreutils"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/core-utils/api20/android/support/v4/print/PrintHelperApi20.java b/core-utils/api20/android/support/v4/print/PrintHelperApi20.java
index 831e9dd..54699a5 100644
--- a/core-utils/api20/android/support/v4/print/PrintHelperApi20.java
+++ b/core-utils/api20/android/support/v4/print/PrintHelperApi20.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.print;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 
@@ -24,7 +23,6 @@
  * Api20 specific PrintManager API implementation.
  */
 @RequiresApi(20)
-@TargetApi(20)
 class PrintHelperApi20 extends PrintHelperKitkat {
     PrintHelperApi20(Context context) {
         super(context);
diff --git a/core-utils/api21/android/support/v4/graphics/drawable/RoundedBitmapDrawable21.java b/core-utils/api21/android/support/v4/graphics/drawable/RoundedBitmapDrawable21.java
index d521293..2aa4345 100644
--- a/core-utils/api21/android/support/v4/graphics/drawable/RoundedBitmapDrawable21.java
+++ b/core-utils/api21/android/support/v4/graphics/drawable/RoundedBitmapDrawable21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.graphics.drawable;
 
-import android.annotation.TargetApi;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Outline;
@@ -26,7 +25,6 @@
 import android.view.View;
 
 @RequiresApi(21)
-@TargetApi(21)
 class RoundedBitmapDrawable21 extends RoundedBitmapDrawable {
     protected RoundedBitmapDrawable21(Resources res, Bitmap bitmap) {
         super(res, bitmap);
diff --git a/core-utils/api21/android/support/v4/provider/DocumentsContractApi21.java b/core-utils/api21/android/support/v4/provider/DocumentsContractApi21.java
index 03667b3..cfaea83 100644
--- a/core-utils/api21/android/support/v4/provider/DocumentsContractApi21.java
+++ b/core-utils/api21/android/support/v4/provider/DocumentsContractApi21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.provider;
 
-import android.annotation.TargetApi;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.Cursor;
@@ -28,7 +27,6 @@
 import java.util.ArrayList;
 
 @RequiresApi(21)
-@TargetApi(21)
 class DocumentsContractApi21 {
     private static final String TAG = "DocumentFile";
 
diff --git a/core-utils/api23/android/support/v4/print/PrintHelperApi23.java b/core-utils/api23/android/support/v4/print/PrintHelperApi23.java
index e2f6d69..bd949b9 100644
--- a/core-utils/api23/android/support/v4/print/PrintHelperApi23.java
+++ b/core-utils/api23/android/support/v4/print/PrintHelperApi23.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.print;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.print.PrintAttributes;
 import android.support.annotation.RequiresApi;
@@ -25,7 +24,6 @@
  * Api23 specific PrintManager API implementation.
  */
 @RequiresApi(23)
-@TargetApi(23)
 class PrintHelperApi23 extends PrintHelperApi20 {
     @Override
     protected PrintAttributes.Builder copyAttributes(PrintAttributes other) {
diff --git a/core-utils/api24/android/support/v4/print/PrintHelperApi24.java b/core-utils/api24/android/support/v4/print/PrintHelperApi24.java
index 36edfbd..9ae32b4 100644
--- a/core-utils/api24/android/support/v4/print/PrintHelperApi24.java
+++ b/core-utils/api24/android/support/v4/print/PrintHelperApi24.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.print;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 
@@ -24,7 +23,6 @@
  * Api24 specific PrintManager API implementation.
  */
 @RequiresApi(24)
-@TargetApi(24)
 class PrintHelperApi24 extends PrintHelperApi23 {
     PrintHelperApi24(Context context) {
         super(context);
diff --git a/core-utils/build.gradle b/core-utils/build.gradle
index d40781d..a1ca98b 100644
--- a/core-utils/build.gradle
+++ b/core-utils/build.gradle
@@ -1,32 +1,27 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'support-core-utils'
 
 dependencies {
     compile project(':support-annotations')
     compile project(':support-compat')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile 'org.mockito:mockito-core:1.9.5'
-    androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
-    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
-    testCompile 'junit:junit:4.12'
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'gingerbread',
                 'honeycomb',
@@ -38,66 +33,11 @@
                 'api24',
                 'java'
         ]
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/java'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-        exclude('android/content/pm/**')
-        exclude('android/service/media/**')
-    }
-
-    artifacts.add('archives', sourcesJarTask);
+supportLibrary {
+    name 'Android Support Library v4'
+    inceptionYear '2011'
+    description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
 }
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Library v4'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/core-utils/gingerbread/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java b/core-utils/gingerbread/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java
index 72b6abb..a38afa4 100644
--- a/core-utils/gingerbread/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java
+++ b/core-utils/gingerbread/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java
@@ -15,7 +15,6 @@
  */
 package android.support.v4.graphics.drawable;
 
-import android.annotation.TargetApi;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
@@ -43,7 +42,6 @@
  * </p>
  */
 @RequiresApi(9)
-@TargetApi(9)
 public abstract class RoundedBitmapDrawable extends Drawable {
     private static final int DEFAULT_PAINT_FLAGS =
             Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG;
diff --git a/core-utils/honeycomb/android/support/v4/app/TaskStackBuilderHoneycomb.java b/core-utils/honeycomb/android/support/v4/app/TaskStackBuilderHoneycomb.java
index d970019..e41fdd8 100644
--- a/core-utils/honeycomb/android/support/v4/app/TaskStackBuilderHoneycomb.java
+++ b/core-utils/honeycomb/android/support/v4/app/TaskStackBuilderHoneycomb.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
@@ -26,7 +25,6 @@
  * Implementation of TaskStackBuilder that can call Honeycomb APIs.
  */
 @RequiresApi(11)
-@TargetApi(11)
 class TaskStackBuilderHoneycomb {
     public static PendingIntent getActivitiesPendingIntent(Context context, int requestCode,
             Intent[] intents, int flags) {
diff --git a/core-utils/java/android/support/v4/content/MimeTypeFilter.java b/core-utils/java/android/support/v4/content/MimeTypeFilter.java
new file mode 100644
index 0000000..6d26dcb
--- /dev/null
+++ b/core-utils/java/android/support/v4/content/MimeTypeFilter.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.content;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import java.util.ArrayList;
+
+/**
+ * Provides utility methods for matching MIME type filters used in ContentProvider.
+ *
+ * <p>Wildcards are allowed only instead of the entire type or subtype with a tree prefix.
+ * Eg. image\/*, *\/* is a valid filter and will match image/jpeg, but image/j* is invalid and
+ * it will not match image/jpeg. Suffixes and parameters are not supported, and they are treated
+ * as part of the subtype during matching.
+ *
+ * <p><em>Note: MIME type matching in the Android framework is case-sensitive, unlike the formal
+ * RFC definitions. As a result, you should always write these elements with lower case letters,
+ * or use {@link android.content.Intent#normalizeMimeType} to ensure that they are converted to
+ * lower case.</em>
+ *
+ * <p>Null MIME type doesn't match anything.
+ */
+public final class MimeTypeFilter {
+
+    private MimeTypeFilter() {
+    }
+
+    private static boolean mimeTypeAgainstFilter(
+            @NonNull String[] mimeTypeParts, @NonNull String[]filterParts) {
+        if (mimeTypeParts.length != 2 || filterParts.length != 2) {
+            return false;
+        }
+        if (!"*".equals(filterParts[0])
+                && !filterParts[0].equals(mimeTypeParts[0])) {
+            return false;
+        }
+        if (!"*".equals(filterParts[1])
+                && !filterParts[1].equals(mimeTypeParts[1])) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * See the class description for the matching behavior details.
+     * @return True if the {@code mimeType} matches the {@code filter}.
+     */
+    public static boolean matches(@Nullable String mimeType, @NonNull String filter) {
+        if (mimeType == null) {
+            return false;
+        }
+
+        final String[] mimeTypeParts = mimeType.split("/");
+        final String[] filterParts = filter.split("/");
+
+        return mimeTypeAgainstFilter(mimeTypeParts, filterParts);
+    }
+
+    /**
+     * See the class description for the matching behavior details.
+     * @return The first matching filter, or null if nothing matches.
+     */
+    public static String matches(
+            @Nullable String mimeType, @NonNull String[] filters) {
+        if (mimeType == null) {
+            return null;
+        }
+
+        final String[] mimeTypeParts = mimeType.split("/");
+        for (String filter : filters) {
+            final String[] filterParts = filter.split("/");
+            if (mimeTypeAgainstFilter(mimeTypeParts, filterParts)) {
+                return filter;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * See the class description for the matching behavior details.
+     * @return The first matching MIME type, or null if nothing matches.
+     */
+    public static String matches(
+            @Nullable String[] mimeTypes, @NonNull String filter) {
+        if (mimeTypes == null) {
+            return null;
+        }
+
+        final String[] filterParts = filter.split("/");
+        for (String mimeType : mimeTypes) {
+            final String[] mimeTypeParts = mimeType.split("/");
+            if (mimeTypeAgainstFilter(mimeTypeParts, filterParts)) {
+                return mimeType;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * See the class description for the matching behavior details.
+     * @return The list of matching MIME types, or empty list if nothing matches.
+     */
+    public static String[] matchesMany(
+            @Nullable String[] mimeTypes, @NonNull String filter) {
+        if (mimeTypes == null) {
+            return new String[] {};
+        }
+
+        final ArrayList<String> list = new ArrayList<>();
+        final String[] filterParts = filter.split("/");
+        for (String mimeType : mimeTypes) {
+            final String[] mimeTypeParts = mimeType.split("/");
+            if (mimeTypeAgainstFilter(mimeTypeParts, filterParts)) {
+                list.add(mimeType);
+            }
+        }
+
+        return list.toArray(new String[list.size()]);
+    }
+}
diff --git a/core-utils/java/android/support/v4/math/MathUtils.java b/core-utils/java/android/support/v4/math/MathUtils.java
new file mode 100644
index 0000000..e66b2c2
--- /dev/null
+++ b/core-utils/java/android/support/v4/math/MathUtils.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.math;
+
+/**
+ * A utility class providing functions useful for common mathematical operations.
+ */
+public class MathUtils {
+
+    /**
+     * This method takes a numerical value and ensures it fits in a given numerical range. If the
+     * number is smaller than the minimum required by the range, then the minimum of the range will
+     * be returned. If the number is higher than the maximum allowed by the range then the maximum
+     * of the range will be returned.
+     *
+     * @param value the value to be clamped.
+     * @param min minimum resulting value.
+     * @param max maximum resulting value.
+     *
+     * @return the clamped value.
+     */
+    public static float clamp(float value, int min, int max) {
+        if (value < min) {
+            return min;
+        } else if (value > max) {
+            return max;
+        }
+        return value;
+    }
+
+    /**
+     * This method takes a numerical value and ensures it fits in a given numerical range. If the
+     * number is smaller than the minimum required by the range, then the minimum of the range will
+     * be returned. If the number is higher than the maximum allowed by the range then the maximum
+     * of the range will be returned.
+     *
+     * @param value the value to be clamped.
+     * @param min minimum resulting value.
+     * @param max maximum resulting value.
+     *
+     * @return the clamped value.
+     */
+    public static double clamp(double value, double min, double max) {
+        if (value < min) {
+            return min;
+        } else if (value > max) {
+            return max;
+        }
+        return value;
+    }
+
+    /**
+     * This method takes a numerical value and ensures it fits in a given numerical range. If the
+     * number is smaller than the minimum required by the range, then the minimum of the range will
+     * be returned. If the number is higher than the maximum allowed by the range then the maximum
+     * of the range will be returned.
+     *
+     * @param value the value to be clamped.
+     * @param min minimum resulting value.
+     * @param max maximum resulting value.
+     *
+     * @return the clamped value.
+     */
+    public static int clamp(int value, int min, int max) {
+        if (value < min) {
+            return min;
+        } else if (value > max) {
+            return max;
+        }
+        return value;
+    }
+}
diff --git a/core-utils/jellybean/android/support/v4/app/NavUtilsJB.java b/core-utils/jellybean/android/support/v4/app/NavUtilsJB.java
index 86a28b3..64a6a81 100644
--- a/core-utils/jellybean/android/support/v4/app/NavUtilsJB.java
+++ b/core-utils/jellybean/android/support/v4/app/NavUtilsJB.java
@@ -16,14 +16,12 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(16)
-@TargetApi(16)
 class NavUtilsJB {
     public static Intent getParentActivityIntent(Activity activity) {
         return activity.getParentActivityIntent();
diff --git a/core-utils/jellybean/android/support/v4/app/TaskStackBuilderJellybean.java b/core-utils/jellybean/android/support/v4/app/TaskStackBuilderJellybean.java
index 96c3dda..2a18971 100644
--- a/core-utils/jellybean/android/support/v4/app/TaskStackBuilderJellybean.java
+++ b/core-utils/jellybean/android/support/v4/app/TaskStackBuilderJellybean.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
@@ -24,7 +23,6 @@
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(16)
-@TargetApi(16)
 class TaskStackBuilderJellybean {
 
     public static PendingIntent getActivitiesPendingIntent(Context context, int requestCode,
diff --git a/core-utils/kitkat/android/support/v4/print/PrintHelperKitkat.java b/core-utils/kitkat/android/support/v4/print/PrintHelperKitkat.java
index 08a41b2..355e878 100644
--- a/core-utils/kitkat/android/support/v4/print/PrintHelperKitkat.java
+++ b/core-utils/kitkat/android/support/v4/print/PrintHelperKitkat.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.print;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
@@ -52,7 +51,6 @@
  * Kitkat specific PrintManager API implementation.
  */
 @RequiresApi(19)
-@TargetApi(19)
 class PrintHelperKitkat {
     private static final String LOG_TAG = "PrintHelperKitkat";
     // will be <= 300 dpi on A4 (8.3×11.7) paper (worst case of 150 dpi)
diff --git a/core-utils/kitkat/android/support/v4/provider/DocumentsContractApi19.java b/core-utils/kitkat/android/support/v4/provider/DocumentsContractApi19.java
index f164f17..41ba0f0 100644
--- a/core-utils/kitkat/android/support/v4/provider/DocumentsContractApi19.java
+++ b/core-utils/kitkat/android/support/v4/provider/DocumentsContractApi19.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.provider;
 
-import android.annotation.TargetApi;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -29,7 +28,6 @@
 import android.util.Log;
 
 @RequiresApi(19)
-@TargetApi(19)
 class DocumentsContractApi19 {
     private static final String TAG = "DocumentFile";
 
diff --git a/core-utils/tests/AndroidManifest.xml b/core-utils/tests/AndroidManifest.xml
index 8a30a93..6af658b 100644
--- a/core-utils/tests/AndroidManifest.xml
+++ b/core-utils/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.coreutils.test">
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                       android.support.test.espresso, android.support.test.espresso.idling"/>
diff --git a/core-utils/tests/java/android/support/v4/content/MimeTypeFilterTest.java b/core-utils/tests/java/android/support/v4/content/MimeTypeFilterTest.java
new file mode 100644
index 0000000..4fec6dd
--- /dev/null
+++ b/core-utils/tests/java/android/support/v4/content/MimeTypeFilterTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.content;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.MoreAsserts;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link MimeTypeFilter}
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class MimeTypeFilterTest {
+    @Test
+    public void matchesBasic() throws Exception {
+        assertTrue(MimeTypeFilter.matches("image/jpeg", "*/*"));
+        assertTrue(MimeTypeFilter.matches("image/jpeg", "image/*"));
+        assertTrue(MimeTypeFilter.matches("image/jpeg", "image/jpeg"));
+        assertTrue(MimeTypeFilter.matches("image/jpeg", "*/jpeg"));
+
+        // These matchers are case *sensitive*.
+        assertFalse(MimeTypeFilter.matches("ImAgE/JpEg", "iMaGe/*"));
+        assertFalse(MimeTypeFilter.matches("IMAGE/JPEG", "image/jpeg"));
+        assertFalse(MimeTypeFilter.matches("image/jpeg", "IMAGE/JPEG"));
+
+        assertFalse(MimeTypeFilter.matches("image/jpeg", "image/png"));
+        assertFalse(MimeTypeFilter.matches("image/jpeg", "video/jpeg"));
+
+        assertFalse(MimeTypeFilter.matches((String) null, "*/*"));
+        assertFalse(MimeTypeFilter.matches((String) null, "image/"));
+        assertFalse(MimeTypeFilter.matches((String) null, "image/jpeg"));
+
+        // Invalid MIME types, filters or swapped arguments.
+        assertFalse(MimeTypeFilter.matches((String) null, ""));
+        assertFalse(MimeTypeFilter.matches("", ""));
+        assertFalse(MimeTypeFilter.matches("", "*/"));
+        assertFalse(MimeTypeFilter.matches("", "*/*"));
+        assertFalse(MimeTypeFilter.matches("image/", "*/*"));
+        assertFalse(MimeTypeFilter.matches("image/", "image/"));
+        assertFalse(MimeTypeFilter.matches("*/*", "image/jpeg"));
+    }
+
+    @Test
+    public void matchesManyFilters() throws Exception {
+        assertEquals("*/*", MimeTypeFilter.matches("image/jpeg", new String[] {"*/*"}));
+        assertEquals("image/*", MimeTypeFilter.matches("image/jpeg", new String[] {"image/*"}));
+        assertEquals("image/jpeg", MimeTypeFilter.matches(
+                "image/jpeg", new String[] {"image/jpeg"}));
+
+        assertEquals("*/*", MimeTypeFilter.matches(
+                "image/jpeg", new String[] {"not/matching", "*/*"}));
+        assertEquals("image/*", MimeTypeFilter.matches(
+                "image/jpeg", new String[] {"image/*", "image/jpeg"}));
+        assertEquals("image/jpeg", MimeTypeFilter.matches(
+                "image/jpeg", new String[] {"image/jpeg", "image/png"}));
+
+        assertNull(MimeTypeFilter.matches(
+                "ImAgE/JpEg", new String[] {"iMaGe/*", "image/*"}));
+        assertEquals("*/jpeg", MimeTypeFilter.matches(
+                "image/jpeg", new String[] {"*/png", "*/jpeg"}));
+
+        assertNull(MimeTypeFilter.matches("image/jpeg", new String[] {}));
+        assertNull(MimeTypeFilter.matches("image/jpeg", new String[] {}));
+
+        assertNull(MimeTypeFilter.matches("image/jpeg", new String[] {"image/png", "video/jpeg"}));
+        assertNull(MimeTypeFilter.matches("image/jpeg", new String[] {"video/jpeg", "image/png"}));
+
+        assertNull(MimeTypeFilter.matches(null, new String[] {"*/*"}));
+        assertNull(MimeTypeFilter.matches(null, new String[] {"image/"}));
+        assertNull(MimeTypeFilter.matches(null, new String[] {"image/jpeg"}));
+
+        // Invalid MIME types, filters or swapped arguments.
+        assertNull(MimeTypeFilter.matches(null, new String[] {""}));
+        assertNull(MimeTypeFilter.matches("", new String[] {""}));
+        assertNull(MimeTypeFilter.matches("", new String[] {"*/"}));
+        assertNull(MimeTypeFilter.matches("", new String[] {"*/*"}));
+        assertNull(MimeTypeFilter.matches("image/", new String[] {"*/*"}));
+        assertNull(MimeTypeFilter.matches("image/", new String[] {"image/"}));
+        assertNull(MimeTypeFilter.matches("*/*", new String[] {"image/jpeg"}));
+    }
+
+    @Test
+    public void matchesManyMimeTypes() throws Exception {
+        MoreAsserts.assertEquals(new String[] {"image/jpeg", "image/png"},
+                MimeTypeFilter.matchesMany(new String[] {"image/jpeg", "image/png"}, "image/*"));
+        MoreAsserts.assertEquals(new String[] {"image/png"},
+                MimeTypeFilter.matchesMany(new String[] {"image/jpeg", "image/png"}, "image/png"));
+        MoreAsserts.assertEquals(new String[] {},
+                MimeTypeFilter.matchesMany(new String[] {"image/jpeg", "image/png"}, "*/JpEg"));
+
+        MoreAsserts.assertEquals(new String[] {},
+                MimeTypeFilter.matchesMany(new String[] {"image/jpeg", "image/png"}, "video/ogv"));
+        MoreAsserts.assertEquals(new String[] {},
+                MimeTypeFilter.matchesMany(new String[] {"image/jpeg", "image/png"}, ""));
+        MoreAsserts.assertEquals(new String[] {},
+                MimeTypeFilter.matchesMany(new String[] {}, "*/*"));
+    }
+}
diff --git a/core-utils/tests/java/android/support/v4/math/MathUtilsTest.java b/core-utils/tests/java/android/support/v4/math/MathUtilsTest.java
new file mode 100644
index 0000000..526f3a6
--- /dev/null
+++ b/core-utils/tests/java/android/support/v4/math/MathUtilsTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.math;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MathUtilsTest {
+
+    @Test
+    public void testClamp() {
+        // Int
+        assertEquals(0, MathUtils.clamp(-4, 0, 7));
+        assertEquals(3, MathUtils.clamp(3, -2, 7));
+        assertEquals(0, MathUtils.clamp(0, 0, 7));
+        assertEquals(7, MathUtils.clamp(7, 0, 7));
+        assertEquals(7, MathUtils.clamp(8, -2, 7));
+
+        // Double
+        assertEquals(0.0, MathUtils.clamp(-0.4, 0.0, 7.0), 0.0);
+        assertEquals(3.0, MathUtils.clamp(3.0, 0.0, 7.0), 0.0);
+        assertEquals(0.1, MathUtils.clamp(0.1, 0.0, 7.0), 0.0);
+        assertEquals(7.0, MathUtils.clamp(7.0, 0.0, 7.0), 0.0);
+        assertEquals(-0.6, MathUtils.clamp(-0.7, -0.6, 7.0), 0.0);
+
+        // Float
+        assertEquals(0.0f, MathUtils.clamp(-0.4f, 0.0f, 7.0f), 0.0f);
+        assertEquals(3.0f, MathUtils.clamp(3.0f, 0.0f, 7.0f), 0.0f);
+        assertEquals(0.1f, MathUtils.clamp(0.1f, 0.0f, 7.0f), 0.0f);
+        assertEquals(7.0f, MathUtils.clamp(7.0f, 0.0f, 7.0f), 0.0f);
+        assertEquals(-0.6f, MathUtils.clamp(-0.7f, -0.6f, 7.0f), 0.0f);
+    }
+}
diff --git a/customtabs/Android.mk b/customtabs/Android.mk
index e6f6ead..cfd9971 100644
--- a/customtabs/Android.mk
+++ b/customtabs/Android.mk
@@ -31,7 +31,6 @@
     $(call all-java-files-under,src) \
     $(call all-Iaidl-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-annotations \
     android-support-compat
diff --git a/customtabs/AndroidManifest-make.xml b/customtabs/AndroidManifest-make.xml
deleted file mode 100644
index 212fab9..0000000
--- a/customtabs/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.customtabs">
-    <uses-sdk android:minSdkVersion="15"/>
-    <application />
-</manifest>
diff --git a/customtabs/build.gradle b/customtabs/build.gradle
index e427d1e..b35a7c3 100644
--- a/customtabs/build.gradle
+++ b/customtabs/build.gradle
@@ -1,56 +1,31 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'customtabs'
 
 dependencies {
     compile project(':support-compat')
     compile project(':support-annotations')
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
-        exclude module: 'support-annotations'
-    }
-    testCompile 'junit:junit:4.12'
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 15
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = ['src']
         main.aidl.srcDirs = ['src']
         main.res.srcDir 'res'
         main.assets.srcDir 'assets'
         main.resources.srcDir 'java'
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir('tests/src/')
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
+supportLibrary {
+    name 'Android Support Custom Tabs'
+    inceptionYear '2015'
+    description 'Android Support Custom Tabs'
 }
diff --git a/design/Android.mk b/design/Android.mk
index 2e634eb..08f8815 100644
--- a/design/Android.mk
+++ b/design/Android.mk
@@ -31,14 +31,9 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := \
     $(call all-java-files-under,base) \
-    $(call all-java-files-under,gingerbread) \
-    $(call all-java-files-under,honeycomb) \
-    $(call all-java-files-under,honeycomb-mr1) \
-    $(call all-java-files-under,ics) \
     $(call all-java-files-under,lollipop) \
     $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-transition \
     android-support-v7-appcompat \
diff --git a/design/AndroidManifest-make.xml b/design/AndroidManifest-make.xml
deleted file mode 100644
index d51186d..0000000
--- a/design/AndroidManifest-make.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.support.design">
-    <uses-sdk android:minSdkVersion="9"
-              tools:overrideLibrary="android.support.transition"/>
-    <application />
-</manifest>
diff --git a/design/AndroidManifest.xml b/design/AndroidManifest.xml
index 2d5fe0b..e4449de 100644
--- a/design/AndroidManifest.xml
+++ b/design/AndroidManifest.xml
@@ -16,7 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.design">
-    <uses-sdk android:minSdkVersion="9"
+    <uses-sdk android:minSdkVersion="14"
               tools:overrideLibrary="android.support.transition"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
diff --git a/design/base/android/support/design/widget/FloatingActionButtonImpl.java b/design/base/android/support/design/widget/FloatingActionButtonImpl.java
index 36ccbf2..132cd81 100644
--- a/design/base/android/support/design/widget/FloatingActionButtonImpl.java
+++ b/design/base/android/support/design/widget/FloatingActionButtonImpl.java
@@ -16,6 +16,9 @@
 
 package android.support.design.widget;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.Color;
@@ -23,15 +26,21 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.os.Build;
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
 import android.support.design.R;
 import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v4.view.ViewCompat;
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.view.animation.Interpolator;
 
-abstract class FloatingActionButtonImpl {
-
+@RequiresApi(14)
+class FloatingActionButtonImpl {
     static final Interpolator ANIM_INTERPOLATOR = AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR;
     static final long PRESSED_ANIM_DURATION = 100;
     static final long PRESSED_ANIM_DELAY = 100;
@@ -42,6 +51,12 @@
 
     int mAnimState = ANIM_STATE_NONE;
 
+    private final StateListAnimator mStateListAnimator;
+
+    ShadowDrawableWrapper mShadowDrawable;
+
+    private float mRotation;
+
     Drawable mShapeDrawable;
     Drawable mRippleDrawable;
     CircularBorderDrawable mBorderDrawable;
@@ -51,8 +66,8 @@
     float mPressedTranslationZ;
 
     interface InternalVisibilityChangedListener {
-        public void onShown();
-        public void onHidden();
+        void onShown();
+        void onHidden();
     }
 
     static final int SHOW_HIDE_ANIM_DURATION = 200;
@@ -66,26 +81,92 @@
 
     final VisibilityAwareImageButton mView;
     final ShadowViewDelegate mShadowViewDelegate;
-    final ValueAnimatorCompat.Creator mAnimatorCreator;
 
     private final Rect mTmpRect = new Rect();
     private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
 
     FloatingActionButtonImpl(VisibilityAwareImageButton view,
-            ShadowViewDelegate shadowViewDelegate, ValueAnimatorCompat.Creator animatorCreator) {
+            ShadowViewDelegate shadowViewDelegate) {
         mView = view;
         mShadowViewDelegate = shadowViewDelegate;
-        mAnimatorCreator = animatorCreator;
+
+        mStateListAnimator = new StateListAnimator();
+
+        // Elevate with translationZ when pressed or focused
+        mStateListAnimator.addState(PRESSED_ENABLED_STATE_SET,
+                createAnimator(new ElevateToTranslationZAnimation()));
+        mStateListAnimator.addState(FOCUSED_ENABLED_STATE_SET,
+                createAnimator(new ElevateToTranslationZAnimation()));
+        // Reset back to elevation by default
+        mStateListAnimator.addState(ENABLED_STATE_SET,
+                createAnimator(new ResetElevationAnimation()));
+        // Set to 0 when disabled
+        mStateListAnimator.addState(EMPTY_STATE_SET,
+                createAnimator(new DisabledElevationAnimation()));
+
+        mRotation = mView.getRotation();
     }
 
-    abstract void setBackgroundDrawable(ColorStateList backgroundTint,
-            PorterDuff.Mode backgroundTintMode, int rippleColor, int borderWidth);
+    void setBackgroundDrawable(ColorStateList backgroundTint,
+            PorterDuff.Mode backgroundTintMode, int rippleColor, int borderWidth) {
+        // Now we need to tint the original background with the tint, using
+        // an InsetDrawable if we have a border width
+        mShapeDrawable = DrawableCompat.wrap(createShapeDrawable());
+        DrawableCompat.setTintList(mShapeDrawable, backgroundTint);
+        if (backgroundTintMode != null) {
+            DrawableCompat.setTintMode(mShapeDrawable, backgroundTintMode);
+        }
 
-    abstract void setBackgroundTintList(ColorStateList tint);
+        // Now we created a mask Drawable which will be used for touch feedback.
+        GradientDrawable touchFeedbackShape = createShapeDrawable();
 
-    abstract void setBackgroundTintMode(PorterDuff.Mode tintMode);
+        // We'll now wrap that touch feedback mask drawable with a ColorStateList. We do not need
+        // to inset for any border here as LayerDrawable will nest the padding for us
+        mRippleDrawable = DrawableCompat.wrap(touchFeedbackShape);
+        DrawableCompat.setTintList(mRippleDrawable, createColorStateList(rippleColor));
 
-    abstract void setRippleColor(int rippleColor);
+        final Drawable[] layers;
+        if (borderWidth > 0) {
+            mBorderDrawable = createBorderDrawable(borderWidth, backgroundTint);
+            layers = new Drawable[] {mBorderDrawable, mShapeDrawable, mRippleDrawable};
+        } else {
+            mBorderDrawable = null;
+            layers = new Drawable[] {mShapeDrawable, mRippleDrawable};
+        }
+
+        mContentBackground = new LayerDrawable(layers);
+
+        mShadowDrawable = new ShadowDrawableWrapper(
+                mView.getContext(),
+                mContentBackground,
+                mShadowViewDelegate.getRadius(),
+                mElevation,
+                mElevation + mPressedTranslationZ);
+        mShadowDrawable.setAddPaddingForCorners(false);
+        mShadowViewDelegate.setBackgroundDrawable(mShadowDrawable);
+    }
+
+    void setBackgroundTintList(ColorStateList tint) {
+        if (mShapeDrawable != null) {
+            DrawableCompat.setTintList(mShapeDrawable, tint);
+        }
+        if (mBorderDrawable != null) {
+            mBorderDrawable.setBorderTint(tint);
+        }
+    }
+
+    void setBackgroundTintMode(PorterDuff.Mode tintMode) {
+        if (mShapeDrawable != null) {
+            DrawableCompat.setTintMode(mShapeDrawable, tintMode);
+        }
+    }
+
+
+    void setRippleColor(int rippleColor) {
+        if (mRippleDrawable != null) {
+            DrawableCompat.setTintList(mRippleDrawable, createColorStateList(rippleColor));
+        }
+    }
 
     final void setElevation(float elevation) {
         if (mElevation != elevation) {
@@ -94,7 +175,9 @@
         }
     }
 
-    abstract float getElevation();
+    float getElevation() {
+        return mElevation;
+    }
 
     final void setPressedTranslationZ(float translationZ) {
         if (mPressedTranslationZ != translationZ) {
@@ -103,21 +186,130 @@
         }
     }
 
-    abstract void onElevationsChanged(float elevation, float pressedTranslationZ);
+    void onElevationsChanged(float elevation, float pressedTranslationZ) {
+        if (mShadowDrawable != null) {
+            mShadowDrawable.setShadowSize(elevation, elevation + mPressedTranslationZ);
+            updatePadding();
+        }
+    }
 
-    abstract void onDrawableStateChanged(int[] state);
+    void onDrawableStateChanged(int[] state) {
+        mStateListAnimator.setState(state);
+    }
 
-    abstract void jumpDrawableToCurrentState();
+    void jumpDrawableToCurrentState() {
+        mStateListAnimator.jumpToCurrentState();
+    }
 
-    abstract void hide(@Nullable InternalVisibilityChangedListener listener, boolean fromUser);
+    void hide(@Nullable final InternalVisibilityChangedListener listener, final boolean fromUser) {
+        if (isOrWillBeHidden()) {
+            // We either are or will soon be hidden, skip the call
+            return;
+        }
 
-    abstract void show(@Nullable InternalVisibilityChangedListener listener, boolean fromUser);
+        mView.animate().cancel();
+
+        if (shouldAnimateVisibilityChange()) {
+            mAnimState = ANIM_STATE_HIDING;
+
+            mView.animate()
+                    .scaleX(0f)
+                    .scaleY(0f)
+                    .alpha(0f)
+                    .setDuration(SHOW_HIDE_ANIM_DURATION)
+                    .setInterpolator(AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR)
+                    .setListener(new AnimatorListenerAdapter() {
+                        private boolean mCancelled;
+
+                        @Override
+                        public void onAnimationStart(Animator animation) {
+                            mView.internalSetVisibility(View.VISIBLE, fromUser);
+                            mCancelled = false;
+                        }
+
+                        @Override
+                        public void onAnimationCancel(Animator animation) {
+                            mCancelled = true;
+                        }
+
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            mAnimState = ANIM_STATE_NONE;
+
+                            if (!mCancelled) {
+                                mView.internalSetVisibility(fromUser ? View.GONE : View.INVISIBLE,
+                                        fromUser);
+                                if (listener != null) {
+                                    listener.onHidden();
+                                }
+                            }
+                        }
+                    });
+        } else {
+            // If the view isn't laid out, or we're in the editor, don't run the animation
+            mView.internalSetVisibility(fromUser ? View.GONE : View.INVISIBLE, fromUser);
+            if (listener != null) {
+                listener.onHidden();
+            }
+        }
+    }
+
+    void show(@Nullable final InternalVisibilityChangedListener listener, final boolean fromUser) {
+        if (isOrWillBeShown()) {
+            // We either are or will soon be visible, skip the call
+            return;
+        }
+
+        mView.animate().cancel();
+
+        if (shouldAnimateVisibilityChange()) {
+            mAnimState = ANIM_STATE_SHOWING;
+
+            if (mView.getVisibility() != View.VISIBLE) {
+                // If the view isn't visible currently, we'll animate it from a single pixel
+                mView.setAlpha(0f);
+                mView.setScaleY(0f);
+                mView.setScaleX(0f);
+            }
+
+            mView.animate()
+                    .scaleX(1f)
+                    .scaleY(1f)
+                    .alpha(1f)
+                    .setDuration(SHOW_HIDE_ANIM_DURATION)
+                    .setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR)
+                    .setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationStart(Animator animation) {
+                            mView.internalSetVisibility(View.VISIBLE, fromUser);
+                        }
+
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            mAnimState = ANIM_STATE_NONE;
+                            if (listener != null) {
+                                listener.onShown();
+                            }
+                        }
+                    });
+        } else {
+            mView.internalSetVisibility(View.VISIBLE, fromUser);
+            mView.setAlpha(1f);
+            mView.setScaleY(1f);
+            mView.setScaleX(1f);
+            if (listener != null) {
+                listener.onShown();
+            }
+        }
+    }
 
     final Drawable getContentBackground() {
         return mContentBackground;
     }
 
-    abstract void onCompatShadowChanged();
+    void onCompatShadowChanged() {
+        // Ignore pre-v21
+    }
 
     final void updatePadding() {
         Rect rect = mTmpRect;
@@ -126,7 +318,9 @@
         mShadowViewDelegate.setShadowPadding(rect.left, rect.top, rect.right, rect.bottom);
     }
 
-    abstract void getPadding(Rect rect);
+    void getPadding(Rect rect) {
+        mShadowDrawable.getPadding(rect);
+    }
 
     void onPaddingUpdated(Rect padding) {}
 
@@ -145,7 +339,7 @@
     }
 
     boolean requirePreDrawListener() {
-        return false;
+        return true;
     }
 
     CircularBorderDrawable createBorderDrawable(int borderWidth, ColorStateList backgroundTint) {
@@ -166,6 +360,11 @@
     }
 
     void onPreDraw() {
+        final float rotation = mView.getRotation();
+        if (mRotation != rotation) {
+            mRotation = rotation;
+            updateFromViewRotation();
+        }
     }
 
     private void ensurePreDrawListener() {
@@ -210,4 +409,123 @@
             return mAnimState != ANIM_STATE_SHOWING;
         }
     }
+
+    private ValueAnimator createAnimator(@NonNull ShadowAnimatorImpl impl) {
+        final ValueAnimator animator = new ValueAnimator();
+        animator.setInterpolator(ANIM_INTERPOLATOR);
+        animator.setDuration(PRESSED_ANIM_DURATION);
+        animator.addListener(impl);
+        animator.addUpdateListener(impl);
+        animator.setFloatValues(0, 1);
+        return animator;
+    }
+
+    private abstract class ShadowAnimatorImpl extends AnimatorListenerAdapter
+            implements ValueAnimator.AnimatorUpdateListener {
+        private boolean mValidValues;
+        private float mShadowSizeStart;
+        private float mShadowSizeEnd;
+
+        @Override
+        public void onAnimationUpdate(ValueAnimator animator) {
+            if (!mValidValues) {
+                mShadowSizeStart = mShadowDrawable.getShadowSize();
+                mShadowSizeEnd = getTargetShadowSize();
+                mValidValues = true;
+            }
+
+            mShadowDrawable.setShadowSize(mShadowSizeStart
+                    + ((mShadowSizeEnd - mShadowSizeStart) * animator.getAnimatedFraction()));
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animator) {
+            mShadowDrawable.setShadowSize(mShadowSizeEnd);
+            mValidValues = false;
+        }
+
+        /**
+         * @return the shadow size we want to animate to.
+         */
+        protected abstract float getTargetShadowSize();
+    }
+
+    private class ResetElevationAnimation extends ShadowAnimatorImpl {
+        ResetElevationAnimation() {
+        }
+
+        @Override
+        protected float getTargetShadowSize() {
+            return mElevation;
+        }
+    }
+
+    private class ElevateToTranslationZAnimation extends ShadowAnimatorImpl {
+        ElevateToTranslationZAnimation() {
+        }
+
+        @Override
+        protected float getTargetShadowSize() {
+            return mElevation + mPressedTranslationZ;
+        }
+    }
+
+    private class DisabledElevationAnimation extends ShadowAnimatorImpl {
+        DisabledElevationAnimation() {
+        }
+
+        @Override
+        protected float getTargetShadowSize() {
+            return 0f;
+        }
+    }
+
+    private static ColorStateList createColorStateList(int selectedColor) {
+        final int[][] states = new int[3][];
+        final int[] colors = new int[3];
+        int i = 0;
+
+        states[i] = FOCUSED_ENABLED_STATE_SET;
+        colors[i] = selectedColor;
+        i++;
+
+        states[i] = PRESSED_ENABLED_STATE_SET;
+        colors[i] = selectedColor;
+        i++;
+
+        // Default enabled state
+        states[i] = new int[0];
+        colors[i] = Color.TRANSPARENT;
+        i++;
+
+        return new ColorStateList(states, colors);
+    }
+
+    private boolean shouldAnimateVisibilityChange() {
+        return ViewCompat.isLaidOut(mView) && !mView.isInEditMode();
+    }
+
+    private void updateFromViewRotation() {
+        if (Build.VERSION.SDK_INT == 19) {
+            // KitKat seems to have an issue with views which are rotated with angles which are
+            // not divisible by 90. Worked around by moving to software rendering in these cases.
+            if ((mRotation % 90) != 0) {
+                if (mView.getLayerType() != View.LAYER_TYPE_SOFTWARE) {
+                    mView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+                }
+            } else {
+                if (mView.getLayerType() != View.LAYER_TYPE_NONE) {
+                    mView.setLayerType(View.LAYER_TYPE_NONE, null);
+                }
+            }
+        }
+
+        // Offset any View rotation
+        if (mShadowDrawable != null) {
+            mShadowDrawable.setRotation(-mRotation);
+        }
+        if (mBorderDrawable != null) {
+            mBorderDrawable.setRotation(-mRotation);
+        }
+    }
 }
diff --git a/design/base/android/support/design/widget/StateListAnimator.java b/design/base/android/support/design/widget/StateListAnimator.java
index 4378ef9..aef24be 100644
--- a/design/base/android/support/design/widget/StateListAnimator.java
+++ b/design/base/android/support/design/widget/StateListAnimator.java
@@ -16,6 +16,9 @@
 
 package android.support.design.widget;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.util.StateSet;
 
 import java.util.ArrayList;
@@ -25,17 +28,17 @@
     private final ArrayList<Tuple> mTuples = new ArrayList<>();
 
     private Tuple mLastMatch = null;
-    ValueAnimatorCompat mRunningAnimator = null;
+    ValueAnimator mRunningAnimator = null;
 
-    private final ValueAnimatorCompat.AnimatorListener mAnimationListener
-            = new ValueAnimatorCompat.AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(ValueAnimatorCompat animator) {
-            if (mRunningAnimator == animator) {
-                mRunningAnimator = null;
-            }
-        }
-    };
+    private final ValueAnimator.AnimatorListener mAnimationListener =
+            new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animator) {
+                    if (mRunningAnimator == animator) {
+                        mRunningAnimator = null;
+                    }
+                }
+            };
 
     /**
      * Associates the given Animation with the provided drawable state specs so that it will be run
@@ -44,7 +47,7 @@
      * @param specs    The drawable state specs to match against
      * @param animator The animator to run when the specs match
      */
-    public void addState(int[] specs, ValueAnimatorCompat animator) {
+    public void addState(int[] specs, ValueAnimator animator) {
         Tuple tuple = new Tuple(specs, animator);
         animator.addListener(mAnimationListener);
         mTuples.add(tuple);
@@ -103,9 +106,9 @@
 
     static class Tuple {
         final int[] mSpecs;
-        final ValueAnimatorCompat mAnimator;
+        final ValueAnimator mAnimator;
 
-        Tuple(int[] specs, ValueAnimatorCompat animator) {
+        Tuple(int[] specs, ValueAnimator animator) {
             mSpecs = specs;
             mAnimator = animator;
         }
diff --git a/design/base/android/support/design/widget/ValueAnimatorCompat.java b/design/base/android/support/design/widget/ValueAnimatorCompat.java
deleted file mode 100644
index 6c52db3..0000000
--- a/design/base/android/support/design/widget/ValueAnimatorCompat.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.design.widget;
-
-import android.support.annotation.NonNull;
-import android.view.animation.Interpolator;
-
-/**
- * This class offers a very small subset of {@code ValueAnimator}'s API, but works pre-v11 too.
- * <p>
- * You shouldn't not instantiate this directly. Instead use {@code ViewUtils.createAnimator()}.
- */
-class ValueAnimatorCompat {
-
-    interface AnimatorUpdateListener {
-        /**
-         * <p>Notifies the occurrence of another frame of the animation.</p>
-         *
-         * @param animator The animation which was repeated.
-         */
-        void onAnimationUpdate(ValueAnimatorCompat animator);
-    }
-
-    /**
-     * An animation listener receives notifications from an animation.
-     * Notifications indicate animation related events, such as the end or the
-     * repetition of the animation.
-     */
-    interface AnimatorListener {
-        /**
-         * <p>Notifies the start of the animation.</p>
-         *
-         * @param animator The started animation.
-         */
-        void onAnimationStart(ValueAnimatorCompat animator);
-        /**
-         * <p>Notifies the end of the animation. This callback is not invoked
-         * for animations with repeat count set to INFINITE.</p>
-         *
-         * @param animator The animation which reached its end.
-         */
-        void onAnimationEnd(ValueAnimatorCompat animator);
-        /**
-         * <p>Notifies the cancellation of the animation. This callback is not invoked
-         * for animations with repeat count set to INFINITE.</p>
-         *
-         * @param animator The animation which was canceled.
-         */
-        void onAnimationCancel(ValueAnimatorCompat animator);
-    }
-
-    static class AnimatorListenerAdapter implements AnimatorListener {
-        @Override
-        public void onAnimationStart(ValueAnimatorCompat animator) {
-        }
-
-        @Override
-        public void onAnimationEnd(ValueAnimatorCompat animator) {
-        }
-
-        @Override
-        public void onAnimationCancel(ValueAnimatorCompat animator) {
-        }
-    }
-
-    interface Creator {
-        @NonNull
-        ValueAnimatorCompat createAnimator();
-    }
-
-    static abstract class Impl {
-        interface AnimatorUpdateListenerProxy {
-            void onAnimationUpdate();
-        }
-
-        interface AnimatorListenerProxy {
-            void onAnimationStart();
-            void onAnimationEnd();
-            void onAnimationCancel();
-        }
-
-        abstract void start();
-        abstract boolean isRunning();
-        abstract void setInterpolator(Interpolator interpolator);
-        abstract void addListener(AnimatorListenerProxy listener);
-        abstract void addUpdateListener(AnimatorUpdateListenerProxy updateListener);
-        abstract void setIntValues(int from, int to);
-        abstract int getAnimatedIntValue();
-        abstract void setFloatValues(float from, float to);
-        abstract float getAnimatedFloatValue();
-        abstract void setDuration(long duration);
-        abstract void cancel();
-        abstract float getAnimatedFraction();
-        abstract void end();
-        abstract long getDuration();
-    }
-
-    private final Impl mImpl;
-
-    ValueAnimatorCompat(Impl impl) {
-        mImpl = impl;
-    }
-
-    public void start() {
-        mImpl.start();
-    }
-
-    public boolean isRunning() {
-        return mImpl.isRunning();
-    }
-
-    public void setInterpolator(Interpolator interpolator) {
-        mImpl.setInterpolator(interpolator);
-    }
-
-    public void addUpdateListener(final AnimatorUpdateListener updateListener) {
-        if (updateListener != null) {
-            mImpl.addUpdateListener(new Impl.AnimatorUpdateListenerProxy() {
-                @Override
-                public void onAnimationUpdate() {
-                    updateListener.onAnimationUpdate(ValueAnimatorCompat.this);
-                }
-            });
-        } else {
-            mImpl.addUpdateListener(null);
-        }
-    }
-
-    public void addListener(final AnimatorListener listener) {
-        if (listener != null) {
-            mImpl.addListener(new Impl.AnimatorListenerProxy() {
-                @Override
-                public void onAnimationStart() {
-                    listener.onAnimationStart(ValueAnimatorCompat.this);
-                }
-
-                @Override
-                public void onAnimationEnd() {
-                    listener.onAnimationEnd(ValueAnimatorCompat.this);
-                }
-
-                @Override
-                public void onAnimationCancel() {
-                    listener.onAnimationCancel(ValueAnimatorCompat.this);
-                }
-            });
-        } else {
-            mImpl.addListener(null);
-        }
-    }
-
-    public void setIntValues(int from, int to) {
-        mImpl.setIntValues(from, to);
-    }
-
-    public int getAnimatedIntValue() {
-        return mImpl.getAnimatedIntValue();
-    }
-
-    public void setFloatValues(float from, float to) {
-        mImpl.setFloatValues(from, to);
-    }
-
-    public float getAnimatedFloatValue() {
-        return mImpl.getAnimatedFloatValue();
-    }
-
-    public void setDuration(long duration) {
-        mImpl.setDuration(duration);
-    }
-
-    public void cancel() {
-        mImpl.cancel();
-    }
-
-    public float getAnimatedFraction() {
-        return mImpl.getAnimatedFraction();
-    }
-
-    public void end() {
-        mImpl.end();
-    }
-
-    public long getDuration() {
-        return mImpl.getDuration();
-    }
-}
diff --git a/design/build.gradle b/design/build.gradle
index d5f83b8..2a7d65d 100644
--- a/design/build.gradle
+++ b/design/build.gradle
@@ -1,5 +1,4 @@
-apply plugin: 'com.android.library'
-
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'design'
 
 dependencies {
@@ -8,41 +7,36 @@
     compile project(':support-recyclerview-v7')
     compile project(':support-transition')
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-contrib:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_contrib) {
         exclude group: 'com.android.support'
     }
-    androidTestCompile 'org.mockito:mockito-core:1.9.5'
-    androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
-    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
-    testCompile 'junit:junit:4.12'
-    testCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
+
+    testCompile libs.junit
+    testCompile ("$libs.test_runner") {
         exclude module: 'support-annotations'
     }
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'base',
                 'gingerbread',
-                'honeycomb',
-                'honeycomb-mr1',
                 'ics',
                 'lollipop',
                 'src'
@@ -53,19 +47,9 @@
         ]
         main.resources.srcDir 'src'
 
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-
         test.java.srcDir 'jvm-tests/src'
     }
 
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
-
     buildTypes.all {
         consumerProguardFiles 'proguard-rules.pro'
     }
@@ -81,52 +65,8 @@
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Design Support Library'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Design Support Library'
+    inceptionYear '2015'
+    description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 4 or later."
 }
diff --git a/design/gingerbread/android/support/design/widget/FloatingActionButtonGingerbread.java b/design/gingerbread/android/support/design/widget/FloatingActionButtonGingerbread.java
deleted file mode 100644
index 6edc9e4..0000000
--- a/design/gingerbread/android/support/design/widget/FloatingActionButtonGingerbread.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.design.widget;
-
-import android.content.res.ColorStateList;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.LayerDrawable;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.design.R;
-import android.support.design.widget.AnimationUtils.AnimationListenerAdapter;
-import android.support.v4.graphics.drawable.DrawableCompat;
-import android.view.View;
-import android.view.animation.Animation;
-
-class FloatingActionButtonGingerbread extends FloatingActionButtonImpl {
-
-    private final StateListAnimator mStateListAnimator;
-
-    ShadowDrawableWrapper mShadowDrawable;
-
-    FloatingActionButtonGingerbread(VisibilityAwareImageButton view,
-            ShadowViewDelegate shadowViewDelegate, ValueAnimatorCompat.Creator animatorCreator) {
-        super(view, shadowViewDelegate, animatorCreator);
-
-        mStateListAnimator = new StateListAnimator();
-
-        // Elevate with translationZ when pressed or focused
-        mStateListAnimator.addState(PRESSED_ENABLED_STATE_SET,
-                createAnimator(new ElevateToTranslationZAnimation()));
-        mStateListAnimator.addState(FOCUSED_ENABLED_STATE_SET,
-                createAnimator(new ElevateToTranslationZAnimation()));
-        // Reset back to elevation by default
-        mStateListAnimator.addState(ENABLED_STATE_SET,
-                createAnimator(new ResetElevationAnimation()));
-        // Set to 0 when disabled
-        mStateListAnimator.addState(EMPTY_STATE_SET,
-                createAnimator(new DisabledElevationAnimation()));
-    }
-
-    @Override
-    void setBackgroundDrawable(ColorStateList backgroundTint,
-            PorterDuff.Mode backgroundTintMode, int rippleColor, int borderWidth) {
-        // Now we need to tint the original background with the tint, using
-        // an InsetDrawable if we have a border width
-        mShapeDrawable = DrawableCompat.wrap(createShapeDrawable());
-        DrawableCompat.setTintList(mShapeDrawable, backgroundTint);
-        if (backgroundTintMode != null) {
-            DrawableCompat.setTintMode(mShapeDrawable, backgroundTintMode);
-        }
-
-        // Now we created a mask Drawable which will be used for touch feedback.
-        GradientDrawable touchFeedbackShape = createShapeDrawable();
-
-        // We'll now wrap that touch feedback mask drawable with a ColorStateList. We do not need
-        // to inset for any border here as LayerDrawable will nest the padding for us
-        mRippleDrawable = DrawableCompat.wrap(touchFeedbackShape);
-        DrawableCompat.setTintList(mRippleDrawable, createColorStateList(rippleColor));
-
-        final Drawable[] layers;
-        if (borderWidth > 0) {
-            mBorderDrawable = createBorderDrawable(borderWidth, backgroundTint);
-            layers = new Drawable[] {mBorderDrawable, mShapeDrawable, mRippleDrawable};
-        } else {
-            mBorderDrawable = null;
-            layers = new Drawable[] {mShapeDrawable, mRippleDrawable};
-        }
-
-        mContentBackground = new LayerDrawable(layers);
-
-        mShadowDrawable = new ShadowDrawableWrapper(
-                mView.getContext(),
-                mContentBackground,
-                mShadowViewDelegate.getRadius(),
-                mElevation,
-                mElevation + mPressedTranslationZ);
-        mShadowDrawable.setAddPaddingForCorners(false);
-        mShadowViewDelegate.setBackgroundDrawable(mShadowDrawable);
-    }
-
-    @Override
-    void setBackgroundTintList(ColorStateList tint) {
-        if (mShapeDrawable != null) {
-            DrawableCompat.setTintList(mShapeDrawable, tint);
-        }
-        if (mBorderDrawable != null) {
-            mBorderDrawable.setBorderTint(tint);
-        }
-    }
-
-    @Override
-    void setBackgroundTintMode(PorterDuff.Mode tintMode) {
-        if (mShapeDrawable != null) {
-            DrawableCompat.setTintMode(mShapeDrawable, tintMode);
-        }
-    }
-
-    @Override
-    void setRippleColor(int rippleColor) {
-        if (mRippleDrawable != null) {
-            DrawableCompat.setTintList(mRippleDrawable, createColorStateList(rippleColor));
-        }
-    }
-
-    @Override
-    float getElevation() {
-        return mElevation;
-    }
-
-    @Override
-    void onElevationsChanged(float elevation, float pressedTranslationZ) {
-        if (mShadowDrawable != null) {
-            mShadowDrawable.setShadowSize(elevation, elevation + mPressedTranslationZ);
-            updatePadding();
-        }
-    }
-
-    @Override
-    void onDrawableStateChanged(int[] state) {
-        mStateListAnimator.setState(state);
-    }
-
-    @Override
-    void jumpDrawableToCurrentState() {
-        mStateListAnimator.jumpToCurrentState();
-    }
-
-    @Override
-    void hide(@Nullable final InternalVisibilityChangedListener listener, final boolean fromUser) {
-        if (isOrWillBeHidden()) {
-            // We either are or will soon be hidden, skip the call
-            return;
-        }
-
-        mAnimState = ANIM_STATE_HIDING;
-
-        Animation anim = android.view.animation.AnimationUtils.loadAnimation(
-                mView.getContext(), R.anim.design_fab_out);
-        anim.setInterpolator(AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR);
-        anim.setDuration(SHOW_HIDE_ANIM_DURATION);
-        anim.setAnimationListener(new AnimationUtils.AnimationListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animation animation) {
-                mAnimState = ANIM_STATE_NONE;
-                mView.internalSetVisibility(fromUser ? View.GONE : View.INVISIBLE, fromUser);
-                if (listener != null) {
-                    listener.onHidden();
-                }
-            }
-        });
-        mView.startAnimation(anim);
-    }
-
-    @Override
-    void show(@Nullable final InternalVisibilityChangedListener listener, final boolean fromUser) {
-        if (isOrWillBeShown()) {
-            // We either are or will soon be visible, skip the call
-            return;
-        }
-
-        mAnimState = ANIM_STATE_SHOWING;
-
-        mView.internalSetVisibility(View.VISIBLE, fromUser);
-        Animation anim = android.view.animation.AnimationUtils.loadAnimation(
-                mView.getContext(), R.anim.design_fab_in);
-        anim.setDuration(SHOW_HIDE_ANIM_DURATION);
-        anim.setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR);
-        anim.setAnimationListener(new AnimationListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animation animation) {
-                mAnimState = ANIM_STATE_NONE;
-                if (listener != null) {
-                    listener.onShown();
-                }
-            }
-        });
-        mView.startAnimation(anim);
-    }
-
-    @Override
-    void onCompatShadowChanged() {
-        // Ignore pre-v21
-    }
-
-    @Override
-    void getPadding(Rect rect) {
-        mShadowDrawable.getPadding(rect);
-    }
-
-    private ValueAnimatorCompat createAnimator(@NonNull ShadowAnimatorImpl impl) {
-        final ValueAnimatorCompat animator = mAnimatorCreator.createAnimator();
-        animator.setInterpolator(ANIM_INTERPOLATOR);
-        animator.setDuration(PRESSED_ANIM_DURATION);
-        animator.addListener(impl);
-        animator.addUpdateListener(impl);
-        animator.setFloatValues(0, 1);
-        return animator;
-    }
-
-    private abstract class ShadowAnimatorImpl extends ValueAnimatorCompat.AnimatorListenerAdapter
-            implements ValueAnimatorCompat.AnimatorUpdateListener {
-        private boolean mValidValues;
-        private float mShadowSizeStart;
-        private float mShadowSizeEnd;
-
-        @Override
-        public void onAnimationUpdate(ValueAnimatorCompat animator) {
-            if (!mValidValues) {
-                mShadowSizeStart = mShadowDrawable.getShadowSize();
-                mShadowSizeEnd = getTargetShadowSize();
-                mValidValues = true;
-            }
-
-            mShadowDrawable.setShadowSize(mShadowSizeStart
-                    + ((mShadowSizeEnd - mShadowSizeStart) * animator.getAnimatedFraction()));
-        }
-
-        @Override
-        public void onAnimationEnd(ValueAnimatorCompat animator) {
-            mShadowDrawable.setShadowSize(mShadowSizeEnd);
-            mValidValues = false;
-        }
-
-        /**
-         * @return the shadow size we want to animate to.
-         */
-        protected abstract float getTargetShadowSize();
-    }
-
-    private class ResetElevationAnimation extends ShadowAnimatorImpl {
-        ResetElevationAnimation() {
-        }
-
-        @Override
-        protected float getTargetShadowSize() {
-            return mElevation;
-        }
-    }
-
-    private class ElevateToTranslationZAnimation extends ShadowAnimatorImpl {
-        ElevateToTranslationZAnimation() {
-        }
-
-        @Override
-        protected float getTargetShadowSize() {
-            return mElevation + mPressedTranslationZ;
-        }
-    }
-
-    private class DisabledElevationAnimation extends ShadowAnimatorImpl {
-        DisabledElevationAnimation() {
-        }
-
-        @Override
-        protected float getTargetShadowSize() {
-            return 0f;
-        }
-    }
-
-    private static ColorStateList createColorStateList(int selectedColor) {
-        final int[][] states = new int[3][];
-        final int[] colors = new int[3];
-        int i = 0;
-
-        states[i] = FOCUSED_ENABLED_STATE_SET;
-        colors[i] = selectedColor;
-        i++;
-
-        states[i] = PRESSED_ENABLED_STATE_SET;
-        colors[i] = selectedColor;
-        i++;
-
-        // Default enabled state
-        states[i] = new int[0];
-        colors[i] = Color.TRANSPARENT;
-        i++;
-
-        return new ColorStateList(states, colors);
-    }
-}
\ No newline at end of file
diff --git a/design/gingerbread/android/support/design/widget/ValueAnimatorCompatImplGingerbread.java b/design/gingerbread/android/support/design/widget/ValueAnimatorCompatImplGingerbread.java
deleted file mode 100644
index 81e59b6..0000000
--- a/design/gingerbread/android/support/design/widget/ValueAnimatorCompatImplGingerbread.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.design.widget;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.Interpolator;
-
-import java.util.ArrayList;
-
-/**
- * A 'fake' ValueAnimator implementation which uses a Runnable.
- */
-class ValueAnimatorCompatImplGingerbread extends ValueAnimatorCompat.Impl {
-
-    private static final int HANDLER_DELAY = 10;
-    private static final int DEFAULT_DURATION = 200;
-
-    private static final Handler sHandler = new Handler(Looper.getMainLooper());
-
-    private long mStartTime;
-    private boolean mIsRunning;
-    private float mAnimatedFraction;
-
-    private final int[] mIntValues = new int[2];
-    private final float[] mFloatValues = new float[2];
-
-    private long mDuration = DEFAULT_DURATION;
-    private Interpolator mInterpolator;
-    private ArrayList<AnimatorListenerProxy> mListeners;
-    private ArrayList<AnimatorUpdateListenerProxy> mUpdateListeners;
-
-    private final Runnable mRunnable = new Runnable() {
-        public void run() {
-            update();
-        }
-    };
-
-    @Override
-    public void start() {
-        if (mIsRunning) {
-            // If we're already running, ignore
-            return;
-        }
-        if (mInterpolator == null) {
-            mInterpolator = new AccelerateDecelerateInterpolator();
-        }
-        mIsRunning = true;
-
-        // Reset the animated fraction
-        mAnimatedFraction = 0f;
-
-        startInternal();
-    }
-
-    final void startInternal() {
-        mStartTime = SystemClock.uptimeMillis();
-        dispatchAnimationUpdate();
-        dispatchAnimationStart();
-        // Now start our animation ticker
-        sHandler.postDelayed(mRunnable, HANDLER_DELAY);
-    }
-
-    @Override
-    public boolean isRunning() {
-        return mIsRunning;
-    }
-
-    @Override
-    public void setInterpolator(Interpolator interpolator) {
-        mInterpolator = interpolator;
-    }
-
-    @Override
-    public void addListener(AnimatorListenerProxy listener) {
-        if (mListeners == null) {
-            mListeners = new ArrayList<>();
-        }
-        mListeners.add(listener);
-    }
-
-    @Override
-    public void addUpdateListener(AnimatorUpdateListenerProxy updateListener) {
-        if (mUpdateListeners == null) {
-            mUpdateListeners = new ArrayList<>();
-        }
-        mUpdateListeners.add(updateListener);
-    }
-
-    @Override
-    public void setIntValues(int from, int to) {
-        mIntValues[0] = from;
-        mIntValues[1] = to;
-    }
-
-    @Override
-    public int getAnimatedIntValue() {
-        return AnimationUtils.lerp(mIntValues[0], mIntValues[1], getAnimatedFraction());
-    }
-
-    @Override
-    public void setFloatValues(float from, float to) {
-        mFloatValues[0] = from;
-        mFloatValues[1] = to;
-    }
-
-    @Override
-    public float getAnimatedFloatValue() {
-        return AnimationUtils.lerp(mFloatValues[0], mFloatValues[1], getAnimatedFraction());
-    }
-
-    @Override
-    public void setDuration(long duration) {
-        mDuration = duration;
-    }
-
-    @Override
-    public void cancel() {
-        mIsRunning = false;
-        sHandler.removeCallbacks(mRunnable);
-
-        dispatchAnimationCancel();
-        dispatchAnimationEnd();
-    }
-
-    @Override
-    public float getAnimatedFraction() {
-        return mAnimatedFraction;
-    }
-
-    @Override
-    public void end() {
-        if (mIsRunning) {
-            mIsRunning = false;
-            sHandler.removeCallbacks(mRunnable);
-            // Set our animated fraction to 1
-            mAnimatedFraction = 1f;
-            dispatchAnimationUpdate();
-            dispatchAnimationEnd();
-        }
-    }
-
-    @Override
-    public long getDuration() {
-        return mDuration;
-    }
-
-    final void update() {
-        if (mIsRunning) {
-            // Update the animated fraction
-            final long elapsed = SystemClock.uptimeMillis() - mStartTime;
-            final float linearFraction = MathUtils.constrain(elapsed / (float) mDuration, 0f, 1f);
-            mAnimatedFraction = mInterpolator != null
-                    ? mInterpolator.getInterpolation(linearFraction)
-                    : linearFraction;
-
-            // If we're running, dispatch to the update listeners
-            dispatchAnimationUpdate();
-
-            // Check to see if we've passed the animation duration
-            if (SystemClock.uptimeMillis() >= (mStartTime + mDuration)) {
-                mIsRunning = false;
-
-                dispatchAnimationEnd();
-            }
-        }
-
-        if (mIsRunning) {
-            // If we're still running, post another delayed runnable
-            sHandler.postDelayed(mRunnable, HANDLER_DELAY);
-        }
-    }
-
-    private void dispatchAnimationUpdate() {
-        if (mUpdateListeners != null) {
-            for (int i = 0, count = mUpdateListeners.size(); i < count; i++) {
-                mUpdateListeners.get(i).onAnimationUpdate();
-            }
-        }
-    }
-
-    private void dispatchAnimationStart() {
-        if (mListeners != null) {
-            for (int i = 0, count = mListeners.size(); i < count; i++) {
-                mListeners.get(i).onAnimationStart();
-            }
-        }
-    }
-
-    private void dispatchAnimationCancel() {
-        if (mListeners != null) {
-            for (int i = 0, count = mListeners.size(); i < count; i++) {
-                mListeners.get(i).onAnimationCancel();
-            }
-        }
-    }
-
-    private void dispatchAnimationEnd() {
-        if (mListeners != null) {
-            for (int i = 0, count = mListeners.size(); i < count; i++) {
-                mListeners.get(i).onAnimationEnd();
-            }
-        }
-    }
-}
diff --git a/design/honeycomb-mr1/android/support/design/widget/ValueAnimatorCompatImplHoneycombMr1.java b/design/honeycomb-mr1/android/support/design/widget/ValueAnimatorCompatImplHoneycombMr1.java
deleted file mode 100644
index e1f287b..0000000
--- a/design/honeycomb-mr1/android/support/design/widget/ValueAnimatorCompatImplHoneycombMr1.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.design.widget;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.view.animation.Interpolator;
-
-@RequiresApi(12)
-@TargetApi(12)
-class ValueAnimatorCompatImplHoneycombMr1 extends ValueAnimatorCompat.Impl {
-
-    private final ValueAnimator mValueAnimator;
-
-    ValueAnimatorCompatImplHoneycombMr1() {
-        mValueAnimator = new ValueAnimator();
-    }
-
-    @Override
-    public void start() {
-        mValueAnimator.start();
-    }
-
-    @Override
-    public boolean isRunning() {
-        return mValueAnimator.isRunning();
-    }
-
-    @Override
-    public void setInterpolator(Interpolator interpolator) {
-        mValueAnimator.setInterpolator(interpolator);
-    }
-
-    @Override
-    public void addUpdateListener(final AnimatorUpdateListenerProxy updateListener) {
-        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                updateListener.onAnimationUpdate();
-            }
-        });
-    }
-
-    @Override
-    public void addListener(final AnimatorListenerProxy listener) {
-        mValueAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animator) {
-                listener.onAnimationStart();
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animator) {
-                listener.onAnimationEnd();
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animator) {
-                listener.onAnimationCancel();
-            }
-        });
-    }
-
-    @Override
-    public void setIntValues(int from, int to) {
-        mValueAnimator.setIntValues(from, to);
-    }
-
-    @Override
-    public int getAnimatedIntValue() {
-        return (int) mValueAnimator.getAnimatedValue();
-    }
-
-    @Override
-    public void setFloatValues(float from, float to) {
-        mValueAnimator.setFloatValues(from, to);
-    }
-
-    @Override
-    public float getAnimatedFloatValue() {
-        return (float) mValueAnimator.getAnimatedValue();
-    }
-
-    @Override
-    public void setDuration(long duration) {
-        mValueAnimator.setDuration(duration);
-    }
-
-    @Override
-    public void cancel() {
-        mValueAnimator.cancel();
-    }
-
-    @Override
-    public float getAnimatedFraction() {
-        return mValueAnimator.getAnimatedFraction();
-    }
-
-    @Override
-    public void end() {
-        mValueAnimator.end();
-    }
-
-    @Override
-    public long getDuration() {
-        return mValueAnimator.getDuration();
-    }
-}
diff --git a/design/honeycomb/android/support/design/widget/ViewGroupUtilsHoneycomb.java b/design/honeycomb/android/support/design/widget/ViewGroupUtilsHoneycomb.java
deleted file mode 100644
index 49a07cd..0000000
--- a/design/honeycomb/android/support/design/widget/ViewGroupUtilsHoneycomb.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.design.widget;
-
-import android.annotation.TargetApi;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.support.annotation.RequiresApi;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-@RequiresApi(11)
-@TargetApi(11)
-class ViewGroupUtilsHoneycomb {
-    private static final ThreadLocal<Matrix> sMatrix = new ThreadLocal<>();
-    private static final ThreadLocal<RectF> sRectF = new ThreadLocal<>();
-
-    public static void offsetDescendantRect(ViewGroup group, View child, Rect rect) {
-        Matrix m = sMatrix.get();
-        if (m == null) {
-            m = new Matrix();
-            sMatrix.set(m);
-        } else {
-            m.reset();
-        }
-
-        offsetDescendantMatrix(group, child, m);
-
-        RectF rectF = sRectF.get();
-        if (rectF == null) {
-            rectF = new RectF();
-            sRectF.set(rectF);
-        }
-        rectF.set(rect);
-        m.mapRect(rectF);
-        rect.set((int) (rectF.left + 0.5f), (int) (rectF.top + 0.5f),
-                (int) (rectF.right + 0.5f), (int) (rectF.bottom + 0.5f));
-    }
-
-    static void offsetDescendantMatrix(ViewParent target, View view, Matrix m) {
-        final ViewParent parent = view.getParent();
-        if (parent instanceof View && parent != target) {
-            final View vp = (View) parent;
-            offsetDescendantMatrix(target, vp, m);
-            m.preTranslate(-vp.getScrollX(), -vp.getScrollY());
-        }
-
-        m.preTranslate(view.getLeft(), view.getTop());
-
-        if (!view.getMatrix().isIdentity()) {
-            m.preConcat(view.getMatrix());
-        }
-    }
-}
diff --git a/design/ics/android/support/design/internal/BottomNavigationAnimationHelperIcs.java b/design/ics/android/support/design/internal/BottomNavigationAnimationHelperIcs.java
deleted file mode 100644
index 6681d0b..0000000
--- a/design/ics/android/support/design/internal/BottomNavigationAnimationHelperIcs.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.design.internal;
-
-import android.support.transition.AutoTransition;
-import android.support.transition.TransitionManager;
-import android.support.transition.TransitionSet;
-import android.support.v4.view.animation.FastOutSlowInInterpolator;
-import android.view.ViewGroup;
-
-class BottomNavigationAnimationHelperIcs extends BottomNavigationAnimationHelperBase {
-    private static final long ACTIVE_ANIMATION_DURATION_MS = 115L;
-
-    private final TransitionSet mSet;
-
-    BottomNavigationAnimationHelperIcs() {
-        mSet = new AutoTransition();
-        mSet.setOrdering(TransitionSet.ORDERING_TOGETHER);
-        mSet.setDuration(ACTIVE_ANIMATION_DURATION_MS);
-        mSet.setInterpolator(new FastOutSlowInInterpolator());
-        TextScale textScale = new TextScale();
-        mSet.addTransition(textScale);
-    }
-
-    void beginDelayedTransition(ViewGroup view) {
-        TransitionManager.beginDelayedTransition(view, mSet);
-    }
-}
diff --git a/design/ics/android/support/design/widget/FloatingActionButtonIcs.java b/design/ics/android/support/design/widget/FloatingActionButtonIcs.java
deleted file mode 100644
index 73b4cac..0000000
--- a/design/ics/android/support/design/widget/FloatingActionButtonIcs.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.design.widget;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.support.annotation.Nullable;
-import android.support.annotation.RequiresApi;
-import android.support.v4.view.ViewCompat;
-import android.view.View;
-
-@RequiresApi(14)
-@TargetApi(14)
-class FloatingActionButtonIcs extends FloatingActionButtonGingerbread {
-
-    private float mRotation;
-
-    FloatingActionButtonIcs(VisibilityAwareImageButton view,
-            ShadowViewDelegate shadowViewDelegate, ValueAnimatorCompat.Creator animatorCreator) {
-        super(view, shadowViewDelegate, animatorCreator);
-        mRotation = mView.getRotation();
-    }
-
-    @Override
-    boolean requirePreDrawListener() {
-        return true;
-    }
-
-    @Override
-    void onPreDraw() {
-        final float rotation = mView.getRotation();
-        if (mRotation != rotation) {
-            mRotation = rotation;
-            updateFromViewRotation();
-        }
-    }
-
-    @Override
-    void hide(@Nullable final InternalVisibilityChangedListener listener, final boolean fromUser) {
-        if (isOrWillBeHidden()) {
-            // We either are or will soon be hidden, skip the call
-            return;
-        }
-
-        mView.animate().cancel();
-
-        if (shouldAnimateVisibilityChange()) {
-            mAnimState = ANIM_STATE_HIDING;
-
-            mView.animate()
-                    .scaleX(0f)
-                    .scaleY(0f)
-                    .alpha(0f)
-                    .setDuration(SHOW_HIDE_ANIM_DURATION)
-                    .setInterpolator(AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR)
-                    .setListener(new AnimatorListenerAdapter() {
-                        private boolean mCancelled;
-
-                        @Override
-                        public void onAnimationStart(Animator animation) {
-                            mView.internalSetVisibility(View.VISIBLE, fromUser);
-                            mCancelled = false;
-                        }
-
-                        @Override
-                        public void onAnimationCancel(Animator animation) {
-                            mCancelled = true;
-                        }
-
-                        @Override
-                        public void onAnimationEnd(Animator animation) {
-                            mAnimState = ANIM_STATE_NONE;
-
-                            if (!mCancelled) {
-                                mView.internalSetVisibility(fromUser ? View.GONE : View.INVISIBLE,
-                                        fromUser);
-                                if (listener != null) {
-                                    listener.onHidden();
-                                }
-                            }
-                        }
-                    });
-        } else {
-            // If the view isn't laid out, or we're in the editor, don't run the animation
-            mView.internalSetVisibility(fromUser ? View.GONE : View.INVISIBLE, fromUser);
-            if (listener != null) {
-                listener.onHidden();
-            }
-        }
-    }
-
-    @Override
-    void show(@Nullable final InternalVisibilityChangedListener listener, final boolean fromUser) {
-        if (isOrWillBeShown()) {
-            // We either are or will soon be visible, skip the call
-            return;
-        }
-
-        mView.animate().cancel();
-
-        if (shouldAnimateVisibilityChange()) {
-            mAnimState = ANIM_STATE_SHOWING;
-
-            if (mView.getVisibility() != View.VISIBLE) {
-                // If the view isn't visible currently, we'll animate it from a single pixel
-                mView.setAlpha(0f);
-                mView.setScaleY(0f);
-                mView.setScaleX(0f);
-            }
-
-            mView.animate()
-                    .scaleX(1f)
-                    .scaleY(1f)
-                    .alpha(1f)
-                    .setDuration(SHOW_HIDE_ANIM_DURATION)
-                    .setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR)
-                    .setListener(new AnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationStart(Animator animation) {
-                            mView.internalSetVisibility(View.VISIBLE, fromUser);
-                        }
-
-                        @Override
-                        public void onAnimationEnd(Animator animation) {
-                            mAnimState = ANIM_STATE_NONE;
-                            if (listener != null) {
-                                listener.onShown();
-                            }
-                        }
-                    });
-        } else {
-            mView.internalSetVisibility(View.VISIBLE, fromUser);
-            mView.setAlpha(1f);
-            mView.setScaleY(1f);
-            mView.setScaleX(1f);
-            if (listener != null) {
-                listener.onShown();
-            }
-        }
-    }
-
-    private boolean shouldAnimateVisibilityChange() {
-        return ViewCompat.isLaidOut(mView) && !mView.isInEditMode();
-    }
-
-    private void updateFromViewRotation() {
-        if (Build.VERSION.SDK_INT == 19) {
-            // KitKat seems to have an issue with views which are rotated with angles which are
-            // not divisible by 90. Worked around by moving to software rendering in these cases.
-            if ((mRotation % 90) != 0) {
-                if (mView.getLayerType() != View.LAYER_TYPE_SOFTWARE) {
-                    mView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-                }
-            } else {
-                if (mView.getLayerType() != View.LAYER_TYPE_NONE) {
-                    mView.setLayerType(View.LAYER_TYPE_NONE, null);
-                }
-            }
-        }
-
-        // Offset any View rotation
-        if (mShadowDrawable != null) {
-            mShadowDrawable.setRotation(-mRotation);
-        }
-        if (mBorderDrawable != null) {
-            mBorderDrawable.setRotation(-mRotation);
-        }
-    }
-}
diff --git a/design/lollipop/android/support/design/widget/CircularBorderDrawableLollipop.java b/design/lollipop/android/support/design/widget/CircularBorderDrawableLollipop.java
index ed03d35..8008404 100644
--- a/design/lollipop/android/support/design/widget/CircularBorderDrawableLollipop.java
+++ b/design/lollipop/android/support/design/widget/CircularBorderDrawableLollipop.java
@@ -16,7 +16,6 @@
 
 package android.support.design.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.Outline;
 import android.support.annotation.RequiresApi;
 
@@ -24,7 +23,6 @@
  * Lollipop version of {@link CircularBorderDrawable}.
  */
 @RequiresApi(21)
-@TargetApi(21)
 class CircularBorderDrawableLollipop extends CircularBorderDrawable {
 
     @Override
diff --git a/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java b/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java
index 24ef314..d7c258f 100644
--- a/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java
+++ b/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java
@@ -19,7 +19,6 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.StateListAnimator;
-import android.annotation.TargetApi;
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
@@ -34,14 +33,13 @@
 import android.view.View;
 
 @RequiresApi(21)
-@TargetApi(21)
-class FloatingActionButtonLollipop extends FloatingActionButtonIcs {
+class FloatingActionButtonLollipop extends FloatingActionButtonImpl {
 
     private InsetDrawable mInsetDrawable;
 
     FloatingActionButtonLollipop(VisibilityAwareImageButton view,
-            ShadowViewDelegate shadowViewDelegate, ValueAnimatorCompat.Creator animatorCreator) {
-        super(view, shadowViewDelegate, animatorCreator);
+            ShadowViewDelegate shadowViewDelegate) {
+        super(view, shadowViewDelegate);
     }
 
     @Override
diff --git a/design/lollipop/android/support/design/widget/ViewUtilsLollipop.java b/design/lollipop/android/support/design/widget/ViewUtilsLollipop.java
index 8dfa926..5927e9b 100644
--- a/design/lollipop/android/support/design/widget/ViewUtilsLollipop.java
+++ b/design/lollipop/android/support/design/widget/ViewUtilsLollipop.java
@@ -19,7 +19,6 @@
 import android.animation.AnimatorInflater;
 import android.animation.ObjectAnimator;
 import android.animation.StateListAnimator;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.support.annotation.RequiresApi;
@@ -29,7 +28,6 @@
 import android.view.ViewOutlineProvider;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ViewUtilsLollipop {
 
     private static final int[] STATE_LIST_ANIM_ATTRS = new int[] {android.R.attr.stateListAnimator};
diff --git a/design/res/anim/design_fab_in.xml b/design/res/anim/design_fab_in.xml
deleted file mode 100644
index 294050f..0000000
--- a/design/res/anim/design_fab_in.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 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.
-  -->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <alpha android:fromAlpha="0.0"
-           android:toAlpha="1.0"/>
-
-    <scale android:fromXScale="0.0"
-           android:fromYScale="0.0"
-           android:toXScale="1.0"
-           android:toYScale="1.0"
-           android:pivotX="50%"
-           android:pivotY="50%"/>
-
-</set>
diff --git a/design/res/anim/design_fab_out.xml b/design/res/anim/design_fab_out.xml
deleted file mode 100644
index 0f80a9a..0000000
--- a/design/res/anim/design_fab_out.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 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.
-  -->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <alpha android:fromAlpha="1.0"
-           android:toAlpha="0.0"/>
-
-    <scale android:fromXScale="1.0"
-           android:fromYScale="1.0"
-           android:toXScale="0.0"
-           android:toYScale="0.0"
-           android:pivotX="50%"
-           android:pivotY="50%"/>
-
-</set>
diff --git a/design/res/layout/design_bottom_sheet_dialog.xml b/design/res/layout/design_bottom_sheet_dialog.xml
index c99caa6..f4edb66 100644
--- a/design/res/layout/design_bottom_sheet_dialog.xml
+++ b/design/res/layout/design_bottom_sheet_dialog.xml
@@ -32,7 +32,6 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal|top"
-            android:clickable="true"
             app:layout_behavior="@string/bottom_sheet_behavior"
             style="?attr/bottomSheetStyle"/>
 
diff --git a/design/src/android/support/design/internal/BaselineLayout.java b/design/src/android/support/design/internal/BaselineLayout.java
index 23a04cd..d2a7be4 100644
--- a/design/src/android/support/design/internal/BaselineLayout.java
+++ b/design/src/android/support/design/internal/BaselineLayout.java
@@ -17,8 +17,6 @@
 package android.support.design.internal;
 
 import android.content.Context;
-import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.ViewUtils;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
@@ -66,8 +64,7 @@
             }
             maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
             maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(child));
+            childState = View.combineMeasuredStates(childState, child.getMeasuredState());
         }
         if (maxChildBaseline != -1) {
             maxChildDescent = Math.max(maxChildDescent, getPaddingBottom());
@@ -77,8 +74,8 @@
         maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
         maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
         setMeasuredDimension(
-                ViewCompat.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
-                ViewCompat.resolveSizeAndState(maxHeight, heightMeasureSpec,
+                View.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+                View.resolveSizeAndState(maxHeight, heightMeasureSpec,
                         childState << MEASURED_HEIGHT_STATE_SHIFT));
     }
 
diff --git a/design/src/android/support/design/internal/BottomNavigationItemView.java b/design/src/android/support/design/internal/BottomNavigationItemView.java
index ad05e76..f764ffa 100644
--- a/design/src/android/support/design/internal/BottomNavigationItemView.java
+++ b/design/src/android/support/design/internal/BottomNavigationItemView.java
@@ -99,6 +99,8 @@
         setIcon(itemData.getIcon());
         setTitle(itemData.getTitle());
         setId(itemData.getItemId());
+        setContentDescription(itemData.getContentDescription());
+        ViewCompat.setTooltipText(this, itemData.getTooltipText());
     }
 
     public void setItemPosition(int position) {
@@ -132,10 +134,10 @@
 
     @Override
     public void setChecked(boolean checked) {
-        ViewCompat.setPivotX(mLargeLabel, mLargeLabel.getWidth() / 2);
-        ViewCompat.setPivotY(mLargeLabel, mLargeLabel.getBaseline());
-        ViewCompat.setPivotX(mSmallLabel, mSmallLabel.getWidth() / 2);
-        ViewCompat.setPivotY(mSmallLabel, mSmallLabel.getBaseline());
+        mLargeLabel.setPivotX(mLargeLabel.getWidth() / 2);
+        mLargeLabel.setPivotY(mLargeLabel.getBaseline());
+        mSmallLabel.setPivotX(mSmallLabel.getWidth() / 2);
+        mSmallLabel.setPivotY(mSmallLabel.getBaseline());
         if (mShiftingMode) {
             if (checked) {
                 LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
@@ -143,16 +145,16 @@
                 iconParams.topMargin = mDefaultMargin;
                 mIcon.setLayoutParams(iconParams);
                 mLargeLabel.setVisibility(VISIBLE);
-                ViewCompat.setScaleX(mLargeLabel, 1f);
-                ViewCompat.setScaleY(mLargeLabel, 1f);
+                mLargeLabel.setScaleX(1f);
+                mLargeLabel.setScaleY(1f);
             } else {
                 LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
                 iconParams.gravity = Gravity.CENTER;
                 iconParams.topMargin = mDefaultMargin;
                 mIcon.setLayoutParams(iconParams);
                 mLargeLabel.setVisibility(INVISIBLE);
-                ViewCompat.setScaleX(mLargeLabel, 0.5f);
-                ViewCompat.setScaleY(mLargeLabel, 0.5f);
+                mLargeLabel.setScaleX(0.5f);
+                mLargeLabel.setScaleY(0.5f);
             }
             mSmallLabel.setVisibility(INVISIBLE);
         } else {
@@ -164,10 +166,10 @@
                 mLargeLabel.setVisibility(VISIBLE);
                 mSmallLabel.setVisibility(INVISIBLE);
 
-                ViewCompat.setScaleX(mLargeLabel, 1f);
-                ViewCompat.setScaleY(mLargeLabel, 1f);
-                ViewCompat.setScaleX(mSmallLabel, mScaleUpFactor);
-                ViewCompat.setScaleY(mSmallLabel, mScaleUpFactor);
+                mLargeLabel.setScaleX(1f);
+                mLargeLabel.setScaleY(1f);
+                mSmallLabel.setScaleX(mScaleUpFactor);
+                mSmallLabel.setScaleY(mScaleUpFactor);
             } else {
                 LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
                 iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
@@ -176,10 +178,10 @@
                 mLargeLabel.setVisibility(INVISIBLE);
                 mSmallLabel.setVisibility(VISIBLE);
 
-                ViewCompat.setScaleX(mLargeLabel, mScaleDownFactor);
-                ViewCompat.setScaleY(mLargeLabel, mScaleDownFactor);
-                ViewCompat.setScaleX(mSmallLabel, 1f);
-                ViewCompat.setScaleY(mSmallLabel, 1f);
+                mLargeLabel.setScaleX(mScaleDownFactor);
+                mLargeLabel.setScaleY(mScaleDownFactor);
+                mSmallLabel.setScaleX(1f);
+                mSmallLabel.setScaleY(1f);
             }
         }
 
diff --git a/design/src/android/support/design/internal/BottomNavigationMenuView.java b/design/src/android/support/design/internal/BottomNavigationMenuView.java
index d80cd64..f2790b8 100644
--- a/design/src/android/support/design/internal/BottomNavigationMenuView.java
+++ b/design/src/android/support/design/internal/BottomNavigationMenuView.java
@@ -21,12 +21,15 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
-import android.os.Build;
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
 import android.support.design.R;
+import android.support.transition.AutoTransition;
+import android.support.transition.TransitionManager;
+import android.support.transition.TransitionSet;
 import android.support.v4.util.Pools;
 import android.support.v4.view.ViewCompat;
+import android.support.v4.view.animation.FastOutSlowInInterpolator;
 import android.support.v7.view.menu.MenuBuilder;
 import android.support.v7.view.menu.MenuItemImpl;
 import android.support.v7.view.menu.MenuView;
@@ -40,12 +43,14 @@
  */
 @RestrictTo(LIBRARY_GROUP)
 public class BottomNavigationMenuView extends ViewGroup implements MenuView {
+    private static final long ACTIVE_ANIMATION_DURATION_MS = 115L;
+
+    private final TransitionSet mSet;
     private final int mInactiveItemMaxWidth;
     private final int mInactiveItemMinWidth;
     private final int mActiveItemMaxWidth;
     private final int mItemHeight;
     private final OnClickListener mOnClickListener;
-    private final BottomNavigationAnimationHelperBase mAnimationHelper;
     private static final Pools.Pool<BottomNavigationItemView> sItemPool =
             new Pools.SynchronizedPool<>(5);
 
@@ -77,11 +82,11 @@
                 R.dimen.design_bottom_navigation_active_item_max_width);
         mItemHeight = res.getDimensionPixelSize(R.dimen.design_bottom_navigation_height);
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            mAnimationHelper = new BottomNavigationAnimationHelperIcs();
-        } else {
-            mAnimationHelper = new BottomNavigationAnimationHelperBase();
-        }
+        mSet = new AutoTransition();
+        mSet.setOrdering(TransitionSet.ORDERING_TOGETHER);
+        mSet.setDuration(ACTIVE_ANIMATION_DURATION_MS);
+        mSet.setInterpolator(new FastOutSlowInInterpolator());
+        mSet.addTransition(new TextScale());
 
         mOnClickListener = new OnClickListener() {
             @Override
@@ -148,9 +153,9 @@
             totalWidth += child.getMeasuredWidth();
         }
         setMeasuredDimension(
-                ViewCompat.resolveSizeAndState(totalWidth,
+                View.resolveSizeAndState(totalWidth,
                         MeasureSpec.makeMeasureSpec(totalWidth, MeasureSpec.EXACTLY), 0),
-                ViewCompat.resolveSizeAndState(mItemHeight, heightSpec, 0));
+                View.resolveSizeAndState(mItemHeight, heightSpec, 0));
     }
 
     @Override
@@ -302,7 +307,7 @@
             mPresenter.setUpdateSuspended(false);
         }
         if (previousSelectedId != mSelectedItemId) {
-            mAnimationHelper.beginDelayedTransition(this);
+            TransitionManager.beginDelayedTransition(this);
         }
     }
 
diff --git a/design/src/android/support/design/internal/ForegroundLinearLayout.java b/design/src/android/support/design/internal/ForegroundLinearLayout.java
index c75603b..bda83dd 100644
--- a/design/src/android/support/design/internal/ForegroundLinearLayout.java
+++ b/design/src/android/support/design/internal/ForegroundLinearLayout.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -121,7 +120,6 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     @Override
     public void jumpDrawablesToCurrentState() {
         super.jumpDrawablesToCurrentState();
@@ -227,7 +225,6 @@
     }
 
     @RequiresApi(21)
-    @TargetApi(21)
     @Override
     public void drawableHotspotChanged(float x, float y) {
         super.drawableHotspotChanged(x, y);
diff --git a/design/src/android/support/design/internal/NavigationMenuItemView.java b/design/src/android/support/design/internal/NavigationMenuItemView.java
index 8bece63..2a4367c 100644
--- a/design/src/android/support/design/internal/NavigationMenuItemView.java
+++ b/design/src/android/support/design/internal/NavigationMenuItemView.java
@@ -116,6 +116,8 @@
         setTitle(itemData.getTitle());
         setIcon(itemData.getIcon());
         setActionView(itemData.getActionView());
+        setContentDescription(itemData.getContentDescription());
+        ViewCompat.setTooltipText(this, itemData.getTooltipText());
         adjustAppearance();
     }
 
diff --git a/design/src/android/support/design/internal/SnackbarContentLayout.java b/design/src/android/support/design/internal/SnackbarContentLayout.java
index dca1d6b..55a66fb 100644
--- a/design/src/android/support/design/internal/SnackbarContentLayout.java
+++ b/design/src/android/support/design/internal/SnackbarContentLayout.java
@@ -131,26 +131,26 @@
 
     @Override
     public void animateContentIn(int delay, int duration) {
-        ViewCompat.setAlpha(mMessageView, 0f);
-        ViewCompat.animate(mMessageView).alpha(1f).setDuration(duration)
+        mMessageView.setAlpha(0f);
+        mMessageView.animate().alpha(1f).setDuration(duration)
                 .setStartDelay(delay).start();
 
         if (mActionView.getVisibility() == VISIBLE) {
-            ViewCompat.setAlpha(mActionView, 0f);
-            ViewCompat.animate(mActionView).alpha(1f).setDuration(duration)
+            mActionView.setAlpha(0f);
+            mActionView.animate().alpha(1f).setDuration(duration)
                     .setStartDelay(delay).start();
         }
     }
 
     @Override
     public void animateContentOut(int delay, int duration) {
-        ViewCompat.setAlpha(mMessageView, 1f);
-        ViewCompat.animate(mMessageView).alpha(0f).setDuration(duration)
+        mMessageView.setAlpha(1f);
+        mMessageView.animate().alpha(0f).setDuration(duration)
                 .setStartDelay(delay).start();
 
         if (mActionView.getVisibility() == VISIBLE) {
-            ViewCompat.setAlpha(mActionView, 1f);
-            ViewCompat.animate(mActionView).alpha(0f).setDuration(duration)
+            mActionView.setAlpha(1f);
+            mActionView.animate().alpha(0f).setDuration(duration)
                     .setStartDelay(delay).start();
         }
     }
diff --git a/design/ics/android/support/design/internal/TextScale.java b/design/src/android/support/design/internal/TextScale.java
similarity index 96%
rename from design/ics/android/support/design/internal/TextScale.java
rename to design/src/android/support/design/internal/TextScale.java
index c017223..06c9472 100644
--- a/design/ics/android/support/design/internal/TextScale.java
+++ b/design/src/android/support/design/internal/TextScale.java
@@ -18,8 +18,8 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
+import android.support.annotation.RestrictTo;
 import android.support.transition.Transition;
 import android.support.transition.TransitionValues;
 import android.view.ViewGroup;
@@ -30,8 +30,8 @@
 /**
  * @hide
  */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(14)
-@TargetApi(14)
 public class TextScale extends Transition {
     private static final String PROPNAME_SCALE = "android:textscale:scale";
 
diff --git a/design/src/android/support/design/widget/AppBarLayout.java b/design/src/android/support/design/widget/AppBarLayout.java
index ff41db8..e350cd4 100644
--- a/design/src/android/support/design/widget/AppBarLayout.java
+++ b/design/src/android/support/design/widget/AppBarLayout.java
@@ -19,7 +19,7 @@
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 import static android.support.design.widget.ViewUtils.objectEquals;
 
-import android.annotation.TargetApi;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
@@ -690,14 +690,12 @@
         }
 
         @RequiresApi(19)
-        @TargetApi(19)
         public LayoutParams(LinearLayout.LayoutParams source) {
             // The copy constructor called here only exists on API 19+.
             super(source);
         }
 
         @RequiresApi(19)
-        @TargetApi(19)
         public LayoutParams(LayoutParams source) {
             // The copy constructor called here only exists on API 19+.
             super(source);
@@ -794,7 +792,7 @@
         private boolean mSkipNestedPreScroll;
         private boolean mWasNestedFlung;
 
-        private ValueAnimatorCompat mOffsetAnimator;
+        private ValueAnimator mOffsetAnimator;
 
         private int mOffsetToChildIndexOnLayout = INVALID_POSITION;
         private boolean mOffsetToChildIndexOnLayoutIsMinHeight;
@@ -954,13 +952,13 @@
             }
 
             if (mOffsetAnimator == null) {
-                mOffsetAnimator = ViewUtils.createAnimator();
+                mOffsetAnimator = new ValueAnimator();
                 mOffsetAnimator.setInterpolator(AnimationUtils.DECELERATE_INTERPOLATOR);
-                mOffsetAnimator.addUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() {
+                mOffsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                     @Override
-                    public void onAnimationUpdate(ValueAnimatorCompat animator) {
+                    public void onAnimationUpdate(ValueAnimator animation) {
                         setHeaderTopBottomOffset(coordinatorLayout, child,
-                                animator.getAnimatedIntValue());
+                                (int) animation.getAnimatedValue());
                     }
                 });
             } else {
diff --git a/design/src/android/support/design/widget/BaseTransientBottomBar.java b/design/src/android/support/design/widget/BaseTransientBottomBar.java
index 9035f82..18c9ef9 100644
--- a/design/src/android/support/design/widget/BaseTransientBottomBar.java
+++ b/design/src/android/support/design/widget/BaseTransientBottomBar.java
@@ -19,6 +19,9 @@
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 import static android.support.design.widget.AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.os.Build;
@@ -31,7 +34,6 @@
 import android.support.annotation.RestrictTo;
 import android.support.design.R;
 import android.support.v4.view.ViewCompat;
-import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
 import android.support.v4.view.WindowInsetsCompat;
 import android.util.AttributeSet;
 import android.view.Gravity;
@@ -168,6 +170,12 @@
     static final int MSG_SHOW = 0;
     static final int MSG_DISMISS = 1;
 
+    // On JB/KK versions of the platform sometimes View.setTranslationY does not
+    // result in layout / draw pass, and CoordinatorLayout relies on a draw pass to
+    // happen to sync vertical positioning of all its child views
+    private static final boolean USE_OFFSET_API = (Build.VERSION.SDK_INT >= 16)
+            && (Build.VERSION.SDK_INT <= 19);
+
     static {
         sHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
             @Override
@@ -486,27 +494,48 @@
     }
 
     void animateViewIn() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            ViewCompat.setTranslationY(mView, mView.getHeight());
-            ViewCompat.animate(mView)
-                    .translationY(0f)
-                    .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
-                    .setDuration(ANIMATION_DURATION)
-                    .setListener(new ViewPropertyAnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationStart(View view) {
-                            mContentViewCallback.animateContentIn(
-                                    ANIMATION_DURATION - ANIMATION_FADE_DURATION,
-                                    ANIMATION_FADE_DURATION);
-                        }
+        if (Build.VERSION.SDK_INT >= 12) {
+            final int viewHeight = mView.getHeight();
+            if (USE_OFFSET_API) {
+                ViewCompat.offsetTopAndBottom(mView, viewHeight);
+            } else {
+                mView.setTranslationY(viewHeight);
+            }
+            final ValueAnimator animator = new ValueAnimator();
+            animator.setIntValues(viewHeight, 0);
+            animator.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
+            animator.setDuration(ANIMATION_DURATION);
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animator) {
+                    mContentViewCallback.animateContentIn(
+                            ANIMATION_DURATION - ANIMATION_FADE_DURATION,
+                            ANIMATION_FADE_DURATION);
+                }
 
-                        @Override
-                        public void onAnimationEnd(View view) {
-                            onViewShown();
-                        }
-                    }).start();
+                @Override
+                public void onAnimationEnd(Animator animator) {
+                    onViewShown();
+                }
+            });
+            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                private int mPreviousAnimatedIntValue = viewHeight;
+
+                @Override
+                public void onAnimationUpdate(ValueAnimator animator) {
+                    int currentAnimatedIntValue = (int) animator.getAnimatedValue();
+                    if (USE_OFFSET_API) {
+                        ViewCompat.offsetTopAndBottom(mView,
+                                currentAnimatedIntValue - mPreviousAnimatedIntValue);
+                    } else {
+                        mView.setTranslationY(currentAnimatedIntValue);
+                    }
+                    mPreviousAnimatedIntValue = currentAnimatedIntValue;
+                }
+            });
+            animator.start();
         } else {
-            Animation anim = AnimationUtils.loadAnimation(mView.getContext(),
+            final Animation anim = AnimationUtils.loadAnimation(mView.getContext(),
                     R.anim.design_snackbar_in);
             anim.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
             anim.setDuration(ANIMATION_DURATION);
@@ -527,24 +556,40 @@
     }
 
     private void animateViewOut(final int event) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            ViewCompat.animate(mView)
-                    .translationY(mView.getHeight())
-                    .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
-                    .setDuration(ANIMATION_DURATION)
-                    .setListener(new ViewPropertyAnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationStart(View view) {
-                            mContentViewCallback.animateContentOut(0, ANIMATION_FADE_DURATION);
-                        }
+        if (Build.VERSION.SDK_INT >= 12) {
+            final ValueAnimator animator = new ValueAnimator();
+            animator.setIntValues(0, mView.getHeight());
+            animator.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
+            animator.setDuration(ANIMATION_DURATION);
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animator) {
+                    mContentViewCallback.animateContentOut(0, ANIMATION_FADE_DURATION);
+                }
 
-                        @Override
-                        public void onAnimationEnd(View view) {
-                            onViewHidden(event);
-                        }
-                    }).start();
+                @Override
+                public void onAnimationEnd(Animator animator) {
+                    onViewHidden(event);
+                }
+            });
+            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                private int mPreviousAnimatedIntValue = 0;
+
+                @Override
+                public void onAnimationUpdate(ValueAnimator animator) {
+                    int currentAnimatedIntValue = (int) animator.getAnimatedValue();
+                    if (USE_OFFSET_API) {
+                        ViewCompat.offsetTopAndBottom(mView,
+                                currentAnimatedIntValue - mPreviousAnimatedIntValue);
+                    } else {
+                        mView.setTranslationY(currentAnimatedIntValue);
+                    }
+                    mPreviousAnimatedIntValue = currentAnimatedIntValue;
+                }
+            });
+            animator.start();
         } else {
-            Animation anim = AnimationUtils.loadAnimation(mView.getContext(),
+            final Animation anim = AnimationUtils.loadAnimation(mView.getContext(),
                     R.anim.design_snackbar_out);
             anim.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
             anim.setDuration(ANIMATION_DURATION);
diff --git a/design/src/android/support/design/widget/BottomSheetBehavior.java b/design/src/android/support/design/widget/BottomSheetBehavior.java
index e745217..a69b8bd 100644
--- a/design/src/android/support/design/widget/BottomSheetBehavior.java
+++ b/design/src/android/support/design/widget/BottomSheetBehavior.java
@@ -31,8 +31,6 @@
 import android.support.v4.os.ParcelableCompatCreatorCallbacks;
 import android.support.v4.view.AbsSavedState;
 import android.support.v4.view.MotionEventCompat;
-import android.support.v4.view.NestedScrollingChild;
-import android.support.v4.view.VelocityTrackerCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.widget.ViewDragHelper;
 import android.util.AttributeSet;
@@ -597,8 +595,9 @@
         return Math.abs(newTop - mMaxOffset) / (float) mPeekHeight > HIDE_THRESHOLD;
     }
 
-    private View findScrollingChild(View view) {
-        if (view instanceof NestedScrollingChild) {
+    @VisibleForTesting
+    View findScrollingChild(View view) {
+        if (ViewCompat.isNestedScrollingEnabled(view)) {
             return view;
         }
         if (view instanceof ViewGroup) {
@@ -615,7 +614,7 @@
 
     private float getYVelocity() {
         mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-        return VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId);
+        return mVelocityTracker.getYVelocity(mActivePointerId);
     }
 
     void startSettlingAnimation(View child, int state) {
@@ -629,9 +628,11 @@
         } else {
             throw new IllegalArgumentException("Illegal state argument: " + state);
         }
-        setStateInternal(STATE_SETTLING);
         if (mViewDragHelper.smoothSlideViewTo(child, child.getLeft(), top)) {
+            setStateInternal(STATE_SETTLING);
             ViewCompat.postOnAnimation(child, new SettleRunnable(child, state));
+        } else {
+            setStateInternal(state);
         }
     }
 
diff --git a/design/src/android/support/design/widget/BottomSheetDialog.java b/design/src/android/support/design/widget/BottomSheetDialog.java
index c5fccb0..6ee5d68 100644
--- a/design/src/android/support/design/widget/BottomSheetDialog.java
+++ b/design/src/android/support/design/widget/BottomSheetDialog.java
@@ -29,6 +29,7 @@
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
 import android.support.v7.app.AppCompatDialog;
 import android.util.TypedValue;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
@@ -161,6 +162,13 @@
                 return super.performAccessibilityAction(host, action, args);
             }
         });
+        bottomSheet.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View view, MotionEvent event) {
+                // Consume the event and prevent it from falling through
+                return true;
+            }
+        });
         return coordinator;
     }
 
diff --git a/design/src/android/support/design/widget/CollapsingToolbarLayout.java b/design/src/android/support/design/widget/CollapsingToolbarLayout.java
index 5f8de36..cb24537 100644
--- a/design/src/android/support/design/widget/CollapsingToolbarLayout.java
+++ b/design/src/android/support/design/widget/CollapsingToolbarLayout.java
@@ -20,7 +20,7 @@
 import static android.support.design.widget.MathUtils.constrain;
 import static android.support.design.widget.ViewUtils.objectEquals;
 
-import android.annotation.TargetApi;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
@@ -125,7 +125,7 @@
     Drawable mStatusBarScrim;
     private int mScrimAlpha;
     private boolean mScrimsAreShown;
-    private ValueAnimatorCompat mScrimAnimator;
+    private ValueAnimator mScrimAnimator;
     private long mScrimAnimationDuration;
     private int mScrimVisibleHeightTrigger = -1;
 
@@ -595,16 +595,16 @@
     private void animateScrim(int targetAlpha) {
         ensureToolbar();
         if (mScrimAnimator == null) {
-            mScrimAnimator = ViewUtils.createAnimator();
+            mScrimAnimator = new ValueAnimator();
             mScrimAnimator.setDuration(mScrimAnimationDuration);
             mScrimAnimator.setInterpolator(
                     targetAlpha > mScrimAlpha
                             ? AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR
                             : AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR);
-            mScrimAnimator.addUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() {
+            mScrimAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                 @Override
-                public void onAnimationUpdate(ValueAnimatorCompat animator) {
-                    setScrimAlpha(animator.getAnimatedIntValue());
+                public void onAnimationUpdate(ValueAnimator animator) {
+                    setScrimAlpha((int) animator.getAnimatedValue());
                 }
             });
         } else if (mScrimAnimator.isRunning()) {
@@ -1185,7 +1185,6 @@
         }
 
         @RequiresApi(19)
-        @TargetApi(19)
         public LayoutParams(FrameLayout.LayoutParams source) {
             // The copy constructor called here only exists on API 19+.
             super(source);
diff --git a/design/src/android/support/design/widget/CoordinatorLayout.java b/design/src/android/support/design/widget/CoordinatorLayout.java
index e0ec883..ada6a0e 100644
--- a/design/src/android/support/design/widget/CoordinatorLayout.java
+++ b/design/src/android/support/design/widget/CoordinatorLayout.java
@@ -792,14 +792,13 @@
 
             heightUsed = Math.max(heightUsed, heightPadding + child.getMeasuredHeight() +
                     lp.topMargin + lp.bottomMargin);
-            childState = ViewCompat.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(child));
+            childState = View.combineMeasuredStates(childState, child.getMeasuredState());
         }
 
-        final int width = ViewCompat.resolveSizeAndState(widthUsed, widthMeasureSpec,
-                childState & ViewCompat.MEASURED_STATE_MASK);
-        final int height = ViewCompat.resolveSizeAndState(heightUsed, heightMeasureSpec,
-                childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
+        final int width = View.resolveSizeAndState(widthUsed, widthMeasureSpec,
+                childState & View.MEASURED_STATE_MASK);
+        final int height = View.resolveSizeAndState(heightUsed, heightMeasureSpec,
+                childState << View.MEASURED_HEIGHT_STATE_SHIFT);
         setMeasuredDimension(width, height);
     }
 
@@ -1371,9 +1370,9 @@
         if (behavior != null && behavior.getInsetDodgeRect(this, child, dodgeRect)) {
             // Make sure that the rect is within the view's bounds
             if (!bounds.contains(dodgeRect)) {
-                    throw new IllegalArgumentException("Rect should be within the child's bounds."
-                            + " Rect:" + dodgeRect.toShortString()
-                            + " | Bounds:" + bounds.toShortString());
+                throw new IllegalArgumentException("Rect should be within the child's bounds."
+                        + " Rect:" + dodgeRect.toShortString()
+                        + " | Bounds:" + bounds.toShortString());
             }
         } else {
             dodgeRect.set(bounds);
@@ -2165,15 +2164,6 @@
         }
 
         /**
-         * @deprecated this method is not called anymore. You can safely remove all usages
-         * and implementations. This method will be removed in a future release.
-         */
-        @Deprecated
-        public boolean isDirty(CoordinatorLayout parent, V child) {
-            return false;
-        }
-
-        /**
          * Called when the parent CoordinatorLayout is about to measure the given child view.
          *
          * <p>This method can be used to perform custom or modified measurement of a child view
diff --git a/design/src/android/support/design/widget/FloatingActionButton.java b/design/src/android/support/design/widget/FloatingActionButton.java
index 1597386..5488b2b 100644
--- a/design/src/android/support/design/widget/FloatingActionButton.java
+++ b/design/src/android/support/design/widget/FloatingActionButton.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -470,7 +469,6 @@
         getImpl().onDrawableStateChanged(getDrawableState());
     }
 
-    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
     @Override
     public void jumpDrawablesToCurrentState() {
         super.jumpDrawablesToCurrentState();
@@ -797,16 +795,10 @@
     }
 
     private FloatingActionButtonImpl createImpl() {
-        final int sdk = Build.VERSION.SDK_INT;
-        if (sdk >= 21) {
-            return new FloatingActionButtonLollipop(this, new ShadowDelegateImpl(),
-                    ViewUtils.DEFAULT_ANIMATOR_CREATOR);
-        } else if (sdk >= 14) {
-            return new FloatingActionButtonIcs(this, new ShadowDelegateImpl(),
-                    ViewUtils.DEFAULT_ANIMATOR_CREATOR);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            return new FloatingActionButtonLollipop(this, new ShadowDelegateImpl());
         } else {
-            return new FloatingActionButtonGingerbread(this, new ShadowDelegateImpl(),
-                    ViewUtils.DEFAULT_ANIMATOR_CREATOR);
+            return new FloatingActionButtonImpl(this, new ShadowDelegateImpl());
         }
     }
 
diff --git a/design/src/android/support/design/widget/HeaderBehavior.java b/design/src/android/support/design/widget/HeaderBehavior.java
index 5e555de..31dab82 100644
--- a/design/src/android/support/design/widget/HeaderBehavior.java
+++ b/design/src/android/support/design/widget/HeaderBehavior.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.support.design.widget.CoordinatorLayout.Behavior;
 import android.support.v4.view.MotionEventCompat;
-import android.support.v4.view.VelocityTrackerCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.widget.ScrollerCompat;
 import android.util.AttributeSet;
@@ -167,8 +166,7 @@
                 if (mVelocityTracker != null) {
                     mVelocityTracker.addMovement(ev);
                     mVelocityTracker.computeCurrentVelocity(1000);
-                    float yvel = VelocityTrackerCompat.getYVelocity(mVelocityTracker,
-                            mActivePointerId);
+                    float yvel = mVelocityTracker.getYVelocity(mActivePointerId);
                     fling(parent, child, -getScrollRangeForDragFling(child), 0, yvel);
                 }
                 // $FALLTHROUGH
diff --git a/design/src/android/support/design/widget/SwipeDismissBehavior.java b/design/src/android/support/design/widget/SwipeDismissBehavior.java
index 1bf3d5a..fed5332 100644
--- a/design/src/android/support/design/widget/SwipeDismissBehavior.java
+++ b/design/src/android/support/design/widget/SwipeDismissBehavior.java
@@ -345,13 +345,13 @@
                     + child.getWidth() * mAlphaEndSwipeDistance;
 
             if (left <= startAlphaDistance) {
-                ViewCompat.setAlpha(child, 1f);
+                child.setAlpha(1f);
             } else if (left >= endAlphaDistance) {
-                ViewCompat.setAlpha(child, 0f);
+                child.setAlpha(0f);
             } else {
                 // We're between the start and end distances
                 final float distance = fraction(startAlphaDistance, endAlphaDistance, left);
-                ViewCompat.setAlpha(child, clamp(0f, 1f - distance, 1f));
+                child.setAlpha(clamp(0f, 1f - distance, 1f));
             }
         }
     };
diff --git a/design/src/android/support/design/widget/TabLayout.java b/design/src/android/support/design/widget/TabLayout.java
index b6f94a4..7f3e231 100755
--- a/design/src/android/support/design/widget/TabLayout.java
+++ b/design/src/android/support/design/widget/TabLayout.java
@@ -21,7 +21,9 @@
 import static android.support.v4.view.ViewPager.SCROLL_STATE_IDLE;
 import static android.support.v4.view.ViewPager.SCROLL_STATE_SETTLING;
 
-import android.annotation.TargetApi;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -29,7 +31,6 @@
 import android.database.DataSetObserver;
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.support.annotation.ColorInt;
@@ -66,7 +67,6 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -271,7 +271,7 @@
     private final ArrayList<OnTabSelectedListener> mSelectedListeners = new ArrayList<>();
     private OnTabSelectedListener mCurrentVpSelectedListener;
 
-    private ValueAnimatorCompat mScrollAnimator;
+    private ValueAnimator mScrollAnimator;
 
     ViewPager mViewPager;
     private PagerAdapter mPagerAdapter;
@@ -1085,13 +1085,13 @@
 
         if (startScrollX != targetScrollX) {
             if (mScrollAnimator == null) {
-                mScrollAnimator = ViewUtils.createAnimator();
+                mScrollAnimator = new ValueAnimator();
                 mScrollAnimator.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR);
                 mScrollAnimator.setDuration(ANIMATION_DURATION);
-                mScrollAnimator.addUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() {
+                mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                     @Override
-                    public void onAnimationUpdate(ValueAnimatorCompat animator) {
-                        scrollTo(animator.getAnimatedIntValue(), 0);
+                    public void onAnimationUpdate(ValueAnimator animator) {
+                        scrollTo((int) animator.getAnimatedValue(), 0);
                     }
                 });
             }
@@ -1486,7 +1486,7 @@
         }
     }
 
-    class TabView extends LinearLayout implements OnLongClickListener {
+    class TabView extends LinearLayout {
         private Tab mTab;
         private TextView mTextView;
         private ImageView mIconView;
@@ -1551,7 +1551,6 @@
             }
         }
 
-        @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
         @Override
         public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
             super.onInitializeAccessibilityEvent(event);
@@ -1559,7 +1558,6 @@
             event.setClassName(ActionBar.Tab.class.getName());
         }
 
-        @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
         @Override
         public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
             super.onInitializeAccessibilityNodeInfo(info);
@@ -1754,44 +1752,7 @@
                     iconView.requestLayout();
                 }
             }
-
-            if (!hasText && !TextUtils.isEmpty(contentDesc)) {
-                setOnLongClickListener(this);
-            } else {
-                setOnLongClickListener(null);
-                setLongClickable(false);
-            }
-        }
-
-        @Override
-        public boolean onLongClick(final View v) {
-            final int[] screenPos = new int[2];
-            final Rect displayFrame = new Rect();
-            getLocationOnScreen(screenPos);
-            getWindowVisibleDisplayFrame(displayFrame);
-
-            final Context context = getContext();
-            final int width = getWidth();
-            final int height = getHeight();
-            final int midy = screenPos[1] + height / 2;
-            int referenceX = screenPos[0] + width / 2;
-            if (ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_LTR) {
-                final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
-                referenceX = screenWidth - referenceX; // mirror
-            }
-
-            Toast cheatSheet = Toast.makeText(context, mTab.getContentDescription(),
-                    Toast.LENGTH_SHORT);
-            if (midy < displayFrame.height()) {
-                // Show below the tab view
-                cheatSheet.setGravity(Gravity.TOP | GravityCompat.END, referenceX,
-                        screenPos[1] + height - displayFrame.top);
-            } else {
-                // Show along the bottom center
-                cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
-            }
-            cheatSheet.show();
-            return true;
+            ViewCompat.setTooltipText(this, hasText ? null : contentDesc);
         }
 
         public Tab getTab() {
@@ -1816,7 +1777,7 @@
         private int mIndicatorLeft = -1;
         private int mIndicatorRight = -1;
 
-        private ValueAnimatorCompat mIndicatorAnimator;
+        private ValueAnimator mIndicatorAnimator;
 
         SlidingTabStrip(Context context) {
             super(context);
@@ -2013,22 +1974,22 @@
             }
 
             if (startLeft != targetLeft || startRight != targetRight) {
-                ValueAnimatorCompat animator = mIndicatorAnimator = ViewUtils.createAnimator();
+                ValueAnimator animator = mIndicatorAnimator = new ValueAnimator();
                 animator.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR);
                 animator.setDuration(duration);
                 animator.setFloatValues(0, 1);
-                animator.addUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() {
+                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                     @Override
-                    public void onAnimationUpdate(ValueAnimatorCompat animator) {
+                    public void onAnimationUpdate(ValueAnimator animator) {
                         final float fraction = animator.getAnimatedFraction();
                         setIndicatorPosition(
                                 AnimationUtils.lerp(startLeft, targetLeft, fraction),
                                 AnimationUtils.lerp(startRight, targetRight, fraction));
                     }
                 });
-                animator.addListener(new ValueAnimatorCompat.AnimatorListenerAdapter() {
+                animator.addListener(new AnimatorListenerAdapter() {
                     @Override
-                    public void onAnimationEnd(ValueAnimatorCompat animator) {
+                    public void onAnimationEnd(Animator animator) {
                         mSelectedPosition = position;
                         mSelectionOffset = 0f;
                     }
diff --git a/design/src/android/support/design/widget/TextInputLayout.java b/design/src/android/support/design/widget/TextInputLayout.java
index 10da563..83e517d 100644
--- a/design/src/android/support/design/widget/TextInputLayout.java
+++ b/design/src/android/support/design/widget/TextInputLayout.java
@@ -16,6 +16,9 @@
 
 package android.support.design.widget;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.Canvas;
@@ -45,7 +48,6 @@
 import android.support.v4.view.AccessibilityDelegateCompat;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewCompat;
-import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
 import android.support.v4.widget.Space;
 import android.support.v4.widget.TextViewCompat;
@@ -168,7 +170,7 @@
     final CollapsingTextHelper mCollapsingTextHelper = new CollapsingTextHelper(this);
 
     private boolean mHintAnimationEnabled;
-    private ValueAnimatorCompat mAnimator;
+    private ValueAnimator mAnimator;
 
     private boolean mHasReconstructedEditTextBackground;
     private boolean mInDrawableStateChanged;
@@ -595,7 +597,7 @@
     public void setErrorEnabled(boolean enabled) {
         if (mErrorEnabled != enabled) {
             if (mErrorView != null) {
-                ViewCompat.animate(mErrorView).cancel();
+                mErrorView.animate().cancel();
             }
 
             if (enabled) {
@@ -698,43 +700,43 @@
         mErrorShown = !TextUtils.isEmpty(error);
 
         // Cancel any on-going animation
-        ViewCompat.animate(mErrorView).cancel();
+        mErrorView.animate().cancel();
 
         if (mErrorShown) {
             mErrorView.setText(error);
             mErrorView.setVisibility(VISIBLE);
 
             if (animate) {
-                if (ViewCompat.getAlpha(mErrorView) == 1f) {
+                if (mErrorView.getAlpha() == 1f) {
                     // If it's currently 100% show, we'll animate it from 0
-                    ViewCompat.setAlpha(mErrorView, 0f);
+                    mErrorView.setAlpha(0f);
                 }
-                ViewCompat.animate(mErrorView)
+                mErrorView.animate()
                         .alpha(1f)
                         .setDuration(ANIMATION_DURATION)
                         .setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR)
-                        .setListener(new ViewPropertyAnimatorListenerAdapter() {
+                        .setListener(new AnimatorListenerAdapter() {
                             @Override
-                            public void onAnimationStart(View view) {
-                                view.setVisibility(VISIBLE);
+                            public void onAnimationStart(Animator animator) {
+                                mErrorView.setVisibility(VISIBLE);
                             }
                         }).start();
             } else {
                 // Set alpha to 1f, just in case
-                ViewCompat.setAlpha(mErrorView, 1f);
+                mErrorView.setAlpha(1f);
             }
         } else {
             if (mErrorView.getVisibility() == VISIBLE) {
                 if (animate) {
-                    ViewCompat.animate(mErrorView)
+                    mErrorView.animate()
                             .alpha(0f)
                             .setDuration(ANIMATION_DURATION)
                             .setInterpolator(AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR)
-                            .setListener(new ViewPropertyAnimatorListenerAdapter() {
+                            .setListener(new AnimatorListenerAdapter() {
                                 @Override
-                                public void onAnimationEnd(View view) {
+                                public void onAnimationEnd(Animator animator) {
                                     mErrorView.setText(error);
-                                    view.setVisibility(INVISIBLE);
+                                    mErrorView.setVisibility(INVISIBLE);
                                 }
                             }).start();
                 } else {
@@ -1420,13 +1422,13 @@
             return;
         }
         if (mAnimator == null) {
-            mAnimator = ViewUtils.createAnimator();
+            mAnimator = new ValueAnimator();
             mAnimator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
             mAnimator.setDuration(ANIMATION_DURATION);
-            mAnimator.addUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() {
+            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                 @Override
-                public void onAnimationUpdate(ValueAnimatorCompat animator) {
-                    mCollapsingTextHelper.setExpansionFraction(animator.getAnimatedFloatValue());
+                public void onAnimationUpdate(ValueAnimator animator) {
+                    mCollapsingTextHelper.setExpansionFraction((float) animator.getAnimatedValue());
                 }
             });
         }
diff --git a/design/src/android/support/design/widget/ViewGroupUtils.java b/design/src/android/support/design/widget/ViewGroupUtils.java
index bb5e1b6..0545516 100644
--- a/design/src/android/support/design/widget/ViewGroupUtils.java
+++ b/design/src/android/support/design/widget/ViewGroupUtils.java
@@ -16,51 +16,16 @@
 
 package android.support.design.widget;
 
+import android.graphics.Matrix;
 import android.graphics.Rect;
-import android.os.Build;
+import android.graphics.RectF;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 
 class ViewGroupUtils {
-
-    private interface ViewGroupUtilsImpl {
-        void offsetDescendantRect(ViewGroup parent, View child, Rect rect);
-    }
-
-    private static class ViewGroupUtilsImplBase implements ViewGroupUtilsImpl {
-        ViewGroupUtilsImplBase() {
-        }
-
-        @Override
-        public void offsetDescendantRect(ViewGroup parent, View child, Rect rect) {
-            parent.offsetDescendantRectToMyCoords(child, rect);
-            // View#offsetDescendantRectToMyCoords includes scroll offsets of the last child.
-            // We need to reverse it here so that we get the rect of the view itself rather
-            // than its content.
-            rect.offset(child.getScrollX(), child.getScrollY());
-        }
-    }
-
-    private static class ViewGroupUtilsImplHoneycomb implements ViewGroupUtilsImpl {
-        ViewGroupUtilsImplHoneycomb() {
-        }
-
-        @Override
-        public void offsetDescendantRect(ViewGroup parent, View child, Rect rect) {
-            ViewGroupUtilsHoneycomb.offsetDescendantRect(parent, child, rect);
-        }
-    }
-
-    private static final ViewGroupUtilsImpl IMPL;
-
-    static {
-        final int version = Build.VERSION.SDK_INT;
-        if (version >= 11) {
-            IMPL = new ViewGroupUtilsImplHoneycomb();
-        } else {
-            IMPL = new ViewGroupUtilsImplBase();
-        }
-    }
+    private static final ThreadLocal<Matrix> sMatrix = new ThreadLocal<>();
+    private static final ThreadLocal<RectF> sRectF = new ThreadLocal<>();
 
     /**
      * This is a port of the common
@@ -72,7 +37,25 @@
      * @param rect (in/out) the rect to offset from descendant to this view's coordinate system
      */
     static void offsetDescendantRect(ViewGroup parent, View descendant, Rect rect) {
-        IMPL.offsetDescendantRect(parent, descendant, rect);
+        Matrix m = sMatrix.get();
+        if (m == null) {
+            m = new Matrix();
+            sMatrix.set(m);
+        } else {
+            m.reset();
+        }
+
+        offsetDescendantMatrix(parent, descendant, m);
+
+        RectF rectF = sRectF.get();
+        if (rectF == null) {
+            rectF = new RectF();
+            sRectF.set(rectF);
+        }
+        rectF.set(rect);
+        m.mapRect(rectF);
+        rect.set((int) (rectF.left + 0.5f), (int) (rectF.top + 0.5f),
+                (int) (rectF.right + 0.5f), (int) (rectF.bottom + 0.5f));
     }
 
     /**
@@ -87,4 +70,18 @@
         offsetDescendantRect(parent, descendant, out);
     }
 
+    private static void offsetDescendantMatrix(ViewParent target, View view, Matrix m) {
+        final ViewParent parent = view.getParent();
+        if (parent instanceof View && parent != target) {
+            final View vp = (View) parent;
+            offsetDescendantMatrix(target, vp, m);
+            m.preTranslate(-vp.getScrollX(), -vp.getScrollY());
+        }
+
+        m.preTranslate(view.getLeft(), view.getTop());
+
+        if (!view.getMatrix().isIdentity()) {
+            m.preConcat(view.getMatrix());
+        }
+    }
 }
diff --git a/design/src/android/support/design/widget/ViewUtils.java b/design/src/android/support/design/widget/ViewUtils.java
index f49d836..1762b09 100644
--- a/design/src/android/support/design/widget/ViewUtils.java
+++ b/design/src/android/support/design/widget/ViewUtils.java
@@ -17,24 +17,8 @@
 package android.support.design.widget;
 
 import android.graphics.PorterDuff;
-import android.os.Build;
 
 class ViewUtils {
-
-    static final ValueAnimatorCompat.Creator DEFAULT_ANIMATOR_CREATOR
-            = new ValueAnimatorCompat.Creator() {
-        @Override
-        public ValueAnimatorCompat createAnimator() {
-            return new ValueAnimatorCompat(Build.VERSION.SDK_INT >= 12
-                    ? new ValueAnimatorCompatImplHoneycombMr1()
-                    : new ValueAnimatorCompatImplGingerbread());
-        }
-    };
-
-    static ValueAnimatorCompat createAnimator() {
-        return DEFAULT_ANIMATOR_CREATOR.createAnimator();
-    }
-
     static boolean objectEquals(Object a, Object b) {
         return (a == b) || (a != null && a.equals(b));
     }
diff --git a/design/tests/AndroidManifest.xml b/design/tests/AndroidManifest.xml
index 886540d..b021d92 100755
--- a/design/tests/AndroidManifest.xml
+++ b/design/tests/AndroidManifest.xml
@@ -19,7 +19,7 @@
           package="android.support.design.test">
 
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                       android.support.test.espresso, android.support.test.espresso.idling"/>
diff --git a/design/tests/src/android/support/design/custom/TestFloatingBehavior.java b/design/tests/src/android/support/design/custom/TestFloatingBehavior.java
index a508736..8e00fa6 100644
--- a/design/tests/src/android/support/design/custom/TestFloatingBehavior.java
+++ b/design/tests/src/android/support/design/custom/TestFloatingBehavior.java
@@ -18,7 +18,6 @@
 import android.content.Context;
 import android.support.design.widget.CoordinatorLayout;
 import android.support.design.widget.Snackbar;
-import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.TextView;
@@ -42,8 +41,8 @@
     @Override
     public boolean onDependentViewChanged(CoordinatorLayout parent, TextView child,
             View dependency) {
-        ViewCompat.setTranslationY(child, Math.min(0,
-                ViewCompat.getTranslationY(dependency) - dependency.getHeight()));
+        child.setTranslationY(Math.min(0,
+                dependency.getTranslationY() - dependency.getHeight()));
         return true;
     }
 }
diff --git a/design/tests/src/android/support/design/testutils/ViewPagerActions.java b/design/tests/src/android/support/design/testutils/ViewPagerActions.java
index e7b4bf7..1a147cf 100644
--- a/design/tests/src/android/support/design/testutils/ViewPagerActions.java
+++ b/design/tests/src/android/support/design/testutils/ViewPagerActions.java
@@ -16,22 +16,17 @@
 
 package android.support.design.testutils;
 
+import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast;
+
 import android.support.annotation.Nullable;
 import android.support.test.espresso.UiController;
 import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.action.CoordinatesProvider;
-import android.support.test.espresso.action.GeneralClickAction;
-import android.support.test.espresso.action.Press;
-import android.support.test.espresso.action.Tap;
 import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.PagerTitleStrip;
 import android.support.v4.view.ViewPager;
 import android.view.View;
-import android.widget.TextView;
-import org.hamcrest.Matcher;
 
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast;
+import org.hamcrest.Matcher;
 
 public class ViewPagerActions {
     /**
@@ -203,31 +198,4 @@
             }
         };
     }
-
-    /**
-     * Moves <code>ViewPager</code> to specific page.
-     */
-    public static ViewAction notifyAdapterContentChange() {
-        return new ViewAction() {
-            @Override
-            public Matcher<View> getConstraints() {
-                return isAssignableFrom(ViewPager.class);
-            }
-
-            @Override
-            public String getDescription() {
-                return "ViewPager notify on adapter content change";
-            }
-
-            @Override
-            public void perform(UiController uiController, View view) {
-                uiController.loopMainThreadUntilIdle();
-
-                ViewPager viewPager = (ViewPager) view;
-                viewPager.getAdapter().notifyDataSetChanged();
-
-                uiController.loopMainThreadUntilIdle();
-            }
-        };
-    }
 }
diff --git a/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java b/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
index 5a536f6..cbf2fc9 100644
--- a/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
+++ b/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
@@ -38,17 +38,24 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import android.app.Activity;
 import android.content.res.Resources;
+import android.os.Build;
 import android.os.Parcelable;
 import android.support.annotation.ColorInt;
 import android.support.design.test.R;
 import android.support.design.testutils.TestDrawable;
 import android.support.design.testutils.TestUtilsMatchers;
 import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.LargeTest;
+import android.support.test.filters.SdkSuppress;
 import android.support.test.filters.SmallTest;
 import android.support.v4.content.res.ResourcesCompat;
 import android.view.Menu;
 import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.PointerIcon;
+import android.view.View;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -110,7 +117,7 @@
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testNavigationSelectionListener() {
         BottomNavigationView.OnNavigationItemSelectedListener mockedListener =
                 mock(BottomNavigationView.OnNavigationItemSelectedListener.class);
@@ -376,6 +383,27 @@
     @UiThreadTest
     @Test
     @SmallTest
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+    public void testPointerIcon() throws Throwable {
+        final Activity activity = mActivityTestRule.getActivity();
+        final PointerIcon expectedIcon = PointerIcon.getSystemIcon(activity, PointerIcon.TYPE_HAND);
+        final MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_MOVE, 0, 0, 0);
+        final Menu menu = mBottomNavigation.getMenu();
+        for (int i = 0; i < menu.size(); i++) {
+            final MenuItem item = menu.getItem(i);
+            assertTrue(item.isEnabled());
+            final View itemView = activity.findViewById(item.getItemId());
+            assertEquals(expectedIcon, itemView.onResolvePointerIcon(event, 0));
+            item.setEnabled(false);
+            assertEquals(null, itemView.onResolvePointerIcon(event, 0));
+            item.setEnabled(true);
+            assertEquals(expectedIcon, itemView.onResolvePointerIcon(event, 0));
+        }
+    }
+
+    @UiThreadTest
+    @Test
+    @SmallTest
     public void testClearingMenu() throws Throwable {
         mBottomNavigation.getMenu().clear();
         assertEquals(0, mBottomNavigation.getMenu().size());
diff --git a/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java b/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java
index 3a4ae2a..2faf8a0 100644
--- a/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java
+++ b/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java
@@ -23,6 +23,7 @@
 import static org.hamcrest.Matchers.lessThanOrEqualTo;
 import static org.junit.Assert.fail;
 
+import android.content.Context;
 import android.os.SystemClock;
 import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
@@ -723,6 +724,37 @@
         }
     }
 
+    @Test
+    @MediumTest
+    public void testExpandedPeekHeight() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Make the peek height as tall as the bottom sheet.
+                BottomSheetBehavior behavior = getBehavior();
+                behavior.setPeekHeight(getBottomSheet().getHeight());
+                assertThat(behavior.getState(), is(BottomSheetBehavior.STATE_COLLAPSED));
+            }
+        });
+        // Both of these will not animate the sheet , but the state should be changed.
+        checkSetState(BottomSheetBehavior.STATE_EXPANDED, ViewMatchers.isDisplayed());
+        checkSetState(BottomSheetBehavior.STATE_COLLAPSED, ViewMatchers.isDisplayed());
+    }
+
+    @Test
+    @SmallTest
+    public void testFindScrollingChildEnabled() {
+        Context context = mActivityTestRule.getActivity();
+        NestedScrollView disabledParent = new NestedScrollView(context);
+        disabledParent.setNestedScrollingEnabled(false);
+        NestedScrollView enabledChild = new NestedScrollView(context);
+        enabledChild.setNestedScrollingEnabled(true);
+        disabledParent.addView(enabledChild);
+
+        View scrollingChild = getBehavior().findScrollingChild(disabledParent);
+        assertThat(scrollingChild, is((View) enabledChild));
+    }
+
     private void checkSetState(final int state, Matcher<View> matcher) throws Throwable {
         registerIdlingResourceCallback();
         try {
diff --git a/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java b/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java
index 4c6bbbf..940eb5a 100644
--- a/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java
+++ b/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java
@@ -20,8 +20,11 @@
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.lessThan;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.timeout;
@@ -91,6 +94,59 @@
 
     @Test
     @MediumTest
+    public void testTouchInside() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                showDialog();
+                // Confirms that the dialog is shown
+                assertThat(mDialog.isShowing(), is(true));
+                FrameLayout bottomSheet = (FrameLayout) mDialog
+                        .findViewById(R.id.design_bottom_sheet);
+                // The bottom sheet is not clickable
+                assertNotNull(bottomSheet);
+                assertThat(bottomSheet.isClickable(), is(false));
+            }
+        });
+        // Click on the bottom sheet
+        Espresso.onView(ViewMatchers.withId(R.id.design_bottom_sheet))
+                .perform(ViewActions.click());
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Confirm that touch didn't fall through as outside touch
+                assertThat(mDialog.isShowing(), is(true));
+            }
+        });
+    }
+
+    @Test
+    @MediumTest
+    public void testClickContent() throws Throwable {
+        final View.OnClickListener mockListener = mock(View.OnClickListener.class);
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                showDialog();
+                // Confirms that the dialog is shown
+                assertThat(mDialog.isShowing(), is(true));
+                FrameLayout bottomSheet = (FrameLayout) mDialog
+                        .findViewById(R.id.design_bottom_sheet);
+                // Set up an OnClickListener to the content of the bottom sheet
+                assertNotNull(bottomSheet);
+                View child = bottomSheet.getChildAt(0);
+                child.setOnClickListener(mockListener);
+            }
+        });
+        // Click on the bottom sheet; since the whole sheet is occupied with its only child, this
+        // clicks the child
+        Espresso.onView(ViewMatchers.withParent(ViewMatchers.withId(R.id.design_bottom_sheet)))
+                .perform(ViewActions.click());
+        verify(mockListener, times(1)).onClick(any(View.class));
+    }
+
+    @Test
+    @MediumTest
     public void testShortDialog() throws Throwable {
         mActivityTestRule.runOnUiThread(new Runnable() {
             @Override
diff --git a/design/tests/src/android/support/design/widget/CoordinatorSnackbarWithFabTest.java b/design/tests/src/android/support/design/widget/CoordinatorSnackbarWithFabTest.java
index 2cdc990..30f04ce 100644
--- a/design/tests/src/android/support/design/widget/CoordinatorSnackbarWithFabTest.java
+++ b/design/tests/src/android/support/design/widget/CoordinatorSnackbarWithFabTest.java
@@ -32,6 +32,7 @@
 import android.support.test.espresso.UiController;
 import android.support.test.espresso.ViewAction;
 import android.support.test.filters.MediumTest;
+import android.support.test.filters.SdkSuppress;
 import android.support.v7.widget.AppCompatTextView;
 import android.view.View;
 import android.view.ViewGroup;
@@ -99,6 +100,8 @@
         }
     }
 
+    // Test is flaky on API 19
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
     @Test
     public void testBuiltInSliding() {
         onView(withId(R.id.coordinator_stub)).perform(
diff --git a/design/tests/src/android/support/design/widget/CustomSnackbarTest.java b/design/tests/src/android/support/design/widget/CustomSnackbarTest.java
index cec87da..4fc2525 100644
--- a/design/tests/src/android/support/design/widget/CustomSnackbarTest.java
+++ b/design/tests/src/android/support/design/widget/CustomSnackbarTest.java
@@ -40,8 +40,8 @@
 import android.support.design.testutils.SnackbarUtils;
 import android.support.test.espresso.ViewAction;
 import android.support.test.espresso.ViewInteraction;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
-import android.support.test.filters.SmallTest;
 import android.support.v4.view.ViewCompat;
 import android.view.LayoutInflater;
 
@@ -98,15 +98,15 @@
                 new BaseTransientBottomBar.ContentViewCallback() {
                     @Override
                     public void animateContentIn(int delay, int duration) {
-                        ViewCompat.setAlpha(content, 0f);
-                        ViewCompat.animate(content).alpha(1f).setDuration(duration)
+                        content.setAlpha(0f);
+                        content.animate().alpha(1f).setDuration(duration)
                                 .setStartDelay(delay).start();
                     }
 
                     @Override
                     public void animateContentOut(int delay, int duration) {
-                        ViewCompat.setAlpha(content, 1f);
-                        ViewCompat.animate(content).alpha(0f).setDuration(duration)
+                        content.setAlpha(1f);
+                        content.animate().alpha(0f).setDuration(duration)
                                 .setStartDelay(delay).start();
                     }
                 };
@@ -114,7 +114,7 @@
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testBasicContent() throws Throwable {
         // Verify different combinations of snackbar content (title / subtitle and action)
         // and duration
diff --git a/design/tests/src/android/support/design/widget/FloatingActionButtonTest.java b/design/tests/src/android/support/design/widget/FloatingActionButtonTest.java
index e8cc701..1037235 100644
--- a/design/tests/src/android/support/design/widget/FloatingActionButtonTest.java
+++ b/design/tests/src/android/support/design/widget/FloatingActionButtonTest.java
@@ -53,6 +53,8 @@
 import android.support.test.espresso.action.GeneralSwipeAction;
 import android.support.test.espresso.action.Press;
 import android.support.test.espresso.action.Swipe;
+import android.support.test.filters.LargeTest;
+import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.v4.content.ContextCompat;
 import android.view.Gravity;
@@ -60,7 +62,6 @@
 
 import org.junit.Test;
 
-@SmallTest
 public class FloatingActionButtonTest
         extends BaseInstrumentationTestCase<FloatingActionButtonActivity> {
 
@@ -68,6 +69,7 @@
         super(FloatingActionButtonActivity.class);
     }
 
+    @SmallTest
     @Test
     public void testDefaultBackgroundTint() {
         final int colorAccent = TestUtils.getThemeAttrColor(
@@ -76,6 +78,7 @@
                 .check(matches(withFabBackgroundFill(colorAccent)));
     }
 
+    @SmallTest
     @Test
     public void testSetTintOnDefaultBackgroundTint() {
         onView(withId(R.id.fab_standard))
@@ -83,12 +86,14 @@
                 .check(matches(withFabBackgroundFill(Color.GREEN)));
     }
 
+    @SmallTest
     @Test
     public void testDeclaredBackgroundTint() {
         onView(withId(R.id.fab_tint))
                 .check(matches(withFabBackgroundFill(Color.MAGENTA)));
     }
 
+    @SmallTest
     @Test
     public void testSetTintOnDeclaredBackgroundTint() {
         onView(withId(R.id.fab_tint))
@@ -96,6 +101,7 @@
                 .check(matches(withFabBackgroundFill(Color.GREEN)));
     }
 
+    @SmallTest
     @Test
     public void testSetStatefulTintAcrossStateChanges() {
         final Activity activity = mActivityTestRule.getActivity();
@@ -118,6 +124,7 @@
                 .check(matches(withFabBackgroundFill(normal)));
     }
 
+    @SmallTest
     @Test
     public void testDeclaredStatefulTintAcrossStateChanges() {
         final Activity activity = mActivityTestRule.getActivity();
@@ -132,12 +139,14 @@
                 .check(matches(withFabBackgroundFill(disabled)));
     }
 
+    @SmallTest
     @Test
     public void setVectorDrawableSrc() {
         onView(withId(R.id.fab_standard))
                 .perform(setImageResource(R.drawable.vector_icon));
     }
 
+    @SmallTest
     @Test
     public void testSetMiniSize() {
         final int miniSize = mActivityTestRule.getActivity().getResources()
@@ -148,6 +157,7 @@
                 .check(matches(withFabContentHeight(miniSize)));
     }
 
+    @SmallTest
     @Test
     public void testSetSizeToggle() {
         final int miniSize = mActivityTestRule.getActivity().getResources()
@@ -164,6 +174,7 @@
                 .check(matches(withFabContentHeight(normalSize)));
     }
 
+    @SmallTest
     @Test
     public void testOffset() {
         onView(withId(R.id.fab_standard))
@@ -175,6 +186,7 @@
                 .check(matches(withFabContentAreaOnMargins(Gravity.RIGHT | Gravity.BOTTOM)));
     }
 
+    @SmallTest
     @Test
     public void testHideShow() {
         onView(withId(R.id.fab_standard))
@@ -183,6 +195,7 @@
                 .check(matches(isDisplayed()));
     }
 
+    @MediumTest
     @Test
     public void testShowHide() {
         onView(withId(R.id.fab_standard))
@@ -191,6 +204,7 @@
                 .check(matches(not(isDisplayed())));
     }
 
+    @LargeTest
     @Test
     public void testClickableTouchAndDragOffView() {
         onView(withId(R.id.fab_standard))
@@ -232,6 +246,7 @@
                 .check(matches(not(isPressed())));
     }
 
+    @MediumTest
     @Test
     public void testOnClickListener() {
         final View.OnClickListener listener = mock(View.OnClickListener.class);
@@ -245,6 +260,7 @@
         verify(listener, times(1)).onClick(view);
     }
 
+    @SmallTest
     @Test
     public void testSetCompatElevation() {
         onView(withId(R.id.fab_standard))
diff --git a/design/tests/src/android/support/design/widget/SnackbarTestWithFAB.java b/design/tests/src/android/support/design/widget/SnackbarTestWithFAB.java
index 7d90a2b..5ffe3ca 100644
--- a/design/tests/src/android/support/design/widget/SnackbarTestWithFAB.java
+++ b/design/tests/src/android/support/design/widget/SnackbarTestWithFAB.java
@@ -20,13 +20,13 @@
 
 import android.support.design.test.R;
 import android.support.design.testutils.SnackbarUtils;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.view.View;
 
 import org.junit.Before;
 import org.junit.Test;
 
-@MediumTest
+@LargeTest
 public class SnackbarTestWithFAB extends BaseInstrumentationTestCase<SnackbarActivityWithFAB> {
 
     private static final String MESSAGE_TEXT = "Test Message";
diff --git a/design/tests/src/android/support/design/widget/TabLayoutTest.java b/design/tests/src/android/support/design/widget/TabLayoutTest.java
index 539ab86..cb4e669 100755
--- a/design/tests/src/android/support/design/widget/TabLayoutTest.java
+++ b/design/tests/src/android/support/design/widget/TabLayoutTest.java
@@ -27,12 +27,16 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
+import android.os.Build;
 import android.support.design.test.R;
 import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SdkSuppress;
 import android.support.test.filters.SmallTest;
 import android.support.v7.app.AppCompatActivity;
 import android.view.InflateException;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.PointerIcon;
 import android.view.View;
 
 import org.junit.Test;
@@ -179,6 +183,24 @@
         assertTabCustomViewSelected(tabs);
     }
 
+    @Test
+    @UiThreadTest
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+    public void testPointerIcon() {
+        final LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
+        final TabLayout tabLayout = (TabLayout) inflater.inflate(R.layout.design_tabs_items, null);
+        final PointerIcon expectedIcon =
+                PointerIcon.getSystemIcon(mActivityTestRule.getActivity(), PointerIcon.TYPE_HAND);
+
+        final int tabCount = tabLayout.getTabCount();
+        assertEquals(3, tabCount);
+
+        final MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_MOVE, 0, 0, 0);
+        for (int i = 0; i < tabCount; i++) {
+            assertEquals(expectedIcon, tabLayout.getTabAt(i).mView.onResolvePointerIcon(event, 0));
+        }
+    }
+
     private static void assertTabCustomViewSelected(final TabLayout tabLayout) {
         for (int i = 0, count = tabLayout.getTabCount(); i < count; i++) {
             final TabLayout.Tab tab = tabLayout.getTabAt(i);
diff --git a/design/tests/src/android/support/design/widget/TabLayoutWithViewPagerTest.java b/design/tests/src/android/support/design/widget/TabLayoutWithViewPagerTest.java
index 00810d5..c01b785 100755
--- a/design/tests/src/android/support/design/widget/TabLayoutWithViewPagerTest.java
+++ b/design/tests/src/android/support/design/widget/TabLayoutWithViewPagerTest.java
@@ -16,7 +16,6 @@
 package android.support.design.widget;
 
 import static android.support.design.testutils.TabLayoutActions.setupWithViewPager;
-import static android.support.design.testutils.ViewPagerActions.notifyAdapterContentChange;
 import static android.support.design.testutils.ViewPagerActions.setAdapter;
 import static android.support.test.espresso.Espresso.onView;
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
@@ -42,6 +41,8 @@
 import android.support.design.testutils.TestUtilsActions;
 import android.support.design.testutils.TestUtilsMatchers;
 import android.support.design.testutils.ViewPagerActions;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
@@ -176,6 +177,63 @@
         }
     }
 
+    private static <Q> ViewAction addItemToPager(final String title, final Q content) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(ViewPager.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Add item and notify on content change";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                final ViewPager viewPager = (ViewPager) view;
+                final BasePagerAdapter<Q> viewPagerAdapter =
+                        (BasePagerAdapter<Q>) viewPager.getAdapter();
+                viewPagerAdapter.add(title, content);
+                viewPagerAdapter.notifyDataSetChanged();
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
+    private static <Q> ViewAction addItemsToPager(final String[] title, final Q[] content) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(ViewPager.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Add items and notify on content change";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                final ViewPager viewPager = (ViewPager) view;
+                final BasePagerAdapter<Q> viewPagerAdapter =
+                        (BasePagerAdapter<Q>) viewPager.getAdapter();
+                int itemCount = title.length;
+                for (int i = 0; i < itemCount; i++) {
+                    viewPagerAdapter.add(title[i], content[i]);
+                }
+                viewPagerAdapter.notifyDataSetChanged();
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
     public TabLayoutWithViewPagerTest() {
         super(TabLayoutWithViewPagerActivity.class);
     }
@@ -307,15 +365,15 @@
         assertEquals("Initial adapter page count", 3, initialAdapter.getCount());
 
         // Add two more entries to our adapter
-        mDefaultPagerAdapter.add("Yellow", Color.YELLOW);
-        mDefaultPagerAdapter.add("Magenta", Color.MAGENTA);
-        final int newItemCount = mDefaultPagerAdapter.getCount();
-        onView(withId(R.id.tabs_viewpager)).perform(notifyAdapterContentChange());
+        onView(withId(R.id.tabs_viewpager)).perform(
+                addItemsToPager(new String[] { "Yellow", "Magenta"},
+                        new Integer[] { Color.YELLOW, Color.MAGENTA }));
 
         // We have more comprehensive test coverage for changing the ViewPager adapter in v4/tests.
         // Here we are focused on testing the continuous integration of TabLayout with the new
         // content of ViewPager
 
+        final int newItemCount = mDefaultPagerAdapter.getCount();
         assertEquals("Matching item count", newItemCount, mTabLayout.getTabCount());
 
         for (int i = 0; i < newItemCount; i++) {
@@ -337,15 +395,13 @@
         assertEquals("Initial adapter class", ColorPagerAdapter.class, initialAdapter.getClass());
         assertEquals("Initial adapter page count", 3, initialAdapter.getCount());
 
-        // Add two more entries to our adapter
-        mDefaultPagerAdapter.add("Yellow", Color.YELLOW);
-        mDefaultPagerAdapter.add("Magenta", Color.MAGENTA);
-        final int newItemCount = mDefaultPagerAdapter.getCount();
-
-        // Notify the adapter that it has changed
-        onView(withId(R.id.tabs_viewpager)).perform(notifyAdapterContentChange());
+        // Add two entries to our adapter
+        onView(withId(R.id.tabs_viewpager)).perform(
+                addItemsToPager(new String[] { "Yellow", "Magenta"},
+                        new Integer[] { Color.YELLOW, Color.MAGENTA }));
 
         // Assert that the TabLayout did not update and add the new items
+        final int newItemCount = mDefaultPagerAdapter.getCount();
         assertNotEquals("Matching item count", newItemCount, mTabLayout.getTabCount());
     }
 
@@ -428,9 +484,7 @@
 
         // Add a bunch of tabs and verify that all of them are visible on the screen
         for (int i = 0; i < 8; i++) {
-            newAdapter.add("Title " + i, "Body " + i);
-            onView(withId(R.id.tabs_viewpager)).perform(
-                    notifyAdapterContentChange());
+            onView(withId(R.id.tabs_viewpager)).perform(addItemToPager("Title " + i, "Body " + i));
 
             int expectedTabCount = i + 1;
             assertEquals("Tab count after adding #" + i, expectedTabCount,
@@ -499,9 +553,7 @@
                 tabTitleBuilder.append(titleComponent);
             }
             final String tabTitle = tabTitleBuilder.toString();
-            newAdapter.add(tabTitle, "Body " + i);
-            onView(withId(R.id.tabs_viewpager)).perform(
-                    notifyAdapterContentChange());
+            onView(withId(R.id.tabs_viewpager)).perform(addItemToPager(tabTitle, "Body " + i));
 
             int expectedTabCount = i + 1;
             // Check that all tabs are at least as wide as min width *and* at most as wide as max
diff --git a/development/checkstyle/.gitignore b/development/checkstyle/.gitignore
new file mode 100644
index 0000000..d163863
--- /dev/null
+++ b/development/checkstyle/.gitignore
@@ -0,0 +1 @@
+build/
\ No newline at end of file
diff --git a/development/checkstyle/LICENSE b/development/checkstyle/LICENSE
new file mode 100644
index 0000000..c1f5472
--- /dev/null
+++ b/development/checkstyle/LICENSE
@@ -0,0 +1,502 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/development/checkstyle/README b/development/checkstyle/README
new file mode 100644
index 0000000..8f9bf38
--- /dev/null
+++ b/development/checkstyle/README
@@ -0,0 +1,16 @@
+Description:
+Checkstyle is used by developers to validate Java code style before running
+repo upload. This project implements Checkstyle checks specific to the Android
+support library.
+
+Projects used:
+* Name: Checkstyle
+  Description: Checkstyle is a development tool to help programmers write Java
+               code that adheres to a coding standard.
+  URL: http://checkstyle.sourceforge.net/
+  Version: 6.12.1
+  License: LGPL 2.1
+  License File: LICENSE
+  Local Modifications:
+  - The only source file used here is MissingDeprecatedCheck, which was adapted
+    to create MissingRestrictToCheck.
diff --git a/development/checkstyle/build.gradle b/development/checkstyle/build.gradle
new file mode 100644
index 0000000..636fef3
--- /dev/null
+++ b/development/checkstyle/build.gradle
@@ -0,0 +1,22 @@
+apply plugin: 'java'
+sourceCompatibility = JavaVersion.VERSION_1_7
+targetCompatibility = JavaVersion.VERSION_1_7
+
+dependencies {
+    compile files(
+            '../../../../prebuilts/checkstyle/checkstyle.jar',
+            '../../../../prebuilts/sdk/current/support/annotations/android-support-annotations.jar')
+}
+
+sourceSets {
+    main.java.srcDir 'src'
+}
+
+sourceCompatibility = JavaVersion.VERSION_1_7
+targetCompatibility = JavaVersion.VERSION_1_7
+
+jar {
+    from sourceSets.main.output
+    baseName = "com.android.support.checkstyle"
+    destinationDir = new File("prebuilt")
+}
diff --git a/development/checkstyle/config/support-lib.xml b/development/checkstyle/config/support-lib.xml
new file mode 100644
index 0000000..eb5849b
--- /dev/null
+++ b/development/checkstyle/config/support-lib.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (C) 2016 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.
+-->
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd" [
+    <!ENTITY defaultCopyrightCheck SYSTEM "../../../../../prebuilts/checkstyle/default-copyright-check.xml">
+    <!ENTITY defaultJavadocChecks SYSTEM "../../../../../prebuilts/checkstyle/default-javadoc-checks.xml">
+    <!ENTITY defaultTreewalkerChecks SYSTEM "../../../../../prebuilts/checkstyle/default-treewalker-checks.xml">
+    <!ENTITY defaultModuleChecks SYSTEM "../../../../../prebuilts/checkstyle/default-module-checks.xml">
+    ]>
+
+<module name="Checker">
+    &defaultModuleChecks;
+    &defaultCopyrightCheck;
+    <module name="TreeWalker">
+        &defaultJavadocChecks;
+        &defaultTreewalkerChecks;
+
+        <!-- Custom support library check for @RestrictTo / @hide. -->
+        <module name="com.android.support.checkstyle.MismatchedAnnotationCheck">
+            <property name="severity" value="error" />
+            <property name="tag" value="hide" />
+            <property name="annotation" value="android.support.annotation.RestrictTo" />
+            <property name="messageKey" value="annotation.missing.hide" />
+            <message key="annotation.missing.hide" value="Must include both @RestrictTo annotation and @hide Javadoc tag."/>
+        </module>
+    </module>
+</module>
diff --git a/development/checkstyle/gradle/wrapper/gradle-wrapper.jar b/development/checkstyle/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
--- /dev/null
+++ b/development/checkstyle/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/development/checkstyle/gradle/wrapper/gradle-wrapper.properties b/development/checkstyle/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..dfb0681
--- /dev/null
+++ b/development/checkstyle/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Aug 16 10:43:36 PDT 2016
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=../../../../../../tools/external/gradle/gradle-3.2-bin.zip
diff --git a/development/checkstyle/gradlew b/development/checkstyle/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/development/checkstyle/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/development/checkstyle/prebuilt/com.android.support.checkstyle.jar b/development/checkstyle/prebuilt/com.android.support.checkstyle.jar
new file mode 100644
index 0000000..f1b5d4b
--- /dev/null
+++ b/development/checkstyle/prebuilt/com.android.support.checkstyle.jar
Binary files differ
diff --git a/development/checkstyle/src/com/android/support/checkstyle/MismatchedAnnotationCheck.java b/development/checkstyle/src/com/android/support/checkstyle/MismatchedAnnotationCheck.java
new file mode 100644
index 0000000..a1a60df
--- /dev/null
+++ b/development/checkstyle/src/com/android/support/checkstyle/MismatchedAnnotationCheck.java
@@ -0,0 +1,184 @@
+/*
+ * checkstyle: Checks Java source code for adherence to a set of rules.
+ * Copyright (C) 2001-2016 the original author or authors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package com.android.support.checkstyle;
+
+import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TextBlock;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import com.puppycrawl.tools.checkstyle.utils.AnnotationUtility;
+import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
+
+import java.util.regex.Pattern;
+
+/**
+ * This class is used to verify that both an annotation and javadoc tag are
+ * present when either one is present.
+ * <p>
+ * Typically, both ways of flagging APIs serve their own purposes. Annotations
+ * are used for compilers and development tools, while javadoc tags are used
+ * for documentation.
+ * <p>
+ * In some cases, the presence of an annotations implies the presence of a
+ * javadoc tag (or vice versa). For example, in the case of the
+ * {@literal @}Deprecated annotation, the {@literal @}deprecated tag should
+ * also be present. In the case of the {@literal @}RestrictTo tag, the
+ * {@literal @}hide tag should also be present.
+ * <p>
+ * To configure this check, do the following:
+ * <pre>
+ *     &lt;module name="MismatchedAnnotationCheck"&gt;
+ *       &lt;property name="tag" value="hide" /&gt;
+ *       &lt;property name="annotation" value="android.support.annotation.RestrictTo" /&gt;
+ *       &lt;property name="messageKey" value="annotation.missing.hide" /&gt;
+ *       &lt;message key="annotation.missing.hide"
+ *                   value="Must include both {@literal @}RestrictTo annotation
+ *                          and {@literal @}hide Javadoc tag." /&gt;
+ *     &lt;/module&gt;
+ * </pre>
+ */
+@SuppressWarnings("unused")
+public final class MismatchedAnnotationCheck extends AbstractCheck {
+
+    /** Key for the warning message text by check properties. */
+    private static final String MSG_KEY_JAVADOC_DUPLICATE_TAG = "javadoc.duplicateTag";
+
+    /** Key for the warning message text by check properties. */
+    private static final String MSG_KEY_JAVADOC_MISSING = "javadoc.missing";
+
+    /** Javadoc tag. */
+    private String mTag;
+
+    /** Pattern for matching javadoc tag. */
+    private Pattern mMatchTag;
+
+    /** Simple annotation name. */
+    private String mAnnotationSimpleName;
+
+    /** Fully-qualified annotation name. */
+    private String mAnnotation;
+
+    /** Key for the warning message text specified by check properties. */
+    private String mMessageKey;
+
+    @Override
+    public int[] getDefaultTokens() {
+        return getAcceptableTokens();
+    }
+
+    /**
+     * Sets javadoc tag.
+     *
+     * @param tag javadoc tag to check
+     */
+    @SuppressWarnings("unused")
+    public void setTag(String tag) {
+        mTag = tag;
+
+        // Tag may either have a description or be on a line by itself.
+        mMatchTag = CommonUtils.createPattern("@" + tag + "(?:\\s|$)");
+    }
+
+    /**
+     * Sets annotation tag.
+     *
+     * @param annotation annotation to check
+     */
+    @SuppressWarnings("unused")
+    public void setAnnotation(String annotation) {
+        mAnnotation = annotation;
+
+        // Extract the simple class name.
+        final int lastDollar = annotation.lastIndexOf('$');
+        final int lastSep = lastDollar >= 0 ? lastDollar : annotation.lastIndexOf('.');
+        mAnnotationSimpleName = annotation.substring(lastSep + 1);
+    }
+
+
+    /**
+     * Sets annotation tag.
+     *
+     * @param messageKey key to use for failed check message
+     */
+    @SuppressWarnings("unused")
+    public void setMessageKey(String messageKey) {
+        mMessageKey = messageKey;
+    }
+
+    @Override
+    public int[] getAcceptableTokens() {
+        return new int[] {
+                TokenTypes.INTERFACE_DEF,
+                TokenTypes.CLASS_DEF,
+                TokenTypes.ANNOTATION_DEF,
+                TokenTypes.ENUM_DEF,
+                TokenTypes.METHOD_DEF,
+                TokenTypes.CTOR_DEF,
+                TokenTypes.VARIABLE_DEF,
+                TokenTypes.ENUM_CONSTANT_DEF,
+                TokenTypes.ANNOTATION_FIELD_DEF,
+        };
+    }
+
+    @Override
+    public int[] getRequiredTokens() {
+        return getAcceptableTokens();
+    }
+
+    @Override
+    public void visitToken(final DetailAST ast) {
+        final boolean containsAnnotation =
+                AnnotationUtility.containsAnnotation(ast, mAnnotationSimpleName)
+                        || AnnotationUtility.containsAnnotation(ast, mAnnotation);
+        final boolean containsJavadocTag = containsJavadocTag(ast);
+        if (containsAnnotation ^ containsJavadocTag) {
+            log(ast.getLineNo(), mMessageKey);
+        }
+    }
+
+    /**
+     * Checks to see if the text block contains the tag.
+     *
+     * @param ast the AST being visited
+     * @return true if contains the tag
+     */
+    private boolean containsJavadocTag(final DetailAST ast) {
+        final TextBlock javadoc = getFileContents().getJavadocBefore(ast.getLineNo());
+        if (javadoc == null) {
+            return false;
+        }
+
+        int currentLine = javadoc.getStartLineNo();
+        boolean found = false;
+
+        final String[] lines = javadoc.getText();
+        for (String line : lines) {
+            if (mMatchTag.matcher(line).find()) {
+                if (found) {
+                    log(currentLine, MSG_KEY_JAVADOC_DUPLICATE_TAG, mTag);
+                }
+                found = true;
+            }
+            currentLine++;
+        }
+
+        return found;
+    }
+}
diff --git a/documents-archive/AndroidManifest.xml b/documents-archive/AndroidManifest.xml
deleted file mode 100644
index 2cd0f7a..0000000
--- a/documents-archive/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.provider">
-    <uses-sdk android:minSdkVersion="19"/>
-    <application />
-</manifest>
diff --git a/documents-archive/src/android/support/provider/DocumentArchive.java b/documents-archive/src/android/support/provider/DocumentArchive.java
deleted file mode 100644
index 4b0b0b9..0000000
--- a/documents-archive/src/android/support/provider/DocumentArchive.java
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.provider;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.graphics.Point;
-import android.media.ExifInterface;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.os.OperationCanceledException;
-import android.os.ParcelFileDescriptor;
-import android.provider.DocumentsContract;
-import android.provider.DocumentsContract.Document;
-import android.provider.DocumentsProvider;
-import android.support.annotation.Nullable;
-import android.support.annotation.RestrictTo;
-import android.util.Log;
-import android.webkit.MimeTypeMap;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Stack;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Provides basic implementation for creating, extracting and accessing
- * files within archives exposed by a document provider. The id delimiter
- * must be a character which is not used in document ids generated by the
- * document provider.
- *
- * <p>This class is thread safe.
- *
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-public class DocumentArchive implements Closeable {
-    private static final String TAG = "DocumentArchive";
-
-    private static final String[] DEFAULT_PROJECTION = new String[] {
-            Document.COLUMN_DOCUMENT_ID,
-            Document.COLUMN_DISPLAY_NAME,
-            Document.COLUMN_MIME_TYPE,
-            Document.COLUMN_SIZE,
-            Document.COLUMN_FLAGS
-    };
-
-    private final Context mContext;
-    private final String mDocumentId;
-    private final char mIdDelimiter;
-    private final Uri mNotificationUri;
-    private final ZipFile mZipFile;
-    private final ExecutorService mExecutor;
-    private final Map<String, ZipEntry> mEntries;
-    private final Map<String, List<ZipEntry>> mTree;
-
-    private DocumentArchive(
-            Context context,
-            File file,
-            String documentId,
-            char idDelimiter,
-            @Nullable Uri notificationUri)
-            throws IOException {
-        mContext = context;
-        mDocumentId = documentId;
-        mIdDelimiter = idDelimiter;
-        mNotificationUri = notificationUri;
-        mZipFile = new ZipFile(file);
-        mExecutor = Executors.newSingleThreadExecutor();
-
-        // Build the tree structure in memory.
-        mTree = new HashMap<String, List<ZipEntry>>();
-        mTree.put("/", new ArrayList<ZipEntry>());
-
-        mEntries = new HashMap<String, ZipEntry>();
-        ZipEntry entry;
-        final List<? extends ZipEntry> entries = Collections.list(mZipFile.entries());
-        final Stack<ZipEntry> stack = new Stack<>();
-        for (int i = entries.size() - 1; i >= 0; i--) {
-            entry = entries.get(i);
-            if (entry.isDirectory() != entry.getName().endsWith("/")) {
-                throw new IOException(
-                        "Directories must have a trailing slash, and files must not.");
-            }
-            if (mEntries.containsKey(entry.getName())) {
-                throw new IOException("Multiple entries with the same name are not supported.");
-            }
-            mEntries.put(entry.getName(), entry);
-            if (entry.isDirectory()) {
-                mTree.put(entry.getName(), new ArrayList<ZipEntry>());
-            }
-            stack.push(entry);
-        }
-
-        int delimiterIndex;
-        String parentPath;
-        ZipEntry parentEntry;
-        List<ZipEntry> parentList;
-
-        while (stack.size() > 0) {
-            entry = stack.pop();
-
-            delimiterIndex = entry.getName().lastIndexOf('/', entry.isDirectory()
-                    ? entry.getName().length() - 2 : entry.getName().length() - 1);
-            parentPath =
-                    delimiterIndex != -1 ? entry.getName().substring(0, delimiterIndex) + "/" : "/";
-            parentList = mTree.get(parentPath);
-
-            if (parentList == null) {
-                parentEntry = mEntries.get(parentPath);
-                if (parentEntry == null) {
-                    // The ZIP file doesn't contain all directories leading to the entry.
-                    // It's rare, but can happen in a valid ZIP archive. In such case create a
-                    // fake ZipEntry and add it on top of the stack to process it next.
-                    parentEntry = new ZipEntry(parentPath);
-                    parentEntry.setSize(0);
-                    parentEntry.setTime(entry.getTime());
-                    mEntries.put(parentPath, parentEntry);
-                    stack.push(parentEntry);
-                }
-                parentList = new ArrayList<ZipEntry>();
-                mTree.put(parentPath, parentList);
-            }
-
-            parentList.add(entry);
-        }
-    }
-
-    /**
-     * Creates a DocumentsArchive instance for opening, browsing and accessing
-     * documents within the archive passed as a local file.
-     *
-     * @param context Context of the provider.
-     * @param File Local file containing the archive.
-     * @param documentId ID of the archive document.
-     * @param idDelimiter Delimiter for constructing IDs of documents within the archive.
-     *            The delimiter must never be used for IDs of other documents.
-     * @param Uri notificationUri Uri for notifying that the archive file has changed.
-     * @see createForParcelFileDescriptor(DocumentsProvider, ParcelFileDescriptor, String, char,
-     *          Uri)
-     */
-    public static DocumentArchive createForLocalFile(
-            Context context, File file, String documentId, char idDelimiter,
-            @Nullable Uri notificationUri)
-            throws IOException {
-        return new DocumentArchive(context, file, documentId, idDelimiter, notificationUri);
-    }
-
-    /**
-     * Creates a DocumentsArchive instance for opening, browsing and accessing
-     * documents within the archive passed as a file descriptor.
-     *
-     * <p>Note, that this method should be used only if the document does not exist
-     * on the local storage. A snapshot file will be created, which may be slower
-     * and consume significant resources, in contrast to using
-     * {@see createForLocalFile(Context, File, String, char, Uri}.
-     *
-     * @param context Context of the provider.
-     * @param descriptor File descriptor for the archive's contents.
-     * @param documentId ID of the archive document.
-     * @param idDelimiter Delimiter for constructing IDs of documents within the archive.
-     *            The delimiter must never be used for IDs of other documents.
-     * @param Uri notificationUri Uri for notifying that the archive file has changed.
-     * @see createForLocalFile(Context, File, String, char, Uri)
-     */
-    public static DocumentArchive createForParcelFileDescriptor(
-            Context context, ParcelFileDescriptor descriptor, String documentId,
-            char idDelimiter, @Nullable Uri notificationUri)
-            throws IOException {
-        File snapshotFile = null;
-        try {
-            // Create a copy of the archive, as ZipFile doesn't operate on streams.
-            // Moreover, ZipInputStream would be inefficient for large files on
-            // pipes.
-            snapshotFile = File.createTempFile("android.support.provider.snapshot{",
-                    "}.zip", context.getCacheDir());
-
-            try (
-                final FileOutputStream outputStream =
-                        new ParcelFileDescriptor.AutoCloseOutputStream(
-                                ParcelFileDescriptor.open(
-                                        snapshotFile, ParcelFileDescriptor.MODE_WRITE_ONLY));
-                final ParcelFileDescriptor.AutoCloseInputStream inputStream =
-                        new ParcelFileDescriptor.AutoCloseInputStream(descriptor);
-            ) {
-                final byte[] buffer = new byte[32 * 1024];
-                int bytes;
-                while ((bytes = inputStream.read(buffer)) != -1) {
-                    outputStream.write(buffer, 0, bytes);
-                }
-                outputStream.flush();
-                return new DocumentArchive(context, snapshotFile, documentId, idDelimiter,
-                        notificationUri);
-            }
-        } finally {
-            // On UNIX the file will be still available for processes which opened it, even
-            // after deleting it. Remove it ASAP, as it won't be used by anyone else.
-            if (snapshotFile != null) {
-                snapshotFile.delete();
-            }
-        }
-    }
-
-    /**
-     * Lists child documents of an archive or a directory within an
-     * archive. Must be called only for archives with supported mime type,
-     * or for documents within archives.
-     *
-     * @see DocumentsProvider.queryChildDocuments(String, String[], String)
-     */
-    public Cursor queryChildDocuments(String documentId, @Nullable String[] projection,
-            @Nullable String sortOrder) throws FileNotFoundException {
-        final ParsedDocumentId parsedParentId = ParsedDocumentId.fromDocumentId(
-                documentId, mIdDelimiter);
-        Preconditions.checkArgumentEquals(mDocumentId, parsedParentId.mArchiveId,
-                "Mismatching document ID. Expected: %s, actual: %s.");
-
-        final String parentPath = parsedParentId.mPath != null ? parsedParentId.mPath : "/";
-        final MatrixCursor result = new MatrixCursor(
-                projection != null ? projection : DEFAULT_PROJECTION);
-        if (mNotificationUri != null) {
-            result.setNotificationUri(mContext.getContentResolver(), mNotificationUri);
-        }
-
-        final List<ZipEntry> parentList = mTree.get(parentPath);
-        if (parentList == null) {
-            throw new FileNotFoundException();
-        }
-        for (final ZipEntry entry : parentList) {
-            addCursorRow(result, entry);
-        }
-        return result;
-    }
-
-    /**
-     * Returns a MIME type of a document within an archive.
-     *
-     * @see DocumentsProvider.getDocumentType(String)
-     */
-    public String getDocumentType(String documentId) throws FileNotFoundException {
-        final ParsedDocumentId parsedId = ParsedDocumentId.fromDocumentId(
-                documentId, mIdDelimiter);
-        Preconditions.checkArgumentEquals(mDocumentId, parsedId.mArchiveId,
-                "Mismatching document ID. Expected: %s, actual: %s.");
-        Preconditions.checkArgumentNotNull(parsedId.mPath, "Not a document within an archive.");
-
-        final ZipEntry entry = mEntries.get(parsedId.mPath);
-        if (entry == null) {
-            throw new FileNotFoundException();
-        }
-        return getMimeTypeForEntry(entry);
-    }
-
-    /**
-     * Returns true if a document within an archive is a child or any descendant of the archive
-     * document or another document within the archive.
-     *
-     * @see DocumentsProvider.isChildDocument(String, String)
-     */
-    public boolean isChildDocument(String parentDocumentId, String documentId) {
-        final ParsedDocumentId parsedParentId = ParsedDocumentId.fromDocumentId(
-                parentDocumentId, mIdDelimiter);
-        final ParsedDocumentId parsedId = ParsedDocumentId.fromDocumentId(
-                documentId, mIdDelimiter);
-        Preconditions.checkArgumentEquals(mDocumentId, parsedParentId.mArchiveId,
-                "Mismatching document ID. Expected: %s, actual: %s.");
-        Preconditions.checkArgumentNotNull(parsedId.mPath,
-                "Not a document within an archive.");
-
-        final ZipEntry entry = mEntries.get(parsedId.mPath);
-        if (entry == null) {
-            return false;
-        }
-
-        if (parsedParentId.mPath == null) {
-            // No need to compare paths. Every file in the archive is a child of the archive
-            // file.
-            return true;
-        }
-
-        final ZipEntry parentEntry = mEntries.get(parsedParentId.mPath);
-        if (parentEntry == null || !parentEntry.isDirectory()) {
-            return false;
-        }
-
-        final String parentPath = entry.getName();
-
-        // Add a trailing slash even if it's not a directory, so it's easy to check if the
-        // entry is a descendant.
-        final String pathWithSlash = entry.isDirectory() ? entry.getName() : entry.getName() + "/";
-        return pathWithSlash.startsWith(parentPath) && !parentPath.equals(pathWithSlash);
-    }
-
-    /**
-     * Returns metadata of a document within an archive.
-     *
-     * @see DocumentsProvider.queryDocument(String, String[])
-     */
-    public Cursor queryDocument(String documentId, @Nullable String[] projection)
-            throws FileNotFoundException {
-        final ParsedDocumentId parsedId = ParsedDocumentId.fromDocumentId(
-                documentId, mIdDelimiter);
-        Preconditions.checkArgumentEquals(mDocumentId, parsedId.mArchiveId,
-                "Mismatching document ID. Expected: %s, actual: %s.");
-        Preconditions.checkArgumentNotNull(parsedId.mPath, "Not a document within an archive.");
-
-        final ZipEntry entry = mEntries.get(parsedId.mPath);
-        if (entry == null) {
-            throw new FileNotFoundException();
-        }
-
-        final MatrixCursor result = new MatrixCursor(
-                projection != null ? projection : DEFAULT_PROJECTION);
-        if (mNotificationUri != null) {
-            result.setNotificationUri(mContext.getContentResolver(), mNotificationUri);
-        }
-        addCursorRow(result, entry);
-        return result;
-    }
-
-    /**
-     * Opens a file within an archive.
-     *
-     * @see DocumentsProvider.openDocument(String, String, CancellationSignal))
-     */
-    public ParcelFileDescriptor openDocument(
-            String documentId, String mode, @Nullable final CancellationSignal signal)
-            throws FileNotFoundException {
-        Preconditions.checkArgumentEquals("r", mode,
-                "Invalid mode. Only reading \"r\" supported, but got: \"%s\".");
-        final ParsedDocumentId parsedId = ParsedDocumentId.fromDocumentId(
-                documentId, mIdDelimiter);
-        Preconditions.checkArgumentEquals(mDocumentId, parsedId.mArchiveId,
-                "Mismatching document ID. Expected: %s, actual: %s.");
-        Preconditions.checkArgumentNotNull(parsedId.mPath, "Not a document within an archive.");
-
-        final ZipEntry entry = mEntries.get(parsedId.mPath);
-        if (entry == null) {
-            throw new FileNotFoundException();
-        }
-
-        ParcelFileDescriptor[] pipe;
-        InputStream inputStream = null;
-        try {
-            pipe = ParcelFileDescriptor.createReliablePipe();
-            inputStream = mZipFile.getInputStream(entry);
-        } catch (IOException e) {
-            if (inputStream != null) {
-                IoUtils.closeQuietly(inputStream);
-            }
-            // Ideally we'd simply throw IOException to the caller, but for consistency
-            // with DocumentsProvider::openDocument, converting it to IllegalStateException.
-            throw new IllegalStateException("Failed to open the document.", e);
-        }
-        final ParcelFileDescriptor outputPipe = pipe[1];
-        final InputStream finalInputStream = inputStream;
-        mExecutor.execute(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        try (final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
-                                new ParcelFileDescriptor.AutoCloseOutputStream(outputPipe)) {
-                            try {
-                                final byte buffer[] = new byte[32 * 1024];
-                                int bytes;
-                                while ((bytes = finalInputStream.read(buffer)) != -1) {
-                                    if (Thread.interrupted()) {
-                                        throw new InterruptedException();
-                                    }
-                                    if (signal != null) {
-                                        signal.throwIfCanceled();
-                                    }
-                                    outputStream.write(buffer, 0, bytes);
-                                }
-                            } catch (IOException | InterruptedException e) {
-                                // Catch the exception before the outer try-with-resource closes the
-                                // pipe with close() instead of closeWithError().
-                                try {
-                                    outputPipe.closeWithError(e.getMessage());
-                                } catch (IOException e2) {
-                                    Log.e(TAG, "Failed to close the pipe after an error.", e2);
-                                }
-                            }
-                        } catch (OperationCanceledException e) {
-                            // Cancelled gracefully.
-                        } catch (IOException e) {
-                            Log.e(TAG, "Failed to close the output stream gracefully.", e);
-                        } finally {
-                            IoUtils.closeQuietly(finalInputStream);
-                        }
-                    }
-                });
-
-        return pipe[0];
-    }
-
-    /**
-     * Opens a thumbnail of a file within an archive.
-     *
-     * @see DocumentsProvider.openDocumentThumbnail(String, Point, CancellationSignal))
-     */
-    public AssetFileDescriptor openDocumentThumbnail(
-            String documentId, Point sizeHint, final CancellationSignal signal)
-            throws FileNotFoundException {
-        final ParsedDocumentId parsedId = ParsedDocumentId.fromDocumentId(documentId, mIdDelimiter);
-        Preconditions.checkArgumentEquals(mDocumentId, parsedId.mArchiveId,
-                "Mismatching document ID. Expected: %s, actual: %s.");
-        Preconditions.checkArgumentNotNull(parsedId.mPath, "Not a document within an archive.");
-        Preconditions.checkArgument(getDocumentType(documentId).startsWith("image/"),
-                "Thumbnails only supported for image/* MIME type.");
-
-        final ZipEntry entry = mEntries.get(parsedId.mPath);
-        if (entry == null) {
-            throw new FileNotFoundException();
-        }
-
-        InputStream inputStream = null;
-        try {
-            inputStream = mZipFile.getInputStream(entry);
-            final ExifInterface exif = new ExifInterface(inputStream);
-            if (exif.hasThumbnail()) {
-                Bundle extras = null;
-                switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1)) {
-                    case ExifInterface.ORIENTATION_ROTATE_90:
-                        extras = new Bundle(1);
-                        extras.putInt(DocumentsContract.EXTRA_ORIENTATION, 90);
-                        break;
-                    case ExifInterface.ORIENTATION_ROTATE_180:
-                        extras = new Bundle(1);
-                        extras.putInt(DocumentsContract.EXTRA_ORIENTATION, 180);
-                        break;
-                    case ExifInterface.ORIENTATION_ROTATE_270:
-                        extras = new Bundle(1);
-                        extras.putInt(DocumentsContract.EXTRA_ORIENTATION, 270);
-                        break;
-                }
-                final long[] range = exif.getThumbnailRange();
-                return new AssetFileDescriptor(
-                        openDocument(documentId, "r", signal), range[0], range[1], extras);
-            }
-        } catch (IOException e) {
-            // Ignore the exception, as reading the EXIF may legally fail.
-            Log.e(TAG, "Failed to obtain thumbnail from EXIF.", e);
-        } finally {
-            IoUtils.closeQuietly(inputStream);
-        }
-
-        return new AssetFileDescriptor(
-                openDocument(documentId, "r", signal), 0, entry.getSize(), null);
-    }
-
-    /**
-     * Schedules a gracefully close of the archive after any opened files are closed.
-     *
-     * <p>This method does not block until shutdown. Once called, other methods should not be
-     * called.
-     */
-    @Override
-    public void close() {
-        mExecutor.execute(new Runnable() {
-            @Override
-            public void run() {
-                IoUtils.closeQuietly(mZipFile);
-            }
-        });
-        mExecutor.shutdown();
-    }
-
-    private void addCursorRow(MatrixCursor cursor, ZipEntry entry) {
-        final MatrixCursor.RowBuilder row = cursor.newRow();
-        final ParsedDocumentId parsedId = new ParsedDocumentId(mDocumentId, entry.getName());
-        row.add(Document.COLUMN_DOCUMENT_ID, parsedId.toDocumentId(mIdDelimiter));
-
-        final File file = new File(entry.getName());
-        row.add(Document.COLUMN_DISPLAY_NAME, file.getName());
-        row.add(Document.COLUMN_SIZE, entry.getSize());
-
-        final String mimeType = getMimeTypeForEntry(entry);
-        row.add(Document.COLUMN_MIME_TYPE, mimeType);
-
-        final int flags = mimeType.startsWith("image/") ? Document.FLAG_SUPPORTS_THUMBNAIL : 0;
-        row.add(Document.COLUMN_FLAGS, flags);
-    }
-
-    private String getMimeTypeForEntry(ZipEntry entry) {
-        if (entry.isDirectory()) {
-            return Document.MIME_TYPE_DIR;
-        }
-
-        final int lastDot = entry.getName().lastIndexOf('.');
-        if (lastDot >= 0) {
-            final String extension = entry.getName().substring(lastDot + 1).toLowerCase(Locale.US);
-            final String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
-            if (mimeType != null) {
-                return mimeType;
-            }
-        }
-
-        return "application/octet-stream";
-    }
-};
diff --git a/documents-archive/src/android/support/provider/DocumentArchiveHelper.java b/documents-archive/src/android/support/provider/DocumentArchiveHelper.java
deleted file mode 100644
index 6c5e198..0000000
--- a/documents-archive/src/android/support/provider/DocumentArchiveHelper.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.provider;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.content.res.AssetFileDescriptor;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.graphics.Point;
-import android.net.Uri;
-import android.os.CancellationSignal;
-import android.os.ParcelFileDescriptor;
-import android.provider.DocumentsContract.Document;
-import android.provider.DocumentsProvider;
-import android.support.annotation.Nullable;
-import android.support.annotation.RestrictTo;
-import android.util.Log;
-import android.util.LruCache;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * Provides basic implementation for creating, extracting and accessing
- * files within archives exposed by a document provider.
- *
- * <p>This class is thread safe. All methods can be called on any thread without
- * synchronization.
- *
- * TODO: Update the documentation. b/26047732
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-public class DocumentArchiveHelper implements Closeable {
-    /**
-     * Cursor column to be used for passing the local file path for documents.
-     * If it's not specified, then a snapshot will be created, which is slower
-     * and consumes more resources.
-     *
-     * <p>Type: STRING
-     */
-    public static final String COLUMN_LOCAL_FILE_PATH = "local_file_path";
-
-    private static final String TAG = "DocumentArchiveHelper";
-    private static final int OPENED_ARCHIVES_CACHE_SIZE = 4;
-    private static final String[] ZIP_MIME_TYPES = {
-            "application/zip", "application/x-zip", "application/x-zip-compressed"
-    };
-
-    private final DocumentsProvider mProvider;
-    private final char mIdDelimiter;
-
-    // @GuardedBy("mArchives")
-    private final LruCache<String, Loader> mArchives =
-            new LruCache<String, Loader>(OPENED_ARCHIVES_CACHE_SIZE) {
-                @Override
-                public void entryRemoved(boolean evicted, String key,
-                        Loader oldValue, Loader newValue) {
-                    oldValue.getWriteLock().lock();
-                    try {
-                        oldValue.get().close();
-                    } catch (FileNotFoundException e) {
-                        Log.e(TAG, "Failed to close an archive as it no longer exists.");
-                    } finally {
-                        oldValue.getWriteLock().unlock();
-                    }
-                }
-            };
-
-    /**
-     * Creates a helper for handling archived documents.
-     *
-     * @param provider Instance of a documents provider which provides archived documents.
-     * @param idDelimiter A character used to create document IDs within archives. Can be any
-     *            character which is not used in any other document ID. If your provider uses
-     *            numbers as document IDs, the delimiter can be eg. a colon. However if your
-     *            provider uses paths, then a delimiter can be any character not allowed in the
-     *            path, which is often \0.
-     */
-    public DocumentArchiveHelper(DocumentsProvider provider, char idDelimiter) {
-        mProvider = provider;
-        mIdDelimiter = idDelimiter;
-    }
-
-    /**
-     * Lists child documents of an archive or a directory within an
-     * archive. Must be called only for archives with supported mime type,
-     * or for documents within archives.
-     *
-     * @see DocumentsProvider.queryChildDocuments(String, String[], String)
-     */
-    public Cursor queryChildDocuments(String documentId, @Nullable String[] projection,
-            @Nullable String sortOrder)
-            throws FileNotFoundException {
-        Loader loader = null;
-        try {
-            loader = obtainInstance(documentId);
-            return loader.get().queryChildDocuments(documentId, projection, sortOrder);
-        } finally {
-            releaseInstance(loader);
-        }
-    }
-
-    /**
-     * Returns a MIME type of a document within an archive.
-     *
-     * @see DocumentsProvider.getDocumentType(String)
-     */
-    public String getDocumentType(String documentId) throws FileNotFoundException {
-        Loader loader = null;
-        try {
-            loader = obtainInstance(documentId);
-            return loader.get().getDocumentType(documentId);
-        } finally {
-            releaseInstance(loader);
-        }
-    }
-
-    /**
-     * Returns true if a document within an archive is a child or any descendant of the archive
-     * document or another document within the archive.
-     *
-     * @see DocumentsProvider.isChildDocument(String, String)
-     */
-    public boolean isChildDocument(String parentDocumentId, String documentId) {
-        Loader loader = null;
-        try {
-            loader = obtainInstance(documentId);
-            return loader.get().isChildDocument(parentDocumentId, documentId);
-        } catch (FileNotFoundException e) {
-            throw new IllegalStateException(e);
-        } finally {
-            releaseInstance(loader);
-        }
-    }
-
-    /**
-     * Returns metadata of a document within an archive.
-     *
-     * @see DocumentsProvider.queryDocument(String, String[])
-     */
-    public Cursor queryDocument(String documentId, @Nullable String[] projection)
-            throws FileNotFoundException {
-        Loader loader = null;
-        try {
-            loader = obtainInstance(documentId);
-            return loader.get().queryDocument(documentId, projection);
-        } finally {
-            releaseInstance(loader);
-        }
-    }
-
-    /**
-     * Opens a file within an archive.
-     *
-     * @see DocumentsProvider.openDocument(String, String, CancellationSignal))
-     */
-    public ParcelFileDescriptor openDocument(
-            String documentId, String mode, final CancellationSignal signal)
-            throws FileNotFoundException {
-        Loader loader = null;
-        try {
-            loader = obtainInstance(documentId);
-            return loader.get().openDocument(documentId, mode, signal);
-        } finally {
-            releaseInstance(loader);
-        }
-    }
-
-    /**
-     * Opens a thumbnail of a file within an archive.
-     *
-     * @see DocumentsProvider.openDocumentThumbnail(String, Point, CancellationSignal))
-     */
-    public AssetFileDescriptor openDocumentThumbnail(
-            String documentId, Point sizeHint, final CancellationSignal signal)
-            throws FileNotFoundException {
-        Loader loader = null;
-        try {
-            loader = obtainInstance(documentId);
-            return loader.get().openDocumentThumbnail(documentId, sizeHint, signal);
-        } finally {
-            releaseInstance(loader);
-        }
-    }
-
-    /**
-     * Returns true if the passed document ID is for a document within an archive.
-     */
-    public boolean isArchivedDocument(String documentId) {
-        return ParsedDocumentId.hasPath(documentId, mIdDelimiter);
-    }
-
-    /**
-     * Returns true if the passed mime type is supported by the helper.
-     */
-    public boolean isSupportedArchiveType(String mimeType) {
-        for (final String zipMimeType : ZIP_MIME_TYPES) {
-            if (zipMimeType.equals(mimeType)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Closes the helper and disposes all existing archives. It will block until all ongoing
-     * operations on each opened archive are finished.
-     */
-    @Override
-    public void close() {
-        synchronized (mArchives) {
-            mArchives.evictAll();
-        }
-    }
-
-    /**
-     * Releases resources for an archive with the specified document ID. It will block until all
-     * operations on the archive are finished. If not opened, the method does nothing.
-     *
-     * <p>Calling this method is optional. The helper automatically closes the least recently used
-     * archives if too many archives are opened.
-     *
-     * @param archiveDocumentId ID of the archive file.
-     */
-    public void closeArchive(String documentId) {
-        synchronized (mArchives) {
-            mArchives.remove(documentId);
-        }
-    }
-
-    private Loader obtainInstance(String documentId) throws FileNotFoundException {
-        Loader loader;
-        synchronized (mArchives) {
-            loader = getInstanceUncheckedLocked(documentId);
-            loader.getReadLock().lock();
-        }
-        return loader;
-    }
-
-    private void releaseInstance(@Nullable Loader loader) {
-        if (loader != null) {
-            loader.getReadLock().unlock();
-        }
-    }
-
-    private Loader getInstanceUncheckedLocked(String documentId)
-            throws FileNotFoundException {
-        try {
-            final ParsedDocumentId id = ParsedDocumentId.fromDocumentId(documentId, mIdDelimiter);
-            if (mArchives.get(id.mArchiveId) != null) {
-                return mArchives.get(id.mArchiveId);
-            }
-
-            final Cursor cursor = mProvider.queryDocument(id.mArchiveId, new String[]
-                    { Document.COLUMN_MIME_TYPE, COLUMN_LOCAL_FILE_PATH });
-            cursor.moveToFirst();
-            final String mimeType = cursor.getString(cursor.getColumnIndex(
-                    Document.COLUMN_MIME_TYPE));
-            Preconditions.checkArgument(isSupportedArchiveType(mimeType),
-                    "Unsupported archive type.");
-            final int columnIndex = cursor.getColumnIndex(COLUMN_LOCAL_FILE_PATH);
-            final String localFilePath = columnIndex != -1 ? cursor.getString(columnIndex) : null;
-            final File localFile = localFilePath != null ? new File(localFilePath) : null;
-            final Uri notificationUri = cursor.getNotificationUri();
-            final Loader loader = new Loader(mProvider, localFile, id, mIdDelimiter,
-                    notificationUri);
-
-            // Remove the instance from mArchives collection once the archive file changes.
-            if (notificationUri != null) {
-                final LruCache<String, Loader> finalArchives = mArchives;
-                mProvider.getContext().getContentResolver().registerContentObserver(notificationUri,
-                        false,
-                        new ContentObserver(null) {
-                            @Override
-                            public void onChange(boolean selfChange, Uri uri) {
-                                synchronized (mArchives) {
-                                    final Loader currentLoader = mArchives.get(id.mArchiveId);
-                                    if (currentLoader == loader) {
-                                        mArchives.remove(id.mArchiveId);
-                                    }
-                                }
-                            }
-                        });
-            }
-
-            mArchives.put(id.mArchiveId, loader);
-            return loader;
-        } catch (IOException e) {
-            // DocumentsProvider doesn't use IOException. For consistency convert it to
-            // IllegalStateException.
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Loads an instance of DocumentArchive lazily.
-     */
-    private static final class Loader {
-        private final DocumentsProvider mProvider;
-        private final File mLocalFile;
-        private final ParsedDocumentId mId;
-        private final char mIdDelimiter;
-        private final Uri mNotificationUri;
-        private final ReentrantReadWriteLock mLock = new ReentrantReadWriteLock();
-        private DocumentArchive mArchive = null;
-
-        Loader(DocumentsProvider provider, @Nullable File localFile, ParsedDocumentId id,
-                char idDelimiter, Uri notificationUri) {
-            this.mProvider = provider;
-            this.mLocalFile = localFile;
-            this.mId = id;
-            this.mIdDelimiter = idDelimiter;
-            this.mNotificationUri = notificationUri;
-        }
-
-        synchronized DocumentArchive get() throws FileNotFoundException {
-            if (mArchive != null) {
-                return mArchive;
-            }
-
-            try {
-                if (mLocalFile != null) {
-                    mArchive = DocumentArchive.createForLocalFile(
-                            mProvider.getContext(), mLocalFile, mId.mArchiveId, mIdDelimiter,
-                            mNotificationUri);
-                } else {
-                    mArchive = DocumentArchive.createForParcelFileDescriptor(
-                            mProvider.getContext(),
-                            mProvider.openDocument(mId.mArchiveId, "r", null /* signal */),
-                            mId.mArchiveId, mIdDelimiter, mNotificationUri);
-                }
-            } catch (IOException e) {
-                throw new IllegalStateException(e);
-            }
-
-            return mArchive;
-        }
-
-        Lock getReadLock() {
-            return mLock.readLock();
-        }
-
-        Lock getWriteLock() {
-            return mLock.writeLock();
-        }
-    }
-}
diff --git a/documents-archive/src/android/support/provider/IoUtils.java b/documents-archive/src/android/support/provider/IoUtils.java
deleted file mode 100644
index 55c293d..0000000
--- a/documents-archive/src/android/support/provider/IoUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.provider;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.support.annotation.Nullable;
-import android.support.annotation.RestrictTo;
-
-import java.io.Closeable;
-import java.io.InputStream;
-
-/**
- * Simple static methods to perform common IO operations.
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-final class IoUtils {
-    static void closeQuietly(@Nullable Closeable closeable) {
-       if (closeable != null) {
-            try {
-                closeable.close();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                // Ignore.
-            }
-        }
-    }
-
-    static void closeQuietly(@Nullable InputStream stream) {
-       if (stream != null) {
-            try {
-                stream.close();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                // Ignore.
-            }
-        }
-    }
-}
diff --git a/documents-archive/src/android/support/provider/ParsedDocumentId.java b/documents-archive/src/android/support/provider/ParsedDocumentId.java
deleted file mode 100644
index a8c7810..0000000
--- a/documents-archive/src/android/support/provider/ParsedDocumentId.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.provider;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.support.annotation.RestrictTo;
-
-/**
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-class ParsedDocumentId {
-    public final String mArchiveId;
-    public final String mPath;
-
-    public ParsedDocumentId(String archiveId, String path) {
-        mArchiveId = archiveId;
-        mPath = path;
-    }
-
-    static public ParsedDocumentId fromDocumentId(String documentId, char idDelimiter) {
-        final int delimiterPosition = documentId.indexOf(idDelimiter);
-        if (delimiterPosition == -1) {
-            return new ParsedDocumentId(documentId, null);
-        } else {
-            return new ParsedDocumentId(documentId.substring(0, delimiterPosition),
-                    documentId.substring((delimiterPosition + 1)));
-        }
-    }
-
-    static public boolean hasPath(String documentId, char idDelimiter) {
-        return documentId.indexOf(idDelimiter) != -1;
-    }
-
-    public String toDocumentId(char idDelimiter) {
-        if (mPath == null) {
-            return mArchiveId;
-        } else {
-            return mArchiveId + idDelimiter + mPath;
-        }
-    }
-};
diff --git a/documents-archive/src/android/support/provider/Preconditions.java b/documents-archive/src/android/support/provider/Preconditions.java
deleted file mode 100644
index e3971aa..0000000
--- a/documents-archive/src/android/support/provider/Preconditions.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.provider;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.support.annotation.Nullable;
-import android.support.annotation.RestrictTo;
-import android.text.TextUtils;
-
-/**
- * Simple static methods to be called at the start of your own methods to verify
- * correct arguments and state.
- * @hide
- */
-@RestrictTo(LIBRARY_GROUP)
-final class Preconditions {
-    static void checkArgument(boolean expression, String message) {
-        if (!expression) {
-            throw new IllegalArgumentException(message);
-        }
-    }
-
-    static void checkArgumentNotNull(Object object, String message) {
-        if (object == null) {
-            throw new IllegalArgumentException(message);
-        }
-    }
-
-    static void checkArgumentEquals(String expected, @Nullable String actual, String message) {
-        if (!TextUtils.equals(expected, actual)) {
-            throw new IllegalArgumentException(String.format(message, String.valueOf(expected),
-                    String.valueOf(actual)));
-        }
-    }
-
-    static void checkState(boolean expression, String message) {
-        if (!expression) {
-            throw new IllegalStateException(message);
-        }
-    }
-}
diff --git a/documents-archive/tests/AndroidManifest.xml b/documents-archive/tests/AndroidManifest.xml
deleted file mode 100644
index 47da733..0000000
--- a/documents-archive/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.support.provider.tests">
-    <application>
-        <uses-library android:name="android.test.runner" />
-        <provider
-            android:name="android.support.provider.tests.StubProvider"
-            android:authorities="android.support.provider.tests.mystubprovider"
-            android:grantUriPermissions="true"
-            android:exported="true"
-            android:permission="android.permission.MANAGE_DOCUMENTS" />
-    </application>
-
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="android.support.provider.tests"
-        android:label="Tests for android.support.provider." />
-</manifest>
diff --git a/documents-archive/tests/NO_DOCS b/documents-archive/tests/NO_DOCS
deleted file mode 100644
index e69de29..0000000
--- a/documents-archive/tests/NO_DOCS
+++ /dev/null
diff --git a/documents-archive/tests/res/raw/archive.zip b/documents-archive/tests/res/raw/archive.zip
deleted file mode 100644
index c3b8d22..0000000
--- a/documents-archive/tests/res/raw/archive.zip
+++ /dev/null
Binary files differ
diff --git a/documents-archive/tests/res/raw/empty_dirs.zip b/documents-archive/tests/res/raw/empty_dirs.zip
deleted file mode 100644
index 1dd2251..0000000
--- a/documents-archive/tests/res/raw/empty_dirs.zip
+++ /dev/null
Binary files differ
diff --git a/documents-archive/tests/res/raw/no_dirs.zip b/documents-archive/tests/res/raw/no_dirs.zip
deleted file mode 100644
index e178ae1..0000000
--- a/documents-archive/tests/res/raw/no_dirs.zip
+++ /dev/null
Binary files differ
diff --git a/documents-archive/tests/src/android/support/provider/DocumentArchiveTest.java b/documents-archive/tests/src/android/support/provider/DocumentArchiveTest.java
deleted file mode 100644
index 9845412..0000000
--- a/documents-archive/tests/src/android/support/provider/DocumentArchiveTest.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.provider.tests;
-
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.provider.DocumentsContract.Document;
-import android.support.provider.DocumentArchive;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Scanner;
-
-/**
- * Tests for DocumentArchive.
- */
-public class DocumentArchiveTest extends AndroidTestCase {
-    private static final String DOCUMENT_ID = "document-id";
-    private static final char DELIMITER = ':';
-    private static final String NOTIFICATION_URI = "content://notification-uri";
-    private DocumentArchive mArchive = null;
-
-    public void loadArchive(int resource) {
-        // Extract the file from resources.
-        File file = null;
-        try {
-            file = File.createTempFile("android.support.provider.tests{",
-                    "}.zip", mContext.getCacheDir());
-            try (
-                final FileOutputStream outputStream =
-                        new ParcelFileDescriptor.AutoCloseOutputStream(
-                                ParcelFileDescriptor.open(
-                                        file, ParcelFileDescriptor.MODE_WRITE_ONLY));
-                final InputStream inputStream =
-                        mContext.getResources().openRawResource(resource);
-            ) {
-                final byte[] buffer = new byte[32 * 1024];
-                int bytes;
-                while ((bytes = inputStream.read(buffer)) != -1) {
-                    outputStream.write(buffer, 0, bytes);
-                }
-                outputStream.flush();
-                mArchive = DocumentArchive.createForLocalFile(
-                      mContext,
-                      file,
-                      DOCUMENT_ID,
-                      DELIMITER,
-                      Uri.parse(NOTIFICATION_URI));
-
-            }
-        } catch (IOException e) {
-            fail(String.valueOf(e));
-        } finally {
-            // On UNIX the file will be still available for processes which opened it, even
-            // after deleting it. Remove it ASAP, as it won't be used by anyone else.
-            if (file != null) {
-                file.delete();
-            }
-        }
-    }
-
-    @Override
-    public void tearDown() {
-        if (mArchive != null) {
-            mArchive.close();
-        }
-    }
-
-    public void testQueryChildDocument() throws IOException {
-        loadArchive(R.raw.archive);
-        final Cursor cursor = mArchive.queryChildDocuments(DOCUMENT_ID, null, null);
-
-        assertTrue(cursor.moveToFirst());
-        assertEquals("document-id:dir1/",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("dir1",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)));
-        assertEquals(Document.MIME_TYPE_DIR,
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE)));
-        assertEquals(0,
-                cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-
-        assertTrue(cursor.moveToNext());
-        assertEquals("document-id:dir2/",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("dir2",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)));
-        assertEquals(Document.MIME_TYPE_DIR,
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE)));
-        assertEquals(0,
-                cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-
-        assertTrue(cursor.moveToNext());
-        assertEquals("document-id:file1.txt",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("file1.txt",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)));
-        assertEquals("text/plain",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE)));
-        assertEquals(13,
-                cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-
-        assertFalse(cursor.moveToNext());
-
-        // Check if querying children works too.
-        final Cursor childCursor = mArchive.queryChildDocuments("document-id:dir1/", null, null);
-
-        assertTrue(childCursor.moveToFirst());
-        assertEquals("document-id:dir1/cherries.txt",
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("cherries.txt",
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DISPLAY_NAME)));
-        assertEquals("text/plain",
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_MIME_TYPE)));
-        assertEquals(17,
-                childCursor.getInt(childCursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-    }
-
-    public void testQueryChildDocument_NoDirs() throws IOException {
-        loadArchive(R.raw.no_dirs);
-        final Cursor cursor = mArchive.queryChildDocuments(DOCUMENT_ID, null, null);
-
-        assertTrue(cursor.moveToFirst());
-        assertEquals("document-id:dir1/",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("dir1",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)));
-        assertEquals(Document.MIME_TYPE_DIR,
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE)));
-        assertEquals(0,
-                cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-        assertFalse(cursor.moveToNext());
-
-        final Cursor childCursor = mArchive.queryChildDocuments("document-id:dir1/", null, null);
-
-        assertTrue(childCursor.moveToFirst());
-        assertEquals("document-id:dir1/dir2/",
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("dir2",
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DISPLAY_NAME)));
-        assertEquals(Document.MIME_TYPE_DIR,
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_MIME_TYPE)));
-        assertEquals(0,
-                childCursor.getInt(childCursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-        assertFalse(childCursor.moveToNext());
-
-        final Cursor childCursor2 = mArchive.queryChildDocuments(
-                "document-id:dir1/dir2/", null, null);
-
-        assertTrue(childCursor2.moveToFirst());
-        assertEquals("document-id:dir1/dir2/cherries.txt",
-                childCursor2.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DOCUMENT_ID)));
-        assertFalse(childCursor2.moveToNext());
-    }
-
-    public void testQueryChildDocument_EmptyDirs() throws IOException {
-        loadArchive(R.raw.empty_dirs);
-        final Cursor cursor = mArchive.queryChildDocuments(DOCUMENT_ID, null, null);
-
-        assertTrue(cursor.moveToFirst());
-        assertEquals("document-id:dir1/",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("dir1",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)));
-        assertEquals(Document.MIME_TYPE_DIR,
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE)));
-        assertEquals(0,
-                cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-        assertFalse(cursor.moveToNext());
-
-        final Cursor childCursor = mArchive.queryChildDocuments("document-id:dir1/", null, null);
-
-        assertTrue(childCursor.moveToFirst());
-        assertEquals("document-id:dir1/dir2/",
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("dir2",
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DISPLAY_NAME)));
-        assertEquals(Document.MIME_TYPE_DIR,
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_MIME_TYPE)));
-        assertEquals(0,
-                childCursor.getInt(childCursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-
-        assertTrue(childCursor.moveToNext());
-        assertEquals("document-id:dir1/dir3/",
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("dir3",
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_DISPLAY_NAME)));
-        assertEquals(Document.MIME_TYPE_DIR,
-                childCursor.getString(childCursor.getColumnIndexOrThrow(
-                        Document.COLUMN_MIME_TYPE)));
-        assertEquals(0,
-                childCursor.getInt(childCursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-        assertFalse(cursor.moveToNext());
-
-        final Cursor childCursor2 = mArchive.queryChildDocuments(
-                "document-id:dir1/dir2/", null, null);
-        assertFalse(childCursor2.moveToFirst());
-
-        final Cursor childCursor3 = mArchive.queryChildDocuments(
-                "document-id:dir1/dir3/", null, null);
-        assertFalse(childCursor3.moveToFirst());
-    }
-
-    public void testGetDocumentType() throws IOException {
-        loadArchive(R.raw.archive);
-        assertEquals(Document.MIME_TYPE_DIR, mArchive.getDocumentType("document-id:dir1/"));
-        assertEquals("text/plain", mArchive.getDocumentType("document-id:file1.txt"));
-    }
-
-    public void testIsChildDocument() throws IOException {
-        loadArchive(R.raw.archive);
-        assertTrue(mArchive.isChildDocument(DOCUMENT_ID, "document-id:dir1/"));
-        assertFalse(mArchive.isChildDocument(DOCUMENT_ID, "document-id:this-does-not-exist"));
-        assertTrue(mArchive.isChildDocument("document-id:dir1/", "document-id:dir1/cherries.txt"));
-        assertTrue(mArchive.isChildDocument(DOCUMENT_ID, "document-id:dir1/cherries.txt"));
-    }
-
-    public void testQueryDocument() throws IOException {
-        loadArchive(R.raw.archive);
-        final Cursor cursor = mArchive.queryDocument("document-id:dir2/strawberries.txt", null);
-
-        assertTrue(cursor.moveToFirst());
-        assertEquals("document-id:dir2/strawberries.txt",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DOCUMENT_ID)));
-        assertEquals("strawberries.txt",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_DISPLAY_NAME)));
-        assertEquals("text/plain",
-                cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE)));
-        assertEquals(21,
-                cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_SIZE)));
-    }
-
-    public void testOpenDocument() throws IOException {
-        loadArchive(R.raw.archive);
-        final ParcelFileDescriptor descriptor = mArchive.openDocument(
-                "document-id:dir2/strawberries.txt", "r", null /* signal */);
-        try (final ParcelFileDescriptor.AutoCloseInputStream inputStream =
-                new ParcelFileDescriptor.AutoCloseInputStream(descriptor)) {
-            assertEquals("I love strawberries!", new Scanner(inputStream).nextLine());
-        }
-    }
-}
diff --git a/documents-archive/tests/src/android/support/provider/IntegrationTest.java b/documents-archive/tests/src/android/support/provider/IntegrationTest.java
deleted file mode 100644
index 0445d82..0000000
--- a/documents-archive/tests/src/android/support/provider/IntegrationTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.provider.tests;
-
-import android.content.ContentProviderClient;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.provider.DocumentsContract.Document;
-import android.provider.DocumentsContract;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.IllegalArgumentException;
-import java.util.Scanner;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * Integration tests for DocumentsProvider and DocumentArchiveHelper.
- *
- * <p>Only checks if the provider, then helper are forwarding the calls to the
- * underlying {@code ArchiveDocument} correctly. More detailed output testing is
- * done in {@code DocumentArchiveTest}.
- */
-public class IntegrationTest extends AndroidTestCase {
-    private ContentProviderClient mClient;
-
-    @Override
-    public void setUp() throws RemoteException {
-        mClient = getContext().getContentResolver().acquireContentProviderClient(
-                StubProvider.AUTHORITY);
-        assertNotNull(mClient);
-        mClient.call("reset", null, null);
-    }
-
-    @Override
-    public void tearDown() {
-        if (mClient != null) {
-            mClient.release();
-            mClient = null;
-        }
-    }
-
-    public void testQueryForChildren() throws IOException {
-        final Cursor cursor = mContext.getContentResolver().query(
-                DocumentsContract.buildChildDocumentsUri(
-                        StubProvider.AUTHORITY, StubProvider.DOCUMENT_ID),
-                        null, null, null, null);
-        assertEquals(3, cursor.getCount());
-    }
-
-    public void testQueryForDocument_Archive()
-            throws IOException, RemoteException, InterruptedException {
-        final Cursor cursor = mContext.getContentResolver().query(
-                DocumentsContract.buildDocumentUri(
-                        StubProvider.AUTHORITY, StubProvider.DOCUMENT_ID),
-                        null, null, null, null);
-        assertEquals(1, cursor.getCount());
-        assertTrue(cursor.moveToFirst());
-        assertEquals(Document.FLAG_ARCHIVE,
-                cursor.getInt(cursor.getColumnIndexOrThrow(Document.COLUMN_FLAGS)));
-    }
-
-    public void testQueryForDocument_ArchiveDescendant()
-            throws IOException, RemoteException, InterruptedException {
-        final Cursor cursor = mContext.getContentResolver().query(
-                DocumentsContract.buildDocumentUri(
-                        StubProvider.AUTHORITY, StubProvider.FILE_DOCUMENT_ID),
-                        null, null, null, null);
-        assertEquals(1, cursor.getCount());
-        assertEquals(StubProvider.NOTIFY_URI, cursor.getNotificationUri());
-
-        final CountDownLatch changeSignal = new CountDownLatch(1);
-        final ContentObserver observer = new ContentObserver(null) {
-            @Override
-            public void onChange(boolean selfChange) {
-                changeSignal.countDown();
-            }
-        };
-
-        try {
-            getContext().getContentResolver().registerContentObserver(
-                    cursor.getNotificationUri(), false /* notifyForDescendants */, observer);
-
-            // Simulate deleting the archive file, then confirm that the notification is
-            // propagated and the archive closed.
-            mClient.call("delete", null, null);
-            changeSignal.await();
-
-            mContext.getContentResolver().query(
-                    DocumentsContract.buildChildDocumentsUri(
-                            StubProvider.AUTHORITY, StubProvider.FILE_DOCUMENT_ID),
-                            null, null, null, null);
-            fail("Expected IllegalStateException, but succeeded.");
-        } catch (IllegalStateException e) {
-            // Expected, as the file is gone.
-        } finally {
-            getContext().getContentResolver().unregisterContentObserver(observer);
-        }
-    }
-
-    public void testGetType() throws IOException {
-        assertEquals("text/plain", mContext.getContentResolver().getType(
-                DocumentsContract.buildDocumentUri(
-                        StubProvider.AUTHORITY, StubProvider.FILE_DOCUMENT_ID)));
-    }
-
-    public void testOpenFileDescriptor() throws IOException {
-        final ParcelFileDescriptor descriptor = mContext.getContentResolver().openFileDescriptor(
-                DocumentsContract.buildDocumentUri(
-                        StubProvider.AUTHORITY, StubProvider.FILE_DOCUMENT_ID),
-                        "r", null);
-        assertNotNull(descriptor);
-    }
-}
diff --git a/documents-archive/tests/src/android/support/provider/StubProvider.java b/documents-archive/tests/src/android/support/provider/StubProvider.java
deleted file mode 100644
index 3f72cd2..0000000
--- a/documents-archive/tests/src/android/support/provider/StubProvider.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.provider.tests;
-
-import android.database.Cursor;
-import android.database.MatrixCursor.RowBuilder;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.os.ParcelFileDescriptor;
-import android.provider.DocumentsContract.Document;
-import android.provider.DocumentsContract;
-import android.provider.DocumentsProvider;
-import android.support.provider.DocumentArchiveHelper;
-import android.util.Log;
-
-import java.io.FileNotFoundException;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Stub provider for testing support for archives.
- */
-public class StubProvider extends DocumentsProvider {
-    public static final String AUTHORITY = "android.support.provider.tests.mystubprovider";
-    public static final String DOCUMENT_ID = "document-id";
-    public static final String FILE_DOCUMENT_ID = "document-id:dir1/cherries.txt";
-    public static final Uri NOTIFY_URI = DocumentsContract.buildRootsUri(AUTHORITY);
-
-    private static final String TAG = "StubProvider";
-    private static final String[] DEFAULT_PROJECTION = new String[] {
-            Document.COLUMN_DOCUMENT_ID, Document.COLUMN_DISPLAY_NAME, Document.COLUMN_SIZE,
-            Document.COLUMN_MIME_TYPE, Document.COLUMN_FLAGS,
-            DocumentArchiveHelper.COLUMN_LOCAL_FILE_PATH
-    };
-
-    public File file;
-    public DocumentArchiveHelper archiveHelper;
-    public boolean simulatedDelete = false;
-
-    @Override
-    public Bundle call(String method, String args, Bundle extras) {
-        switch (method) {
-            case "reset":
-                simulatedDelete = false;
-                getContext().getContentResolver().notifyChange(NOTIFY_URI, null);
-                return null;
-            case "delete":
-                simulatedDelete = true;
-                getContext().getContentResolver().notifyChange(NOTIFY_URI, null);
-                return null;
-            default:
-                return super.call(method, args, extras);
-        }
-    }
-
-    @Override
-    public boolean onCreate() {
-        try {
-            archiveHelper = new DocumentArchiveHelper(this, ':');
-            file = TestUtils.createFileFromResource(getContext(), R.raw.archive);
-            return true;
-        } catch (IOException e) {
-            Log.e(TAG, "Failed to initialize StubProvider.");
-            return false;
-        }
-    }
-
-    @Override
-    public ParcelFileDescriptor openDocument(
-            String documentId, String mode, CancellationSignal signal)
-            throws FileNotFoundException {
-        if (archiveHelper.isArchivedDocument(documentId)) {
-            return archiveHelper.openDocument(documentId, mode, signal);
-        }
-
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Cursor queryChildDocuments(
-            String parentDocumentId, String[] projection, String sortOrder)
-            throws FileNotFoundException {
-        if (archiveHelper.isArchivedDocument(parentDocumentId) ||
-                archiveHelper.isSupportedArchiveType(getDocumentType(parentDocumentId))) {
-            return archiveHelper.queryChildDocuments(parentDocumentId, projection, sortOrder);
-        }
-
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Cursor queryDocument(String documentId, String[] projection)
-            throws FileNotFoundException {
-        if (archiveHelper.isArchivedDocument(documentId)) {
-            return archiveHelper.queryDocument(documentId, projection);
-        }
-
-        if (DOCUMENT_ID.equals(documentId)) {
-            if (simulatedDelete) {
-                throw new FileNotFoundException();
-            }
-
-            final MatrixCursor result = new MatrixCursor(
-                    projection != null ? projection : DEFAULT_PROJECTION);
-            result.setNotificationUri(getContext().getContentResolver(), NOTIFY_URI);
-            final RowBuilder row = result.newRow();
-            row.add(Document.COLUMN_DOCUMENT_ID, DOCUMENT_ID);
-            row.add(Document.COLUMN_DISPLAY_NAME, file.getName());
-            row.add(Document.COLUMN_SIZE, file.length());
-            row.add(Document.COLUMN_MIME_TYPE, "application/zip");
-            final int flags = archiveHelper.isSupportedArchiveType("application/zip")
-                    ? Document.FLAG_ARCHIVE : 0;
-            row.add(Document.COLUMN_FLAGS, flags);
-            row.add(DocumentArchiveHelper.COLUMN_LOCAL_FILE_PATH, file.getPath());
-            return result;
-        }
-
-        throw new FileNotFoundException();
-    }
-
-    @Override
-    public Cursor queryRoots(String[] projection) throws FileNotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getDocumentType(String documentId) throws FileNotFoundException {
-        if (archiveHelper.isArchivedDocument(documentId)) {
-            return archiveHelper.getDocumentType(documentId);
-        }
-
-        if (DOCUMENT_ID.equals(documentId)) {
-            return "application/zip";
-        }
-
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/documents-archive/tests/src/android/support/provider/TestUtils.java b/documents-archive/tests/src/android/support/provider/TestUtils.java
deleted file mode 100644
index 17ec3e1..0000000
--- a/documents-archive/tests/src/android/support/provider/TestUtils.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.provider.tests;
-
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Utilities for tests.
- */
-final class TestUtils {
-    /**
-     * Saves a file from resources to a temporary location and returns a File instance for it.
-     *
-     * @param id Resource ID
-     */
-    static File createFileFromResource(Context context, int id) throws IOException {
-        final File file = File.createTempFile("android.support.provider.tests{",
-                "}.zip", context.getCacheDir());
-        try (
-            final FileOutputStream outputStream =
-                    new ParcelFileDescriptor.AutoCloseOutputStream(
-                            ParcelFileDescriptor.open(
-                                    file, ParcelFileDescriptor.MODE_WRITE_ONLY));
-            final InputStream inputStream = context.getResources().openRawResource(id);
-        ) {
-            final byte[] buffer = new byte[32 * 1024];
-            int bytes;
-            while ((bytes = inputStream.read(buffer)) != -1) {
-                outputStream.write(buffer, 0, bytes);
-            }
-            outputStream.flush();
-            return file;
-        }
-    }
-}
diff --git a/exifinterface/Android.mk b/exifinterface/Android.mk
index 4d5887c..9da8bc5 100644
--- a/exifinterface/Android.mk
+++ b/exifinterface/Android.mk
@@ -25,7 +25,6 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-annotations
 LOCAL_JAR_EXCLUDE_FILES := none
diff --git a/exifinterface/AndroidManifest-make.xml b/exifinterface/AndroidManifest-make.xml
deleted file mode 100644
index 4812a71..0000000
--- a/exifinterface/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.exifinterface">
-    <uses-sdk android:minSdkVersion="9"/>
-    <application />
-</manifest>
diff --git a/exifinterface/AndroidManifest.xml b/exifinterface/AndroidManifest.xml
index bacbdbe..94b3300 100644
--- a/exifinterface/AndroidManifest.xml
+++ b/exifinterface/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.exifinterface">
-    <uses-sdk android:minSdkVersion="9"/>
+    <uses-sdk android:minSdkVersion="14"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/exifinterface/build.gradle b/exifinterface/build.gradle
index c761832..583ed93 100644
--- a/exifinterface/build.gradle
+++ b/exifinterface/build.gradle
@@ -1,84 +1,27 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'exifinterface'
 
 dependencies {
     compile project(':support-annotations')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = ['src']
         main.res.srcDirs = ['res']
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support ExifInterface'
-                description "Android Support ExifInterface"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2016'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support ExifInterface'
+    inceptionYear '2016'
+    description 'Android Support ExifInterface'
 }
diff --git a/fragment/Android.mk b/fragment/Android.mk
index f55cfb7..399b5d9 100644
--- a/fragment/Android.mk
+++ b/fragment/Android.mk
@@ -30,18 +30,15 @@
 LOCAL_MODULE := android-support-fragment
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := \
-    $(call all-java-files-under, gingerbread) \
-    $(call all-java-files-under, honeycomb) \
+    $(call all-java-files-under, api14) \
     $(call all-java-files-under, jellybean) \
     $(call all-java-files-under, api21) \
     $(call all-java-files-under, java)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-core-ui \
     android-support-core-utils \
-    android-support-media-compat \
     android-support-annotations
 LOCAL_JAR_EXCLUDE_FILES := none
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
diff --git a/fragment/AndroidManifest-make.xml b/fragment/AndroidManifest-make.xml
deleted file mode 100644
index 54e61d3..0000000
--- a/fragment/AndroidManifest-make.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.support.fragment">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.fragment"/>
-    <application />
-</manifest>
diff --git a/fragment/AndroidManifest.xml b/fragment/AndroidManifest.xml
index 9b34e14..c6fdcc4 100644
--- a/fragment/AndroidManifest.xml
+++ b/fragment/AndroidManifest.xml
@@ -16,7 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.fragment">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.fragment"/>
+    <uses-sdk android:minSdkVersion="14" tools:overrideLibrary="android.support.fragment"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/fragment/gingerbread/android/support/v4/app/BaseFragmentActivityGingerbread.java b/fragment/api14/android/support/v4/app/BaseFragmentActivityApi14.java
similarity index 78%
rename from fragment/gingerbread/android/support/v4/app/BaseFragmentActivityGingerbread.java
rename to fragment/api14/android/support/v4/app/BaseFragmentActivityApi14.java
index 01e9f22..f60d6ce 100644
--- a/fragment/gingerbread/android/support/v4/app/BaseFragmentActivityGingerbread.java
+++ b/fragment/api14/android/support/v4/app/BaseFragmentActivityApi14.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -16,25 +16,16 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender;
-import android.os.Build;
-import android.os.Bundle;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
 import android.util.AttributeSet;
 import android.view.View;
 
-/**
- * Base class for {@code FragmentActivity} to be able to use Gingerbread APIs.
- *
- * @hide
- */
-@RequiresApi(9)
-@TargetApi(9)
-abstract class BaseFragmentActivityGingerbread extends SupportActivity {
+@RequiresApi(14)
+abstract class BaseFragmentActivityApi14 extends SupportActivity {
 
     // We need to keep track of whether startIntentSenderForResult originated from a Fragment, so we
     // can conditionally check whether the requestCode collides with our reserved ID space for the
@@ -44,14 +35,12 @@
     boolean mStartedIntentSenderFromFragment;
 
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        if (Build.VERSION.SDK_INT < 11 && getLayoutInflater().getFactory() == null) {
-            // On pre-HC devices we need to manually install ourselves as a Factory.
-            // On HC and above, we are automatically installed as a private factory
-            getLayoutInflater().setFactory(this);
+    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
+        final View v = dispatchFragmentsOnCreateView(parent, name, context, attrs);
+        if (v == null) {
+            return super.onCreateView(parent, name, context, attrs);
         }
-
-        super.onCreate(savedInstanceState);
+        return v;
     }
 
     @Override
@@ -66,7 +55,6 @@
     abstract View dispatchFragmentsOnCreateView(View parent, String name,
             Context context, AttributeSet attrs);
 
-
     @Override
     public void startIntentSenderForResult(IntentSender intent, int requestCode,
             @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
diff --git a/fragment/api21/android/support/v4/app/FragmentTransitionCompat21.java b/fragment/api21/android/support/v4/app/FragmentTransitionCompat21.java
index 879be4a..6fce8d5 100644
--- a/fragment/api21/android/support/v4/app/FragmentTransitionCompat21.java
+++ b/fragment/api21/android/support/v4/app/FragmentTransitionCompat21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.app;
 
-import android.annotation.TargetApi;
 import android.graphics.Rect;
 import android.support.annotation.RequiresApi;
 import android.transition.Transition;
@@ -30,7 +29,6 @@
 import java.util.Map;
 
 @RequiresApi(21)
-@TargetApi(21)
 class FragmentTransitionCompat21 {
 
     /**
diff --git a/fragment/build.gradle b/fragment/build.gradle
index 7c9098a..574cc2d 100644
--- a/fragment/build.gradle
+++ b/fragment/build.gradle
@@ -1,102 +1,40 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'support-fragment'
 
 dependencies {
     compile project(':support-compat')
-    compile project(':support-media-compat')
     compile project(':support-core-ui')
     compile project(':support-core-utils')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile 'org.mockito:mockito-core:1.9.5'
-    androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
-    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
-    testCompile 'junit:junit:4.12'
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
-                'gingerbread',
-                'honeycomb',
+                'api14',
                 'jellybean',
                 'api21',
                 'java'
         ]
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/java'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-        exclude('android/content/pm/**')
-        exclude('android/service/media/**')
-    }
-
-    artifacts.add('archives', sourcesJarTask);
+supportLibrary {
+    name 'Android Support Library v4'
+    inceptionYear '2011'
+    description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 4 or later."
 }
 
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Library v4'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/fragment/honeycomb/android/support/v4/app/BaseFragmentActivityHoneycomb.java b/fragment/honeycomb/android/support/v4/app/BaseFragmentActivityHoneycomb.java
deleted file mode 100644
index 95f3d8d..0000000
--- a/fragment/honeycomb/android/support/v4/app/BaseFragmentActivityHoneycomb.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-import android.content.Context;
-import android.os.Build;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Base class for {@code FragmentActivity} to be able to use v11 APIs.
- *
- * @hide
- */
-abstract class BaseFragmentActivityHoneycomb extends BaseFragmentActivityGingerbread {
-
-    @Override
-    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
-        final View v = dispatchFragmentsOnCreateView(parent, name, context, attrs);
-        if (v == null && Build.VERSION.SDK_INT >= 11) {
-            // If we're running on HC or above, let the super have a go
-            return super.onCreateView(parent, name, context, attrs);
-        }
-        return v;
-    }
-
-}
diff --git a/fragment/java/android/support/v4/app/BackStackRecord.java b/fragment/java/android/support/v4/app/BackStackRecord.java
index 326521a..0debe7a 100644
--- a/fragment/java/android/support/v4/app/BackStackRecord.java
+++ b/fragment/java/android/support/v4/app/BackStackRecord.java
@@ -186,6 +186,8 @@
     static final int OP_SHOW = 5;
     static final int OP_DETACH = 6;
     static final int OP_ATTACH = 7;
+    static final int OP_SET_PRIMARY_NAV = 8;
+    static final int OP_UNSET_PRIMARY_NAV = 9;
 
     static final class Op {
         int cmd;
@@ -194,6 +196,14 @@
         int exitAnim;
         int popEnterAnim;
         int popExitAnim;
+
+        Op() {
+        }
+
+        Op(int cmd, Fragment fragment) {
+            this.cmd = cmd;
+            this.fragment = fragment;
+        }
     }
 
     ArrayList<Op> mOps = new ArrayList<>();
@@ -218,6 +228,8 @@
     ArrayList<String> mSharedElementTargetNames;
     boolean mAllowOptimization = false;
 
+    ArrayList<Runnable> mCommitRunnables;
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(128);
@@ -292,6 +304,8 @@
                     case OP_SHOW: cmdStr="SHOW"; break;
                     case OP_DETACH: cmdStr="DETACH"; break;
                     case OP_ATTACH: cmdStr="ATTACH"; break;
+                    case OP_SET_PRIMARY_NAV: cmdStr="SET_PRIMARY_NAV"; break;
+                    case OP_UNSET_PRIMARY_NAV: cmdStr="UNSET_PRIMARY_NAV";break;
                     default: cmdStr="cmd=" + op.cmd; break;
                 }
                 writer.print(prefix); writer.print("  Op #"); writer.print(opNum);
@@ -410,10 +424,7 @@
             fragment.mContainerId = fragment.mFragmentId = containerViewId;
         }
 
-        Op op = new Op();
-        op.cmd = opcmd;
-        op.fragment = fragment;
-        addOp(op);
+        addOp(new Op(opcmd, fragment));
     }
 
     @Override
@@ -433,50 +444,42 @@
 
     @Override
     public FragmentTransaction remove(Fragment fragment) {
-        Op op = new Op();
-        op.cmd = OP_REMOVE;
-        op.fragment = fragment;
-        addOp(op);
+        addOp(new Op(OP_REMOVE, fragment));
 
         return this;
     }
 
     @Override
     public FragmentTransaction hide(Fragment fragment) {
-        Op op = new Op();
-        op.cmd = OP_HIDE;
-        op.fragment = fragment;
-        addOp(op);
+        addOp(new Op(OP_HIDE, fragment));
 
         return this;
     }
 
     @Override
     public FragmentTransaction show(Fragment fragment) {
-        Op op = new Op();
-        op.cmd = OP_SHOW;
-        op.fragment = fragment;
-        addOp(op);
+        addOp(new Op(OP_SHOW, fragment));
 
         return this;
     }
 
     @Override
     public FragmentTransaction detach(Fragment fragment) {
-        Op op = new Op();
-        op.cmd = OP_DETACH;
-        op.fragment = fragment;
-        addOp(op);
+        addOp(new Op(OP_DETACH, fragment));
 
         return this;
     }
 
     @Override
     public FragmentTransaction attach(Fragment fragment) {
-        Op op = new Op();
-        op.cmd = OP_ATTACH;
-        op.fragment = fragment;
-        addOp(op);
+        addOp(new Op(OP_ATTACH, fragment));
+
+        return this;
+    }
+
+    @Override
+    public FragmentTransaction setPrimaryNavigationFragment(Fragment fragment) {
+        addOp(new Op(OP_SET_PRIMARY_NAV, fragment));
 
         return this;
     }
@@ -605,6 +608,28 @@
     }
 
     @Override
+    public FragmentTransaction postOnCommit(Runnable runnable) {
+        if (runnable == null) {
+            throw new IllegalArgumentException("runnable cannot be null");
+        }
+        disallowAddToBackStack();
+        if (mCommitRunnables == null) {
+            mCommitRunnables = new ArrayList<>();
+        }
+        mCommitRunnables.add(runnable);
+        return this;
+    }
+
+    public void runOnCommitRunnables() {
+        if (mCommitRunnables != null) {
+            for (int i = 0, N = mCommitRunnables.size(); i < N; i++) {
+                mCommitRunnables.get(i).run();
+            }
+            mCommitRunnables = null;
+        }
+    }
+
+    @Override
     public int commit() {
         return commitInternal(false);
     }
@@ -678,7 +703,8 @@
         final int numOps = mOps.size();
         for (int opNum = 0; opNum < numOps; opNum++) {
             final Op op = mOps.get(opNum);
-            if (op.fragment.mContainerId == containerId) {
+            final int fragContainer = op.fragment != null ? op.fragment.mContainerId : 0;
+            if (fragContainer != 0 && fragContainer == containerId) {
                 return true;
             }
         }
@@ -693,7 +719,7 @@
         int lastContainer = -1;
         for (int opNum = 0; opNum < numOps; opNum++) {
             final Op op = mOps.get(opNum);
-            final int container = op.fragment.mContainerId;
+            final int container = op.fragment != null ? op.fragment.mContainerId : 0;
             if (container != 0 && container != lastContainer) {
                 lastContainer = container;
                 for (int i = startIndex; i < endIndex; i++) {
@@ -701,7 +727,9 @@
                     final int numThoseOps = record.mOps.size();
                     for (int thoseOpIndex = 0; thoseOpIndex < numThoseOps; thoseOpIndex++) {
                         final Op thatOp = record.mOps.get(thoseOpIndex);
-                        if (thatOp.fragment.mContainerId == container) {
+                        final int thatContainer = thatOp.fragment != null
+                                ? thatOp.fragment.mContainerId : 0;
+                        if (thatContainer == container) {
                             return true;
                         }
                     }
@@ -720,7 +748,9 @@
         for (int opNum = 0; opNum < numOps; opNum++) {
             final Op op = mOps.get(opNum);
             final Fragment f = op.fragment;
-            f.setNextTransition(mTransition, mTransitionStyle);
+            if (f != null) {
+                f.setNextTransition(mTransition, mTransitionStyle);
+            }
             switch (op.cmd) {
                 case OP_ADD:
                     f.setNextAnim(op.enterAnim);
@@ -746,10 +776,16 @@
                     f.setNextAnim(op.enterAnim);
                     mManager.attachFragment(f);
                     break;
+                case OP_SET_PRIMARY_NAV:
+                    mManager.setPrimaryNavigationFragment(f);
+                    break;
+                case OP_UNSET_PRIMARY_NAV:
+                    mManager.setPrimaryNavigationFragment(null);
+                    break;
                 default:
                     throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
             }
-            if (!mAllowOptimization && op.cmd != OP_ADD) {
+            if (!mAllowOptimization && op.cmd != OP_ADD && f != null) {
                 mManager.moveFragmentToExpectedState(f);
             }
         }
@@ -767,7 +803,10 @@
         for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
             final Op op = mOps.get(opNum);
             Fragment f = op.fragment;
-            f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
+            if (f != null) {
+                f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition),
+                        mTransitionStyle);
+            }
             switch (op.cmd) {
                 case OP_ADD:
                     f.setNextAnim(op.popExitAnim);
@@ -793,10 +832,16 @@
                     f.setNextAnim(op.popExitAnim);
                     mManager.detachFragment(f);
                     break;
+                case OP_SET_PRIMARY_NAV:
+                    mManager.setPrimaryNavigationFragment(null);
+                    break;
+                case OP_UNSET_PRIMARY_NAV:
+                    mManager.setPrimaryNavigationFragment(f);
+                    break;
                 default:
                     throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
             }
-            if (!mAllowOptimization && op.cmd != OP_REMOVE) {
+            if (!mAllowOptimization && op.cmd != OP_REMOVE && f != null) {
                 mManager.moveFragmentToExpectedState(f);
             }
         }
@@ -806,15 +851,28 @@
     }
 
     /**
-     * Removes all OP_REPLACE ops and replaces them with the proper add and remove
-     * operations that are equivalent to the replace. This must be called prior to
-     * {@link #executeOps()} or any other call that operations on mOps.
+     * Expands all meta-ops into their more primitive equivalents. This must be called prior to
+     * {@link #executeOps()} or any other call that operations on mOps for forward navigation.
+     * It should not be called for pop/reverse navigation operations.
+     *
+     * <p>Removes all OP_REPLACE ops and replaces them with the proper add and remove
+     * operations that are equivalent to the replace.</p>
+     *
+     * <p>Adds OP_UNSET_PRIMARY_NAV ops to match OP_SET_PRIMARY_NAV, OP_REMOVE and OP_DETACH
+     * ops so that we can restore the old primary nav fragment later. Since callers call this
+     * method in a loop before running ops from several transactions at once, the caller should
+     * pass the return value from this method as the oldPrimaryNav parameter for the next call.
+     * The first call in such a loop should pass the value of
+     * {@link FragmentManager#getPrimaryNavigationFragment()}.</p>
      *
      * @param added Initialized to the fragments that are in the mManager.mAdded, this
      *              will be modified to contain the fragments that will be in mAdded
      *              after the execution ({@link #executeOps()}.
+     * @param oldPrimaryNav The tracked primary navigation fragment as of the beginning of
+     *                      this set of ops
+     * @return the new oldPrimaryNav fragment after this record's ops would be run
      */
-    void expandReplaceOps(ArrayList<Fragment> added) {
+    Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
         for (int opNum = 0; opNum < mOps.size(); opNum++) {
             final Op op = mOps.get(opNum);
             switch (op.cmd) {
@@ -823,22 +881,33 @@
                     added.add(op.fragment);
                     break;
                 case OP_REMOVE:
-                case OP_DETACH:
+                case OP_DETACH: {
                     added.remove(op.fragment);
-                    break;
+                    if (op.fragment == oldPrimaryNav) {
+                        mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.fragment));
+                        opNum++;
+                        oldPrimaryNav = null;
+                    }
+                }
+                break;
                 case OP_REPLACE: {
-                    Fragment f = op.fragment;
-                    int containerId = f.mContainerId;
+                    final Fragment f = op.fragment;
+                    final int containerId = f.mContainerId;
                     boolean alreadyAdded = false;
                     for (int i = added.size() - 1; i >= 0; i--) {
-                        Fragment old = added.get(i);
+                        final Fragment old = added.get(i);
                         if (old.mContainerId == containerId) {
                             if (old == f) {
                                 alreadyAdded = true;
                             } else {
-                                Op removeOp = new Op();
-                                removeOp.cmd = OP_REMOVE;
-                                removeOp.fragment = old;
+                                // This is duplicated from above since we only make
+                                // a single pass for expanding ops. Unset any outgoing primary nav.
+                                if (old == oldPrimaryNav) {
+                                    mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, old));
+                                    opNum++;
+                                    oldPrimaryNav = null;
+                                }
+                                final Op removeOp = new Op(OP_REMOVE, old);
                                 removeOp.enterAnim = op.enterAnim;
                                 removeOp.popEnterAnim = op.popEnterAnim;
                                 removeOp.exitAnim = op.exitAnim;
@@ -858,8 +927,18 @@
                     }
                 }
                 break;
+                case OP_SET_PRIMARY_NAV: {
+                    // It's ok if this is null, that means we will restore to no active
+                    // primary navigation fragment on a pop.
+                    mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, oldPrimaryNav));
+                    opNum++;
+                    // Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
+                    oldPrimaryNav = op.fragment;
+                }
+                break;
             }
         }
+        return oldPrimaryNav;
     }
 
     /**
@@ -868,8 +947,11 @@
      * @param added Initialized to the fragments that are in the mManager.mAdded, this
      *              will be modified to contain the fragments that will be in mAdded
      *              after the execution ({@link #executeOps()}.
+     * @param oldPrimaryNav The tracked primary navigation fragment as of the beginning of
+     *                      this set of ops
+     * @return the new oldPrimaryNav fragment after this record's ops would be popped
      */
-    void trackAddedFragmentsInPop(ArrayList<Fragment> added) {
+    Fragment trackAddedFragmentsInPop(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
         for (int opNum = 0; opNum < mOps.size(); opNum++) {
             final Op op = mOps.get(opNum);
             switch (op.cmd) {
@@ -881,8 +963,15 @@
                 case OP_DETACH:
                     added.add(op.fragment);
                     break;
+                case OP_UNSET_PRIMARY_NAV:
+                    oldPrimaryNav = op.fragment;
+                    break;
+                case OP_SET_PRIMARY_NAV:
+                    oldPrimaryNav = null;
+                    break;
             }
         }
+        return oldPrimaryNav;
     }
 
     boolean isPostponed() {
@@ -906,8 +995,8 @@
 
     private static boolean isFragmentPostponed(Op op) {
         final Fragment fragment = op.fragment;
-        return (fragment.mAdded && fragment.mView != null && !fragment.mDetached
-                && !fragment.mHidden && fragment.isPostponed());
+        return fragment != null && fragment.mAdded && fragment.mView != null && !fragment.mDetached
+                && !fragment.mHidden && fragment.isPostponed();
     }
 
     @Override
diff --git a/fragment/java/android/support/v4/app/Fragment.java b/fragment/java/android/support/v4/app/Fragment.java
index 06d0b1e..297d4bf 100644
--- a/fragment/java/android/support/v4/app/Fragment.java
+++ b/fragment/java/android/support/v4/app/Fragment.java
@@ -98,15 +98,19 @@
         mSavedFragmentState = in.readBundle();
     }
 
-    public Fragment instantiate(FragmentHostCallback host, Fragment parent,
-            FragmentManagerNonConfig childNonConfig) {
+    public Fragment instantiate(FragmentHostCallback host, FragmentContainer container,
+            Fragment parent, FragmentManagerNonConfig childNonConfig) {
         if (mInstance == null) {
             final Context context = host.getContext();
             if (mArguments != null) {
                 mArguments.setClassLoader(context.getClassLoader());
             }
 
-            mInstance = Fragment.instantiate(context, mClassName, mArguments);
+            if (container != null) {
+                mInstance = container.instantiate(context, mClassName, mArguments);
+            } else {
+                mInstance = Fragment.instantiate(context, mClassName, mArguments);
+            }
 
             if (mSavedFragmentState != null) {
                 mSavedFragmentState.setClassLoader(context.getClassLoader());
@@ -231,6 +235,10 @@
     // True if this fragment has been restored from previously saved state.
     boolean mRestored;
 
+    // True if performCreateView has been called and a matching call to performDestroyView
+    // has not yet happened.
+    boolean mPerformedCreateView;
+
     // Number of active back stack entries this fragment is in.
     int mBackStackNesting;
 
@@ -430,7 +438,7 @@
             Fragment f = (Fragment)clazz.newInstance();
             if (args != null) {
                 args.setClassLoader(f.getClass().getClassLoader());
-                f.mArguments = args;
+                f.setArguments(args);
             }
             return f;
         } catch (ClassNotFoundException e) {
@@ -547,15 +555,15 @@
     }
     
     /**
-     * Supply the construction arguments for this fragment.  This can only
-     * be called before the fragment has been attached to its activity; that
-     * is, you should call it immediately after constructing the fragment.  The
-     * arguments supplied here will be retained across fragment destroy and
+     * Supply the construction arguments for this fragment.
+     * The arguments supplied here will be retained across fragment destroy and
      * creation.
+     * <p>This method cannot be called if the fragment is added to a FragmentManager and
+     * if {@link #isStateSaved()} would return true.</p>
      */
     public void setArguments(Bundle args) {
-        if (mIndex >= 0) {
-            throw new IllegalStateException("Fragment already active");
+        if (mIndex >= 0 && isStateSaved()) {
+            throw new IllegalStateException("Fragment already active and state has been saved");
         }
         mArguments = args;
     }
@@ -569,6 +577,21 @@
     }
 
     /**
+     * Returns true if this fragment is added and its state has already been saved
+     * by its host. Any operations that would change saved state should not be performed
+     * if this method returns true, and some operations such as {@link #setArguments(Bundle)}
+     * will fail.
+     *
+     * @return true if this fragment's state has already been saved by its host
+     */
+    public final boolean isStateSaved() {
+        if (mFragmentManager == null) {
+            return false;
+        }
+        return mFragmentManager.isStateSaved();
+    }
+
+    /**
      * Set the initial saved state that this Fragment should restore itself
      * from when first being constructed, as returned by
      * {@link FragmentManager#saveFragmentInstanceState(Fragment)
@@ -596,6 +619,24 @@
      * are going to call back with {@link #onActivityResult(int, int, Intent)}.
      */
     public void setTargetFragment(Fragment fragment, int requestCode) {
+        // Don't allow a caller to set a target fragment in another FragmentManager,
+        // but there's a snag: people do set target fragments before fragments get added.
+        // We'll have the FragmentManager check that for validity when we move
+        // the fragments to a valid state.
+        final FragmentManager mine = getFragmentManager();
+        final FragmentManager theirs = fragment != null ? fragment.getFragmentManager() : null;
+        if (mine != null && theirs != null && mine != theirs) {
+            throw new IllegalArgumentException("Fragment " + fragment
+                    + " must share the same FragmentManager to be set as a target fragment");
+        }
+
+        // Don't let someone create a cycle.
+        for (Fragment check = fragment; check != null; check = check.getTargetFragment()) {
+            if (check == this) {
+                throw new IllegalArgumentException("Setting " + fragment + " as the target of "
+                        + this + " would create a target cycle");
+            }
+        }
         mTarget = fragment;
         mTargetRequestCode = requestCode;
     }
@@ -2168,6 +2209,11 @@
             public boolean onHasView() {
                 return (mView != null);
             }
+
+            @Override
+            public Fragment instantiate(Context context, String className, Bundle arguments) {
+                return mHost.instantiate(context, className, arguments);
+            }
         }, this);
     }
 
@@ -2189,6 +2235,7 @@
         if (mChildFragmentManager != null) {
             mChildFragmentManager.noteStateNotSaved();
         }
+        mPerformedCreateView = true;
         return onCreateView(inflater, container, savedInstanceState);
     }
 
@@ -2423,6 +2470,7 @@
         if (mLoaderManager != null) {
             mLoaderManager.doReportNextStart();
         }
+        mPerformedCreateView = false;
     }
 
     void performDestroy() {
diff --git a/fragment/java/android/support/v4/app/FragmentActivity.java b/fragment/java/android/support/v4/app/FragmentActivity.java
index 0b38fd4..b565b4a 100644
--- a/fragment/java/android/support/v4/app/FragmentActivity.java
+++ b/fragment/java/android/support/v4/app/FragmentActivity.java
@@ -16,8 +16,6 @@
 
 package android.support.v4.app;
 
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.Context;
@@ -25,7 +23,6 @@
 import android.content.IntentSender;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -34,7 +31,6 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
-import android.support.v4.media.session.MediaControllerCompat;
 import android.support.v4.util.SimpleArrayMap;
 import android.support.v4.util.SparseArrayCompat;
 import android.util.AttributeSet;
@@ -49,6 +45,8 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
 /**
  * Base class for activities that want to use the support-based
  * {@link android.support.v4.app.Fragment} and
@@ -181,43 +179,6 @@
     }
 
     /**
-     * Sets a {@link MediaControllerCompat} for later retrieval via
-     * {@link #getSupportMediaController()}.
-     *
-     * <p>On API 21 and later, this controller will be tied to the window of the activity and
-     * media key and volume events which are received while the Activity is in the foreground
-     * will be forwarded to the controller and used to invoke transport controls or adjust the
-     * volume. Prior to API 21, the global handling of media key and volume events through an
-     * active {@link android.support.v4.media.session.MediaSessionCompat} and media button receiver
-     * will still be respected.</p>
-     *
-     * @param mediaController The controller for the session which should receive
-     *     media keys and volume changes on API 21 and later.
-     * @see #getSupportMediaController()
-     * @see #setMediaController(android.media.session.MediaController)
-     * @deprecated Use {@link MediaControllerCompat#setMediaController} instead. This API will be
-     * removed in a future release.
-     */
-    @Deprecated
-    final public void setSupportMediaController(MediaControllerCompat mediaController) {
-        MediaControllerCompat.setMediaController(this, mediaController);
-    }
-
-    /**
-     * Retrieves the current {@link MediaControllerCompat} for sending media key and volume events.
-     *
-     * @return The controller which should receive events.
-     * @see #setSupportMediaController(MediaControllerCompat)
-     * @see #getMediaController()
-     * @deprecated Use {@link MediaControllerCompat#getMediaController} instead. This API will be
-     * removed in a future release.
-     */
-    @Deprecated
-    final public MediaControllerCompat getSupportMediaController() {
-        return MediaControllerCompat.getMediaController(this);
-    }
-
-    /**
      * Reverses the Activity Scene entry Transition and triggers the calling Activity
      * to reverse its exit Transition. When the exit Transition completes,
      * {@link #finish()} is called. If no entry Transition was used, finish() is called
@@ -681,10 +642,7 @@
      * @param args additional arguments to the dump request.
      */
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
-        if (Build.VERSION.SDK_INT >= 11) {
-            // XXX This can only work if we can call the super-class impl. :/
-            //ActivityCompatHoneycomb.dump(this, prefix, fd, writer, args);
-        }
+        super.dump(prefix, fd, writer, args);
         writer.print(prefix); writer.print("Local FragmentActivity ");
                 writer.print(Integer.toHexString(System.identityHashCode(this)));
                 writer.println(" State:");
@@ -696,95 +654,6 @@
                 writer.println(mReallyStopped);
         mFragments.dumpLoaders(innerPrefix, fd, writer, args);
         mFragments.getSupportFragmentManager().dump(prefix, fd, writer, args);
-        writer.print(prefix); writer.println("View Hierarchy:");
-        dumpViewHierarchy(prefix + "  ", writer, getWindow().getDecorView());
-    }
-
-    private static String viewToString(View view) {
-        StringBuilder out = new StringBuilder(128);
-        out.append(view.getClass().getName());
-        out.append('{');
-        out.append(Integer.toHexString(System.identityHashCode(view)));
-        out.append(' ');
-        switch (view.getVisibility()) {
-            case View.VISIBLE: out.append('V'); break;
-            case View.INVISIBLE: out.append('I'); break;
-            case View.GONE: out.append('G'); break;
-            default: out.append('.'); break;
-        }
-        out.append(view.isFocusable() ? 'F' : '.');
-        out.append(view.isEnabled() ? 'E' : '.');
-        out.append(view.willNotDraw() ? '.' : 'D');
-        out.append(view.isHorizontalScrollBarEnabled()? 'H' : '.');
-        out.append(view.isVerticalScrollBarEnabled() ? 'V' : '.');
-        out.append(view.isClickable() ? 'C' : '.');
-        out.append(view.isLongClickable() ? 'L' : '.');
-        out.append(' ');
-        out.append(view.isFocused() ? 'F' : '.');
-        out.append(view.isSelected() ? 'S' : '.');
-        out.append(view.isPressed() ? 'P' : '.');
-        out.append(' ');
-        out.append(view.getLeft());
-        out.append(',');
-        out.append(view.getTop());
-        out.append('-');
-        out.append(view.getRight());
-        out.append(',');
-        out.append(view.getBottom());
-        final int id = view.getId();
-        if (id != View.NO_ID) {
-            out.append(" #");
-            out.append(Integer.toHexString(id));
-            final Resources r = view.getResources();
-            if (id != 0 && r != null) {
-                try {
-                    String pkgname;
-                    switch (id&0xff000000) {
-                        case 0x7f000000:
-                            pkgname="app";
-                            break;
-                        case 0x01000000:
-                            pkgname="android";
-                            break;
-                        default:
-                            pkgname = r.getResourcePackageName(id);
-                            break;
-                    }
-                    String typename = r.getResourceTypeName(id);
-                    String entryname = r.getResourceEntryName(id);
-                    out.append(" ");
-                    out.append(pkgname);
-                    out.append(":");
-                    out.append(typename);
-                    out.append("/");
-                    out.append(entryname);
-                } catch (Resources.NotFoundException e) {
-                }
-            }
-        }
-        out.append("}");
-        return out.toString();
-    }
-
-    private void dumpViewHierarchy(String prefix, PrintWriter writer, View view) {
-        writer.print(prefix);
-        if (view == null) {
-            writer.println("null");
-            return;
-        }
-        writer.println(viewToString(view));
-        if (!(view instanceof ViewGroup)) {
-            return;
-        }
-        ViewGroup grp = (ViewGroup)view;
-        final int N = grp.getChildCount();
-        if (N <= 0) {
-            return;
-        }
-        prefix = prefix + "  ";
-        for (int i=0; i<N; i++) {
-            dumpViewHierarchy(prefix, writer, grp.getChildAt(i));
-        }
     }
 
     void doReallyStop(boolean retaining) {
diff --git a/fragment/java/android/support/v4/app/FragmentContainer.java b/fragment/java/android/support/v4/app/FragmentContainer.java
index 1367540..d15953b 100644
--- a/fragment/java/android/support/v4/app/FragmentContainer.java
+++ b/fragment/java/android/support/v4/app/FragmentContainer.java
@@ -1,5 +1,7 @@
 package android.support.v4.app;
 
+import android.content.Context;
+import android.os.Bundle;
 import android.support.annotation.IdRes;
 import android.support.annotation.Nullable;
 import android.view.View;
@@ -20,4 +22,14 @@
      * Return {@code true} if the container holds any view.
      */
     public abstract boolean onHasView();
+
+
+    /**
+     * Creates an instance of the specified fragment, can be overridden to construct fragments
+     * with dependencies, or change the fragment being constructed. By default just calls
+     * {@link Fragment#instantiate(Context, String, Bundle)}.
+     */
+    public Fragment instantiate(Context context, String className, Bundle arguments) {
+        return Fragment.instantiate(context, className, arguments);
+    }
 }
diff --git a/fragment/java/android/support/v4/app/FragmentManager.java b/fragment/java/android/support/v4/app/FragmentManager.java
index 91d1d91..97c13c0 100644
--- a/fragment/java/android/support/v4/app/FragmentManager.java
+++ b/fragment/java/android/support/v4/app/FragmentManager.java
@@ -386,6 +386,18 @@
     public abstract void unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb);
 
     /**
+     * Return the currently active primary navigation fragment for this FragmentManager.
+     *
+     * <p>The primary navigation fragment's
+     * {@link Fragment#getChildFragmentManager() child FragmentManager} will be called first
+     * to process delegated navigation actions such as {@link #popBackStack()} if no ID
+     * or transaction name is provided to pop to.</p>
+     *
+     * @return the fragment designated as the primary navigation fragment
+     */
+    public abstract Fragment getPrimaryNavigationFragment();
+
+    /**
      * Print the FragmentManager's state into the given stream.
      *
      * @param prefix Text to print at the front of each line.
@@ -544,6 +556,7 @@
     FragmentState[] mActive;
     int[] mAdded;
     BackStackState[] mBackStack;
+    int mPrimaryNavActiveIndex = -1;
 
     public FragmentManagerState() {
     }
@@ -552,6 +565,7 @@
         mActive = in.createTypedArray(FragmentState.CREATOR);
         mAdded = in.createIntArray();
         mBackStack = in.createTypedArray(BackStackState.CREATOR);
+        mPrimaryNavActiveIndex = in.readInt();
     }
 
     @Override
@@ -564,6 +578,7 @@
         dest.writeTypedArray(mActive, flags);
         dest.writeIntArray(mAdded);
         dest.writeTypedArray(mBackStack, flags);
+        dest.writeInt(mPrimaryNavActiveIndex);
     }
 
     public static final Parcelable.Creator<FragmentManagerState> CREATOR
@@ -642,11 +657,11 @@
                     mView.post(new Runnable() {
                         @Override
                         public void run() {
-                            ViewCompat.setLayerType(mView, ViewCompat.LAYER_TYPE_NONE, null);
+                            mView.setLayerType(View.LAYER_TYPE_NONE, null);
                         }
                     });
                 } else {
-                    ViewCompat.setLayerType(mView, ViewCompat.LAYER_TYPE_NONE, null);
+                    mView.setLayerType(View.LAYER_TYPE_NONE, null);
                 }
             }
             if (mOriginalListener != null) {
@@ -683,6 +698,7 @@
     FragmentHostCallback mHost;
     FragmentContainer mContainer;
     Fragment mParent;
+    Fragment mPrimaryNav;
 
     static Field sAnimationListenerField = null;
 
@@ -727,7 +743,7 @@
 
     static boolean shouldRunOnHWLayer(View v, Animation anim) {
         return Build.VERSION.SDK_INT >= 19
-                && ViewCompat.getLayerType(v) == ViewCompat.LAYER_TYPE_NONE
+                && v.getLayerType() == View.LAYER_TYPE_NONE
                 && ViewCompat.hasOverlappingRendering(v)
                 && modifiesAlpha(anim);
     }
@@ -816,6 +832,16 @@
         execPendingActions();
         ensureExecReady(true);
 
+        if (mPrimaryNav != null // We have a primary nav fragment
+                && id < 0 // No valid id (since they're local)
+                && name == null) { // no name to pop to (since they're local)
+            final FragmentManager childManager = mPrimaryNav.peekChildFragmentManager();
+            if (childManager != null && childManager.popBackStackImmediate()) {
+                // We did something, just not to this specific FragmentManager. Return true.
+                return true;
+            }
+        }
+
         boolean executePop = popBackStackState(mTmpRecords, mTmpIsPop, name, id, flags);
         if (executePop) {
             mExecutingActions = true;
@@ -884,7 +910,11 @@
 
     @Override
     public List<Fragment> getFragments() {
-        return mActive;
+        List<Fragment> result = new ArrayList<>();
+        if (mActive != null) {
+            result.addAll(mActive);
+        }
+        return result;
     }
 
     @Override
@@ -1160,7 +1190,7 @@
             // If there's already a listener set on the animation, we need wrap the new listener
             // around the existing listener, so that they will both get animation listener
             // callbacks.
-            ViewCompat.setLayerType(v, ViewCompat.LAYER_TYPE_HARDWARE, null);
+            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
             anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener(v, anim,
                     originalListener));
         }
@@ -1185,7 +1215,7 @@
         if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
             newState = Fragment.STOPPED;
         }
-        if (f.mState < newState) {
+        if (f.mState <= newState) {
             // For fragments that are created from a layout, when restoring from
             // state we don't want to allow them to be created until they are
             // being reloaded from the layout.
@@ -1202,73 +1232,77 @@
             }
             switch (f.mState) {
                 case Fragment.INITIALIZING:
-                    if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
-                    if (f.mSavedFragmentState != null) {
-                        f.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader());
-                        f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
-                                FragmentManagerImpl.VIEW_STATE_TAG);
-                        f.mTarget = getFragment(f.mSavedFragmentState,
-                                FragmentManagerImpl.TARGET_STATE_TAG);
-                        if (f.mTarget != null) {
-                            f.mTargetRequestCode = f.mSavedFragmentState.getInt(
-                                    FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
-                        }
-                        f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
-                                FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
-                        if (!f.mUserVisibleHint) {
-                            f.mDeferStart = true;
-                            if (newState > Fragment.STOPPED) {
-                                newState = Fragment.STOPPED;
+                    if (newState > Fragment.INITIALIZING) {
+                        if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
+                        if (f.mSavedFragmentState != null) {
+                            f.mSavedFragmentState.setClassLoader(mHost.getContext()
+                                    .getClassLoader());
+                            f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
+                                    FragmentManagerImpl.VIEW_STATE_TAG);
+                            f.mTarget = getFragment(f.mSavedFragmentState,
+                                    FragmentManagerImpl.TARGET_STATE_TAG);
+                            if (f.mTarget != null) {
+                                f.mTargetRequestCode = f.mSavedFragmentState.getInt(
+                                        FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
+                            }
+                            f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
+                                    FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
+                            if (!f.mUserVisibleHint) {
+                                f.mDeferStart = true;
+                                if (newState > Fragment.STOPPED) {
+                                    newState = Fragment.STOPPED;
+                                }
                             }
                         }
-                    }
-                    f.mHost = mHost;
-                    f.mParentFragment = mParent;
-                    f.mFragmentManager = mParent != null
-                            ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
-                    dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
-                    f.mCalled = false;
-                    f.onAttach(mHost.getContext());
-                    if (!f.mCalled) {
-                        throw new SuperNotCalledException("Fragment " + f
-                                + " did not call through to super.onAttach()");
-                    }
-                    if (f.mParentFragment == null) {
-                        mHost.onAttachFragment(f);
-                    } else {
-                        f.mParentFragment.onAttachFragment(f);
-                    }
-                    dispatchOnFragmentAttached(f, mHost.getContext(), false);
 
-                    if (!f.mRetaining) {
-                        f.performCreate(f.mSavedFragmentState);
-                        dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
-                    } else {
-                        f.restoreChildFragmentState(f.mSavedFragmentState);
-                        f.mState = Fragment.CREATED;
-                    }
-                    f.mRetaining = false;
-                    if (f.mFromLayout) {
-                        // For fragments that are part of the content view
-                        // layout, we need to instantiate the view immediately
-                        // and the inflater will take care of adding it.
-                        f.mView = f.performCreateView(f.getLayoutInflater(
-                                f.mSavedFragmentState), null, f.mSavedFragmentState);
-                        if (f.mView != null) {
-                            f.mInnerView = f.mView;
-                            if (Build.VERSION.SDK_INT >= 11) {
-                                ViewCompat.setSaveFromParentEnabled(f.mView, false);
-                            } else {
-                                f.mView = NoSaveStateFrameLayout.wrap(f.mView);
+                        f.mHost = mHost;
+                        f.mParentFragment = mParent;
+                        f.mFragmentManager = mParent != null
+                                ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
+
+                        // If we have a target fragment, push it along to at least CREATED
+                        // so that this one can rely on it as an initialized dependency.
+                        if (f.mTarget != null) {
+                            if (!mActive.contains(f.mTarget)) {
+                                throw new IllegalStateException("Fragment " + f
+                                        + " declared target fragment " + f.mTarget
+                                        + " that does not belong to this FragmentManager!");
                             }
-                            if (f.mHidden) f.mView.setVisibility(View.GONE);
-                            f.onViewCreated(f.mView, f.mSavedFragmentState);
-                            dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
-                        } else {
-                            f.mInnerView = null;
+                            if (f.mTarget.mState < Fragment.CREATED) {
+                                moveToState(f.mTarget, Fragment.CREATED, 0, 0, true);
+                            }
                         }
+
+                        dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
+                        f.mCalled = false;
+                        f.onAttach(mHost.getContext());
+                        if (!f.mCalled) {
+                            throw new SuperNotCalledException("Fragment " + f
+                                    + " did not call through to super.onAttach()");
+                        }
+                        if (f.mParentFragment == null) {
+                            mHost.onAttachFragment(f);
+                        } else {
+                            f.mParentFragment.onAttachFragment(f);
+                        }
+                        dispatchOnFragmentAttached(f, mHost.getContext(), false);
+
+                        if (!f.mRetaining) {
+                            f.performCreate(f.mSavedFragmentState);
+                            dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
+                        } else {
+                            f.restoreChildFragmentState(f.mSavedFragmentState);
+                            f.mState = Fragment.CREATED;
+                        }
+                        f.mRetaining = false;
                     }
+
                 case Fragment.CREATED:
+                    // This is outside the if statement below on purpose; we want this to run
+                    // even if we do a moveToState from CREATED => *, CREATED => CREATED, and
+                    // * => CREATED as part of the case fallthrough above.
+                    ensureInflatedFragmentView(f);
+
                     if (newState > Fragment.CREATED) {
                         if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
                         if (!f.mFromLayout) {
@@ -1300,11 +1334,7 @@
                                     f.mSavedFragmentState), container, f.mSavedFragmentState);
                             if (f.mView != null) {
                                 f.mInnerView = f.mView;
-                                if (Build.VERSION.SDK_INT >= 11) {
-                                    ViewCompat.setSaveFromParentEnabled(f.mView, false);
-                                } else {
-                                    f.mView = NoSaveStateFrameLayout.wrap(f.mView);
-                                }
+                                f.mView.setSaveFromParentEnabled(false);
                                 if (container != null) {
                                     container.addView(f.mView);
                                 }
@@ -1413,6 +1443,7 @@
                         f.mContainer = null;
                         f.mView = null;
                         f.mInnerView = null;
+                        f.mInLayout = false;
                     }
                 case Fragment.CREATED:
                     if (newState < Fragment.CREATED) {
@@ -1472,6 +1503,22 @@
         moveToState(f, mCurState, 0, 0, false);
     }
 
+    void ensureInflatedFragmentView(Fragment f) {
+        if (f.mFromLayout && !f.mPerformedCreateView) {
+            f.mView = f.performCreateView(f.getLayoutInflater(
+                    f.mSavedFragmentState), null, f.mSavedFragmentState);
+            if (f.mView != null) {
+                f.mInnerView = f.mView;
+                f.mView.setSaveFromParentEnabled(false);
+                if (f.mHidden) f.mView.setVisibility(View.GONE);
+                f.onViewCreated(f.mView, f.mSavedFragmentState);
+                dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
+            } else {
+                f.mInnerView = null;
+            }
+        }
+    }
+
     /**
      * Fragments that have been shown or hidden don't have their visibility changed or
      * animations run during the {@link #showFragment(Fragment)} or {@link #hideFragment(Fragment)}
@@ -1848,6 +1895,10 @@
         }
     }
 
+    public boolean isStateSaved() {
+        return mStateSaved;
+    }
+
     /**
      * Adds an action to the queue of pending actions.
      *
@@ -2125,13 +2176,14 @@
         if (mAdded != null) {
             mTmpAddedFragments.addAll(mAdded);
         }
+        Fragment oldPrimaryNav = getPrimaryNavigationFragment();
         for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
             final BackStackRecord record = records.get(recordNum);
             final boolean isPop = isRecordPop.get(recordNum);
             if (!isPop) {
-                record.expandReplaceOps(mTmpAddedFragments);
+                oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
             } else {
-                record.trackAddedFragmentsInPop(mTmpAddedFragments);
+                oldPrimaryNav = record.trackAddedFragmentsInPop(mTmpAddedFragments, oldPrimaryNav);
             }
             addToBackStack = addToBackStack || record.mAddToBackStack;
         }
@@ -2166,6 +2218,7 @@
                 freeBackStackIndex(record.mIndex);
                 record.mIndex = -1;
             }
+            record.runOnCommitRunnables();
         }
         if (addToBackStack) {
             reportBackStackChanged();
@@ -2427,20 +2480,20 @@
      */
     private boolean generateOpsForPendingActions(ArrayList<BackStackRecord> records,
             ArrayList<Boolean> isPop) {
-        int numActions;
+        boolean didSomething = false;
         synchronized (this) {
             if (mPendingActions == null || mPendingActions.size() == 0) {
                 return false;
             }
 
-            numActions = mPendingActions.size();
+            final int numActions = mPendingActions.size();
             for (int i = 0; i < numActions; i++) {
-                mPendingActions.get(i).generateOps(records, isPop);
+                didSomething |= mPendingActions.get(i).generateOps(records, isPop);
             }
             mPendingActions.clear();
             mHost.getHandler().removeCallbacks(mExecCommit);
         }
-        return numActions > 0;
+        return didSomething;
     }
 
     void doPendingDeferredStart() {
@@ -2739,6 +2792,9 @@
         fms.mActive = active;
         fms.mAdded = added;
         fms.mBackStack = backStack;
+        if (mPrimaryNav != null) {
+            fms.mPrimaryNavActiveIndex = mPrimaryNav.mIndex;
+        }
         return fms;
     }
 
@@ -2789,7 +2845,7 @@
                 if (childNonConfigs != null && i < childNonConfigs.size()) {
                     childNonConfig = childNonConfigs.get(i);
                 }
-                Fragment f = fs.instantiate(mHost, mParent, childNonConfig);
+                Fragment f = fs.instantiate(mHost, mContainer, mParent, childNonConfig);
                 if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f);
                 mActive.add(f);
                 // Now that the fragment is instantiated (or came from being
@@ -2865,6 +2921,10 @@
         } else {
             mBackStack = null;
         }
+
+        if (fms.mPrimaryNavActiveIndex >= 0) {
+            mPrimaryNav = mActive.get(fms.mPrimaryNavActiveIndex);
+        }
     }
 
     public void attachController(FragmentHostCallback host,
@@ -3061,6 +3121,19 @@
         }
     }
 
+    public void setPrimaryNavigationFragment(Fragment f) {
+        if (f != null && (f.getFragmentManager() != this || f.mIndex >= mActive.size()
+                || mActive.get(f.mIndex) != f)) {
+            throw new IllegalArgumentException("Fragment " + f
+                    + " is not an active fragment of FragmentManager " + this);
+        }
+        mPrimaryNav = f;
+    }
+
+    public Fragment getPrimaryNavigationFragment() {
+        return mPrimaryNav;
+    }
+
     public void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb,
             boolean recursive) {
         if (mLifecycleCallbacks == null) {
@@ -3402,7 +3475,7 @@
                 + Integer.toHexString(id) + " fname=" + fname
                 + " existing=" + fragment);
         if (fragment == null) {
-            fragment = Fragment.instantiate(context, fname);
+            fragment = mContainer.instantiate(context, fname, null);
             fragment.mFromLayout = true;
             fragment.mFragmentId = id != 0 ? id : containerId;
             fragment.mContainerId = containerId;
@@ -3434,7 +3507,9 @@
         }
 
         // If we haven't finished entering the CREATED state ourselves yet,
-        // push the inflated child fragment along.
+        // push the inflated child fragment along. This will ensureInflatedFragmentView
+        // at the right phase of the lifecycle so that we will have mView populated
+        // for compliant fragments below.
         if (mCurState < Fragment.CREATED && fragment.mFromLayout) {
             moveToState(fragment, Fragment.CREATED, 0, 0, false);
         } else {
@@ -3504,6 +3579,16 @@
         @Override
         public boolean generateOps(ArrayList<BackStackRecord> records,
                 ArrayList<Boolean> isRecordPop) {
+            if (mPrimaryNav != null // We have a primary nav fragment
+                    && mId < 0 // No valid id (since they're local)
+                    && mName == null) { // no name to pop to (since they're local)
+                final FragmentManager childManager = mPrimaryNav.peekChildFragmentManager();
+                if (childManager != null && childManager.popBackStackImmediate()) {
+                    // We didn't add any operations for this FragmentManager even though
+                    // a child did do work.
+                    return false;
+                }
+            }
             return popBackStackState(records, isRecordPop, mName, mId, mFlags);
         }
     }
diff --git a/fragment/java/android/support/v4/app/FragmentTransaction.java b/fragment/java/android/support/v4/app/FragmentTransaction.java
index 0171681..e7ac0c6 100644
--- a/fragment/java/android/support/v4/app/FragmentTransaction.java
+++ b/fragment/java/android/support/v4/app/FragmentTransaction.java
@@ -16,8 +16,6 @@
 
 package android.support.v4.app;
 
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
 import android.support.annotation.AnimRes;
 import android.support.annotation.IdRes;
 import android.support.annotation.IntDef;
@@ -30,6 +28,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
 /**
  * Static library support version of the framework's {@link android.app.FragmentTransaction}.
  * Used to write apps that run on platforms prior to Android 3.0.  When running
@@ -148,6 +148,24 @@
     public abstract FragmentTransaction attach(Fragment fragment);
 
     /**
+     * Set a currently active fragment in this FragmentManager as the primary navigation fragment.
+     *
+     * <p>The primary navigation fragment's
+     * {@link Fragment#getChildFragmentManager() child FragmentManager} will be called first
+     * to process delegated navigation actions such as {@link FragmentManager#popBackStack()}
+     * if no ID or transaction name is provided to pop to. Navigation operations outside of the
+     * fragment system may choose to delegate those actions to the primary navigation fragment
+     * as returned by {@link FragmentManager#getPrimaryNavigationFragment()}.</p>
+     *
+     * <p>The fragment provided must currently be added to the FragmentManager to be set as
+     * a primary navigation fragment, or previously added as part of this transaction.</p>
+     *
+     * @param fragment the fragment to set as the primary navigation fragment
+     * @return the same FragmentTransaction instance
+     */
+    public abstract FragmentTransaction setPrimaryNavigationFragment(Fragment fragment);
+
+    /**
      * @return <code>true</code> if this transaction contains no operations,
      * <code>false</code> otherwise.
      */
@@ -305,6 +323,22 @@
     public abstract FragmentTransaction setAllowOptimization(boolean allowOptimization);
 
     /**
+     * Add a Runnable to this transaction that will be run after this transaction has
+     * been committed. If fragment transactions are {@link #setAllowOptimization(boolean) optimized}
+     * this may be after other subsequent fragment operations have also taken place, or operations
+     * in this transaction may have been optimized out due to the presence of a subsequent
+     * fragment transaction in the batch.
+     *
+     * <p><code>postOnCommit</code> may not be used with transactions
+     * {@link #addToBackStack(String) added to the back stack} as Runnables cannot be persisted
+     * with back stack state.</p>
+     *
+     * @param runnable Runnable to add
+     * @return this FragmentTransaction
+     */
+    public abstract FragmentTransaction postOnCommit(Runnable runnable);
+
+    /**
      * Schedules a commit of this transaction.  The commit does
      * not happen immediately; it will be scheduled as work on the main thread
      * to be done the next time that thread is ready.
diff --git a/fragment/java/android/support/v4/app/FragmentTransition.java b/fragment/java/android/support/v4/app/FragmentTransition.java
index 5e0d9e3..ff7f91e 100644
--- a/fragment/java/android/support/v4/app/FragmentTransition.java
+++ b/fragment/java/android/support/v4/app/FragmentTransition.java
@@ -40,14 +40,16 @@
      * REPLACE operations have already been replaced by add/remove operations.
      */
     private static final int[] INVERSE_OPS = {
-            BackStackRecord.OP_NULL,   // inverse of OP_NULL (error)
-            BackStackRecord.OP_REMOVE, // inverse of OP_ADD
-            BackStackRecord.OP_NULL,   // inverse of OP_REPLACE (error)
-            BackStackRecord.OP_ADD,    // inverse of OP_REMOVE
-            BackStackRecord.OP_SHOW,   // inverse of OP_HIDE
-            BackStackRecord.OP_HIDE,   // inverse of OP_SHOW
-            BackStackRecord.OP_ATTACH, // inverse of OP_DETACH
-            BackStackRecord.OP_DETACH, // inverse of OP_ATTACH
+            BackStackRecord.OP_NULL,              // inverse of OP_NULL (error)
+            BackStackRecord.OP_REMOVE,            // inverse of OP_ADD
+            BackStackRecord.OP_NULL,              // inverse of OP_REPLACE (error)
+            BackStackRecord.OP_ADD,               // inverse of OP_REMOVE
+            BackStackRecord.OP_SHOW,              // inverse of OP_HIDE
+            BackStackRecord.OP_HIDE,              // inverse of OP_SHOW
+            BackStackRecord.OP_ATTACH,            // inverse of OP_DETACH
+            BackStackRecord.OP_DETACH,            // inverse of OP_ATTACH
+            BackStackRecord.OP_UNSET_PRIMARY_NAV, // inverse of OP_SET_PRIMARY_NAV
+            BackStackRecord.OP_SET_PRIMARY_NAV,   // inverse of OP_UNSET_PRIMARY_NAV
     };
 
     /**
@@ -1009,6 +1011,9 @@
             SparseArray<FragmentContainerTransition> transitioningFragments, boolean isPop,
             boolean isOptimizedTransaction) {
         final Fragment fragment = op.fragment;
+        if (fragment == null) {
+            return; // no fragment, no transition
+        }
         final int containerId = fragment.mContainerId;
         if (containerId == 0) {
             return; // no container, no transition
diff --git a/fragment/java/android/support/v4/app/NoSaveStateFrameLayout.java b/fragment/java/android/support/v4/app/NoSaveStateFrameLayout.java
deleted file mode 100644
index 74cb319..0000000
--- a/fragment/java/android/support/v4/app/NoSaveStateFrameLayout.java
+++ /dev/null
@@ -1,63 +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 android.support.v4.app;
-
-import android.content.Context;
-import android.os.Parcelable;
-import android.util.SparseArray;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-/**
- * Pre-Honeycomb versions of the platform don't have {@link View#setSaveFromParentEnabled(boolean)},
- * so instead we insert this between the view and its parent.
- */
-class NoSaveStateFrameLayout extends FrameLayout {
-    static ViewGroup wrap(View child) {
-        NoSaveStateFrameLayout wrapper = new NoSaveStateFrameLayout(child.getContext());
-        ViewGroup.LayoutParams childParams = child.getLayoutParams();
-        if (childParams != null) {
-            wrapper.setLayoutParams(childParams);
-        }
-        NoSaveStateFrameLayout.LayoutParams lp = new NoSaveStateFrameLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
-        child.setLayoutParams(lp);
-        wrapper.addView(child);
-        return wrapper;
-    }
-
-    public NoSaveStateFrameLayout(Context context) {
-        super(context);
-    }
-
-    /**
-     * Override to prevent freezing of any child views.
-     */
-    @Override
-    protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
-        dispatchFreezeSelfOnly(container);
-    }
-
-    /**
-     * Override to prevent thawing of any child views.
-     */
-    @Override
-    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
-        dispatchThawSelfOnly(container);
-    }
-}
diff --git a/fragment/jellybean/android/support/v4/app/BaseFragmentActivityJB.java b/fragment/jellybean/android/support/v4/app/BaseFragmentActivityJB.java
index 37fbaeb..3df56e1 100644
--- a/fragment/jellybean/android/support/v4/app/BaseFragmentActivityJB.java
+++ b/fragment/jellybean/android/support/v4/app/BaseFragmentActivityJB.java
@@ -16,18 +16,22 @@
 
 package android.support.v4.app;
 
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
 import android.content.Intent;
 import android.content.IntentSender;
 import android.os.Bundle;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
+import android.support.annotation.RestrictTo;
 
 /**
  * Base class for {@code FragmentActivity} to be able to use v16 APIs.
  *
  * @hide
  */
-abstract class BaseFragmentActivityJB extends BaseFragmentActivityHoneycomb {
+@RestrictTo(LIBRARY_GROUP)
+abstract class BaseFragmentActivityJB extends BaseFragmentActivityApi14 {
 
     // We need to keep track of whether startActivityForResult originated from a Fragment, so we
     // can conditionally check whether the requestCode collides with our reserved ID space for the
diff --git a/fragment/tests/AndroidManifest.xml b/fragment/tests/AndroidManifest.xml
index 9cab8ca..d36cd0a 100644
--- a/fragment/tests/AndroidManifest.xml
+++ b/fragment/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.fragment.test">
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                       android.support.test.espresso, android.support.test.espresso.idling"/>
diff --git a/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java b/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
index 4c0c0a4..c05cc53 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
@@ -586,6 +586,239 @@
         assertFalse(fragment1.mCalledOnResume);
     }
 
+    @Test
+    @UiThreadTest
+    public void testIsStateSaved() throws Throwable {
+        FragmentController fc = startupFragmentController(null);
+        FragmentManager fm = fc.getSupportFragmentManager();
+
+        Fragment f = new StrictFragment();
+        fm.beginTransaction()
+                .add(f, "1")
+                .commitNow();
+
+        assertFalse("fragment reported state saved while resumed", f.isStateSaved());
+
+        fc.dispatchPause();
+        fc.saveAllState();
+
+        assertTrue("fragment reported state not saved after saveAllState", f.isStateSaved());
+
+        fc.dispatchStop();
+        fc.dispatchReallyStop();
+
+        assertTrue("fragment reported state not saved after stop", f.isStateSaved());
+
+        fc.dispatchDestroy();
+
+        assertFalse("fragment reported state saved after destroy", f.isStateSaved());
+    }
+
+    @Test
+    @UiThreadTest
+    public void testSetArgumentsLifecycle() throws Throwable {
+        FragmentController fc = startupFragmentController(null);
+        FragmentManager fm = fc.getSupportFragmentManager();
+
+        Fragment f = new StrictFragment();
+        f.setArguments(new Bundle());
+
+        fm.beginTransaction()
+                .add(f, "1")
+                .commitNow();
+
+        f.setArguments(new Bundle());
+
+        fc.dispatchPause();
+        fc.saveAllState();
+
+        boolean threw = false;
+        try {
+            f.setArguments(new Bundle());
+        } catch (IllegalStateException ise) {
+            threw = true;
+        }
+        assertTrue("fragment allowed setArguments after state save", threw);
+
+        fc.dispatchStop();
+        fc.dispatchReallyStop();
+
+        threw = false;
+        try {
+            f.setArguments(new Bundle());
+        } catch (IllegalStateException ise) {
+            threw = true;
+        }
+        assertTrue("fragment allowed setArguments after stop", threw);
+
+        fc.dispatchDestroy();
+
+        // Fully destroyed, so fragments have been removed.
+        f.setArguments(new Bundle());
+    }
+
+    /*
+     * Test that target fragments are in a useful state when we restore them, even if they're
+     * on the back stack.
+     */
+
+    @Test
+    @UiThreadTest
+    public void targetFragmentRestoreLifecycleStateBackStack() throws Throwable {
+        final FragmentController fc1 = FragmentController.createController(
+                new HostCallbacks(mActivityRule.getActivity()));
+
+        final FragmentManager fm1 = fc1.getSupportFragmentManager();
+
+        fc1.attachHost(null);
+        fc1.dispatchCreate();
+
+        final Fragment target = new TargetFragment();
+        fm1.beginTransaction().add(target, "target").commitNow();
+
+        final Fragment referrer = new ReferrerFragment();
+        referrer.setTargetFragment(target, 0);
+
+        fm1.beginTransaction()
+                .remove(target)
+                .add(referrer, "referrer")
+                .addToBackStack(null)
+                .commit();
+
+        fc1.dispatchActivityCreated();
+        fc1.noteStateNotSaved();
+        fc1.execPendingActions();
+        fc1.doLoaderStart();
+        fc1.dispatchStart();
+        fc1.reportLoaderStart();
+        fc1.dispatchResume();
+        fc1.execPendingActions();
+
+        // Bring the state back down to destroyed, simulating an activity restart
+        fc1.dispatchPause();
+        final Parcelable savedState = fc1.saveAllState();
+        final FragmentManagerNonConfig nonconf = fc1.retainNestedNonConfig();
+        fc1.dispatchStop();
+        fc1.dispatchReallyStop();
+        fc1.dispatchDestroy();
+
+        final FragmentController fc2 = FragmentController.createController(
+                new HostCallbacks(mActivityRule.getActivity()));
+        final FragmentManager fm2 = fc2.getSupportFragmentManager();
+
+        fc2.attachHost(null);
+        fc2.restoreAllState(savedState, nonconf);
+        fc2.dispatchCreate();
+
+        fc2.dispatchActivityCreated();
+        fc2.noteStateNotSaved();
+        fc2.execPendingActions();
+        fc2.doLoaderStart();
+        fc2.dispatchStart();
+        fc2.reportLoaderStart();
+        fc2.dispatchResume();
+        fc2.execPendingActions();
+
+        // Bring the state back down to destroyed before we finish the test
+        fc2.dispatchPause();
+        fc2.saveAllState();
+        fc2.dispatchStop();
+        fc2.dispatchReallyStop();
+        fc2.dispatchDestroy();
+    }
+
+    @Test
+    @UiThreadTest
+    public void targetFragmentRestoreLifecycleStateManagerOrder() throws Throwable {
+        final FragmentController fc1 = FragmentController.createController(
+                new HostCallbacks(mActivityRule.getActivity()));
+
+        final FragmentManager fm1 = fc1.getSupportFragmentManager();
+
+        fc1.attachHost(null);
+        fc1.dispatchCreate();
+
+        final Fragment target1 = new TargetFragment();
+        final Fragment referrer1 = new ReferrerFragment();
+        referrer1.setTargetFragment(target1, 0);
+
+        fm1.beginTransaction().add(target1, "target1").add(referrer1, "referrer1").commitNow();
+
+        final Fragment target2 = new TargetFragment();
+        final Fragment referrer2 = new ReferrerFragment();
+        referrer2.setTargetFragment(target2, 0);
+
+        // Order shouldn't matter.
+        fm1.beginTransaction().add(referrer2, "referrer2").add(target2, "target2").commitNow();
+
+        fc1.dispatchActivityCreated();
+        fc1.noteStateNotSaved();
+        fc1.execPendingActions();
+        fc1.doLoaderStart();
+        fc1.dispatchStart();
+        fc1.reportLoaderStart();
+        fc1.dispatchResume();
+        fc1.execPendingActions();
+
+        // Bring the state back down to destroyed, simulating an activity restart
+        fc1.dispatchPause();
+        final Parcelable savedState = fc1.saveAllState();
+        final FragmentManagerNonConfig nonconf = fc1.retainNestedNonConfig();
+        fc1.dispatchStop();
+        fc1.dispatchReallyStop();
+        fc1.dispatchDestroy();
+
+        final FragmentController fc2 = FragmentController.createController(
+                new HostCallbacks(mActivityRule.getActivity()));
+        final FragmentManager fm2 = fc2.getSupportFragmentManager();
+
+        fc2.attachHost(null);
+        fc2.restoreAllState(savedState, nonconf);
+        fc2.dispatchCreate();
+
+        fc2.dispatchActivityCreated();
+        fc2.noteStateNotSaved();
+        fc2.execPendingActions();
+        fc2.doLoaderStart();
+        fc2.dispatchStart();
+        fc2.reportLoaderStart();
+        fc2.dispatchResume();
+        fc2.execPendingActions();
+
+        // Bring the state back down to destroyed before we finish the test
+        fc2.dispatchPause();
+        fc2.saveAllState();
+        fc2.dispatchStop();
+        fc2.dispatchReallyStop();
+        fc2.dispatchDestroy();
+    }
+
+    @Test
+    public void targetFragmentNoCycles() throws Throwable {
+        final Fragment one = new Fragment();
+        final Fragment two = new Fragment();
+        final Fragment three = new Fragment();
+
+        try {
+            one.setTargetFragment(two, 0);
+            two.setTargetFragment(three, 0);
+            three.setTargetFragment(one, 0);
+            assertTrue("creating a fragment target cycle did not throw IllegalArgumentException",
+                    false);
+        } catch (IllegalArgumentException e) {
+            // Success!
+        }
+    }
+
+    @Test
+    public void targetFragmentSetClear() throws Throwable {
+        final Fragment one = new Fragment();
+        final Fragment two = new Fragment();
+
+        one.setTargetFragment(two, 0);
+        one.setTargetFragment(null, 0);
+    }
+
     private void assertAnimationsMatch(FragmentManager fm, int enter, int exit, int popEnter,
             int popExit) {
         FragmentManagerImpl fmImpl = (FragmentManagerImpl) fm;
@@ -852,4 +1085,31 @@
             return fragment;
         }
     }
+
+    public static class TargetFragment extends Fragment {
+        public boolean calledCreate;
+
+        @Override
+        public void onCreate(@Nullable Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            calledCreate = true;
+        }
+    }
+
+    public static class ReferrerFragment extends Fragment {
+        @Override
+        public void onCreate(@Nullable Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            Fragment target = getTargetFragment();
+            assertNotNull("target fragment was null during referrer onCreate", target);
+
+            if (!(target instanceof TargetFragment)) {
+                throw new IllegalStateException("target fragment was not a TargetFragment");
+            }
+
+            assertTrue("target fragment has not yet been created",
+                    ((TargetFragment) target).calledCreate);
+        }
+    }
 }
diff --git a/fragment/tests/java/android/support/v4/app/FragmentTest.java b/fragment/tests/java/android/support/v4/app/FragmentTest.java
index 35f8e35..90deab9 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentTest.java
@@ -23,6 +23,7 @@
 import android.support.fragment.test.R;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.ActivityTestRule;
@@ -72,7 +73,7 @@
         assertEquals(1, fragment2.createOrder);
     }
 
-    @SmallTest
+    @LargeTest
     @Test
     public void testChildFragmentManagerGone() throws Throwable {
         final FragmentA fragmentA = new FragmentA();
diff --git a/fragment/tests/java/android/support/v4/app/FragmentTransactionTest.java b/fragment/tests/java/android/support/v4/app/FragmentTransactionTest.java
index 117ca9d..201a197 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentTransactionTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentTransactionTest.java
@@ -161,6 +161,46 @@
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
+    @Test
+    public void testPostOnCommit() throws Throwable {
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final boolean[] ran = new boolean[1];
+                FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
+                fm.beginTransaction().postOnCommit(new Runnable() {
+                    @Override
+                    public void run() {
+                        ran[0] = true;
+                    }
+                }).commit();
+                fm.executePendingTransactions();
+
+                assertTrue("postOnCommit runnable never ran", ran[0]);
+
+                ran[0] = false;
+
+                boolean threw = false;
+                try {
+                    fm.beginTransaction().postOnCommit(new Runnable() {
+                        @Override
+                        public void run() {
+                            ran[0] = true;
+                        }
+                    }).addToBackStack(null).commit();
+                } catch (IllegalStateException ise) {
+                    threw = true;
+                }
+
+                fm.executePendingTransactions();
+
+                assertTrue("postOnCommit was allowed to be called for back stack transaction",
+                        threw);
+                assertFalse("postOnCommit runnable for back stack transaction was run", ran[0]);
+            }
+        });
+    }
+
     public static class CorrectFragment extends Fragment {}
 
     private static class PrivateFragment extends Fragment {}
diff --git a/fragment/tests/java/android/support/v4/app/NestedInflatedFragmentTest.java b/fragment/tests/java/android/support/v4/app/NestedInflatedFragmentTest.java
new file mode 100644
index 0000000..b4316da
--- /dev/null
+++ b/fragment/tests/java/android/support/v4/app/NestedInflatedFragmentTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.support.v4.app;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.fragment.test.R;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.app.test.FragmentTestActivity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class NestedInflatedFragmentTest {
+    private static final String TAG = "NestedInflatedFragmentTest";
+
+    @Rule
+    public ActivityTestRule<FragmentTestActivity> mActivityRule =
+            new ActivityTestRule<>(FragmentTestActivity.class);
+
+    @Test
+    @UiThreadTest
+    public void inflatedChildFragment() throws Throwable {
+        final FragmentTestActivity activity = mActivityRule.getActivity();
+        final FragmentManager fm = activity.getSupportFragmentManager();
+
+        ParentFragment parentFragment = new ParentFragment();
+        fm.beginTransaction().add(android.R.id.content, parentFragment).commitNow();
+
+        fm.beginTransaction().replace(android.R.id.content, new SimpleFragment())
+                .addToBackStack(null).commit();
+        fm.executePendingTransactions();
+
+        fm.popBackStackImmediate();
+    }
+
+    public static class ParentFragment extends Fragment {
+        @Nullable
+        @Override
+        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+                @Nullable Bundle savedInstanceState) {
+            return inflater.inflate(R.layout.nested_inflated_fragment_parent, container, false);
+        }
+    }
+
+    public static class InflatedChildFragment extends Fragment {
+        @Nullable
+        @Override
+        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+                @Nullable Bundle savedInstanceState) {
+            return inflater.inflate(R.layout.nested_inflated_fragment_child, container, false);
+        }
+    }
+
+    public static class SimpleFragment extends Fragment {
+        @Nullable
+        @Override
+        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+                @Nullable Bundle savedInstanceState) {
+            TextView textView = new TextView(inflater.getContext());
+            textView.setText("Simple fragment");
+            return textView;
+        }
+    }
+}
diff --git a/fragment/tests/java/android/support/v4/app/PrimaryNavFragmentTest.java b/fragment/tests/java/android/support/v4/app/PrimaryNavFragmentTest.java
new file mode 100644
index 0000000..6895ce9
--- /dev/null
+++ b/fragment/tests/java/android/support/v4/app/PrimaryNavFragmentTest.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.support.v4.app;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.app.test.EmptyFragmentTestActivity;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class PrimaryNavFragmentTest {
+    @Rule
+    public ActivityTestRule<EmptyFragmentTestActivity> mActivityRule =
+            new ActivityTestRule<EmptyFragmentTestActivity>(EmptyFragmentTestActivity.class);
+
+    @Test
+    public void delegateBackToPrimaryNav() throws Throwable {
+        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
+        final StrictFragment strictFragment = new StrictFragment();
+
+        fm.beginTransaction().add(strictFragment, null).setPrimaryNavigationFragment(strictFragment)
+                .commit();
+        executePendingTransactions(fm);
+
+        assertSame("new fragment is not primary nav fragment", strictFragment,
+                fm.getPrimaryNavigationFragment());
+
+        final StrictFragment child = new StrictFragment();
+        FragmentManager cfm = strictFragment.getChildFragmentManager();
+        cfm.beginTransaction().add(child, null).addToBackStack(null).commit();
+        executePendingTransactions(cfm);
+
+        assertEquals("child transaction not on back stack", 1, cfm.getBackStackEntryCount());
+
+        // Should execute the pop for the child fragmentmanager
+        assertTrue("popBackStackImmediate returned no action performed",
+                popBackStackImmediate(fm));
+
+        assertEquals("child transaction still on back stack", 0, cfm.getBackStackEntryCount());
+    }
+
+    @Test
+    public void popPrimaryNav() throws Throwable {
+        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
+        final StrictFragment strictFragment1 = new StrictFragment();
+
+        fm.beginTransaction().add(strictFragment1, null)
+                .setPrimaryNavigationFragment(strictFragment1)
+                .commit();
+        executePendingTransactions(fm);
+
+        assertSame("new fragment is not primary nav fragment", strictFragment1,
+                fm.getPrimaryNavigationFragment());
+
+        fm.beginTransaction().remove(strictFragment1).addToBackStack(null).commit();
+        executePendingTransactions(fm);
+
+        assertNull("primary nav fragment is not null after remove",
+                fm.getPrimaryNavigationFragment());
+
+        popBackStackImmediate(fm);
+
+        assertSame("primary nav fragment was not restored on pop", strictFragment1,
+                fm.getPrimaryNavigationFragment());
+
+        final StrictFragment strictFragment2 = new StrictFragment();
+        fm.beginTransaction().remove(strictFragment1).add(strictFragment2, null)
+                .setPrimaryNavigationFragment(strictFragment2).addToBackStack(null).commit();
+        executePendingTransactions(fm);
+
+        assertSame("primary nav fragment not updated to new fragment", strictFragment2,
+                fm.getPrimaryNavigationFragment());
+
+        popBackStackImmediate(fm);
+
+        assertSame("primary nav fragment not restored on pop", strictFragment1,
+                fm.getPrimaryNavigationFragment());
+
+        fm.beginTransaction().setPrimaryNavigationFragment(strictFragment1)
+                .addToBackStack(null).commit();
+        executePendingTransactions(fm);
+
+        assertSame("primary nav fragment not retained when set again in new transaction",
+                strictFragment1, fm.getPrimaryNavigationFragment());
+        popBackStackImmediate(fm);
+
+        assertSame("same primary nav fragment not retained when set primary nav transaction popped",
+                strictFragment1, fm.getPrimaryNavigationFragment());
+    }
+
+    @Test
+    public void replacePrimaryNav() throws Throwable {
+        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
+        final StrictFragment strictFragment1 = new StrictFragment();
+
+        fm.beginTransaction().add(android.R.id.content, strictFragment1)
+                .setPrimaryNavigationFragment(strictFragment1).commit();
+        executePendingTransactions(fm);
+
+        assertSame("new fragment is not primary nav fragment", strictFragment1,
+                fm.getPrimaryNavigationFragment());
+
+        final StrictFragment strictFragment2 = new StrictFragment();
+        fm.beginTransaction().replace(android.R.id.content, strictFragment2)
+                .addToBackStack(null).commit();
+
+        executePendingTransactions(fm);
+
+        assertNull("primary nav fragment not null after replace",
+                fm.getPrimaryNavigationFragment());
+
+        popBackStackImmediate(fm);
+
+        assertSame("primary nav fragment not restored after popping replace", strictFragment1,
+                fm.getPrimaryNavigationFragment());
+
+        fm.beginTransaction().setPrimaryNavigationFragment(null).commit();
+        executePendingTransactions(fm);
+
+        assertNull("primary nav fragment not null after explicit set to null",
+                fm.getPrimaryNavigationFragment());
+
+        fm.beginTransaction().replace(android.R.id.content, strictFragment2)
+                .setPrimaryNavigationFragment(strictFragment2).addToBackStack(null).commit();
+        executePendingTransactions(fm);
+
+        assertSame("primary nav fragment not set correctly after replace", strictFragment2,
+                fm.getPrimaryNavigationFragment());
+
+        popBackStackImmediate(fm);
+
+        assertNull("primary nav fragment not null after popping replace",
+                fm.getPrimaryNavigationFragment());
+    }
+
+    private void executePendingTransactions(final FragmentManager fm) throws Throwable {
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                fm.executePendingTransactions();
+            }
+        });
+    }
+
+    private boolean popBackStackImmediate(final FragmentManager fm) throws Throwable {
+        final boolean[] result = new boolean[1];
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                result[0] = fm.popBackStackImmediate();
+            }
+        });
+        return result[0];
+    }
+}
diff --git a/fragment/tests/java/android/support/v4/app/StrictFragment.java b/fragment/tests/java/android/support/v4/app/StrictFragment.java
index 7e57745..def71d8 100644
--- a/fragment/tests/java/android/support/v4/app/StrictFragment.java
+++ b/fragment/tests/java/android/support/v4/app/StrictFragment.java
@@ -98,8 +98,8 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        if (mCalledOnCreate) {
-            throw new IllegalStateException("onCreate called more than once");
+        if (mCalledOnCreate && !mCalledOnDestroy) {
+            throw new IllegalStateException("onCreate called more than once with no onDestroy");
         }
         mCalledOnCreate = true;
         checkState("onCreate", ATTACHED);
diff --git a/fragment/tests/res/layout/nested_inflated_fragment_child.xml b/fragment/tests/res/layout/nested_inflated_fragment_child.xml
new file mode 100644
index 0000000..0bb98d2
--- /dev/null
+++ b/fragment/tests/res/layout/nested_inflated_fragment_child.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <TextView android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:text="Test" />
+</LinearLayout>
\ No newline at end of file
diff --git a/fragment/tests/res/layout/nested_inflated_fragment_parent.xml b/fragment/tests/res/layout/nested_inflated_fragment_parent.xml
new file mode 100644
index 0000000..665a705
--- /dev/null
+++ b/fragment/tests/res/layout/nested_inflated_fragment_parent.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+    <fragment android:name="android.support.v4.app.NestedInflatedFragmentTest$InflatedChildFragment"
+              android:id="@+id/child_fragment"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+</LinearLayout>
\ No newline at end of file
diff --git a/graphics/drawable/Android.mk b/graphics/drawable/Android.mk
index 78652aa..f58493b 100644
--- a/graphics/drawable/Android.mk
+++ b/graphics/drawable/Android.mk
@@ -25,7 +25,7 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := $(call all-java-files-under, static/src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/static/res
-LOCAL_MANIFEST_FILE := static/AndroidManifest-make.xml
+LOCAL_MANIFEST_FILE := static/AndroidManifest.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-annotations
@@ -44,7 +44,7 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := $(call all-java-files-under, animated/src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/animated/res
-LOCAL_MANIFEST_FILE := animated/AndroidManifest-make.xml
+LOCAL_MANIFEST_FILE := animated/AndroidManifest.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-vectordrawable \
diff --git a/graphics/drawable/animated/AndroidManifest-make.xml b/graphics/drawable/animated/AndroidManifest-make.xml
deleted file mode 100644
index 98f9e17..0000000
--- a/graphics/drawable/animated/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-   Copyright (C) 2015 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.
-  -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.graphics.drawable.animated">
-    <application/>
-</manifest>
diff --git a/graphics/drawable/animated/build.gradle b/graphics/drawable/animated/build.gradle
index 10d112a..b92efd3 100644
--- a/graphics/drawable/animated/build.gradle
+++ b/graphics/drawable/animated/build.gradle
@@ -1,39 +1,25 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'animated-vector-drawable'
 
 dependencies {
     compile project(':support-vector-drawable')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    testCompile 'junit:junit:4.12'
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
     defaultConfig {
-        minSdkVersion 11
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDir 'src'
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 
     aaptOptions {
@@ -45,52 +31,8 @@
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support AnimatedVectorDrawable'
-                description "Android Support AnimatedVectorDrawable"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2015'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
-}
+supportLibrary {
+    name 'Android Support AnimatedVectorDrawable'
+    inceptionYear '2015'
+    description 'Android Support AnimatedVectorDrawable'
+}
\ No newline at end of file
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
index fe60272..33ff2c5 100644
--- a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
@@ -55,12 +55,81 @@
  * For older API version, this class uses {@link android.animation.ObjectAnimator} and
  * {@link android.animation.AnimatorSet} to animate the properties of a
  * {@link VectorDrawableCompat} to create an animated drawable.
- * <p>
+ * <p/>
  * AnimatedVectorDrawableCompat are defined in the same XML format as {@link AnimatedVectorDrawable}.
- * </p>
+ * <p/>
+ * Here are all the animatable attributes in {@link VectorDrawableCompat}:
+ * <table border="2" align="center" cellpadding="5">
+ *     <thead>
+ *         <tr>
+ *             <th>Element Name</th>
+ *             <th>Animatable attribute name</th>
+ *         </tr>
+ *     </thead>
+ *     <tr>
+ *         <td>&lt;vector&gt;</td>
+ *         <td>alpha</td>
+ *     </tr>
+ *     <tr>
+ *         <td rowspan="7">&lt;group&gt;</td>
+ *         <td>rotation</td>
+ *     </tr>
+ *     <tr>
+ *         <td>pivotX</td>
+ *     </tr>
+ *     <tr>
+ *         <td>pivotY</td>
+ *     </tr>
+ *     <tr>
+ *         <td>scaleX</td>
+ *     </tr>
+ *     <tr>
+ *         <td>scaleY</td>
+ *     </tr>
+ *     <tr>
+ *         <td>translateX</td>
+ *     </tr>
+ *     <tr>
+ *         <td>translateY</td>
+ *     </tr>
+ *     <tr>
+ *         <td rowspan="8">&lt;path&gt;</td>
+ *         <td>fillColor</td>
+ *     </tr>
+ *     <tr>
+ *         <td>strokeColor</td>
+ *     </tr>
+ *     <tr>
+ *         <td>strokeWidth</td>
+ *     </tr>
+ *     <tr>
+ *         <td>strokeAlpha</td>
+ *     </tr>
+ *     <tr>
+ *         <td>fillAlpha</td>
+ *     </tr>
+ *     <tr>
+ *         <td>trimPathStart</td>
+ *     </tr>
+ *     <tr>
+ *         <td>trimPathOffset</td>
+ *     </tr>
+ * </table>
+ * <p/>
  * You can always create a AnimatedVectorDrawableCompat object and use it as a Drawable by the Java
  * API. In order to refer to AnimatedVectorDrawableCompat inside a XML file, you can use
  * app:srcCompat attribute in AppCompat library's ImageButton or ImageView.
+ * <p/>
+ * Note that the animation in AnimatedVectorDrawableCompat has to be valid and functional based on
+ * the SDK version the app will be running on. Before SDK version 21, the animation system didn't
+ * support the following features:
+ * <ul>
+ * <li>Path Morphing (PathType evaluator). This is used for morphing one path into another.</li>
+ * <li>Path Interpolation. This is used to defined a flexible interpolator (represented as a path)
+ * instead of the system defined ones like LinearInterpolator.</li>
+ * <li>Animating 2 values in one ObjectAnimator according to one path's X value and Y value. One
+ * usage is moving one object in both X and Y dimensions along an path.</li>
+ * </ul>
  */
 @SuppressLint("NewApi")
 public class AnimatedVectorDrawableCompat extends VectorDrawableCommon implements Animatable {
diff --git a/graphics/drawable/animated/tests/AndroidManifest.xml b/graphics/drawable/animated/tests/AndroidManifest.xml
index 8999852..ac86e2c 100644
--- a/graphics/drawable/animated/tests/AndroidManifest.xml
+++ b/graphics/drawable/animated/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.graphics.drawable.animated.test">
     <uses-sdk
-            android:minSdkVersion="11"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                     android.support.test.espresso, android.support.test.espresso.idling" />
diff --git a/graphics/drawable/static/AndroidManifest-make.xml b/graphics/drawable/static/AndroidManifest-make.xml
deleted file mode 100644
index 8674cb4..0000000
--- a/graphics/drawable/static/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-   Copyright (C) 2015 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.
-  -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.support.graphics.drawable">
-    <application/>
-</manifest>
diff --git a/graphics/drawable/static/build.gradle b/graphics/drawable/static/build.gradle
index fdb306c..996a855 100644
--- a/graphics/drawable/static/build.gradle
+++ b/graphics/drawable/static/build.gradle
@@ -1,42 +1,23 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'support-vector-drawable'
 
 dependencies {
     compile project(':support-annotations')
     compile project(':support-compat')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
-        exclude module: 'support-annotations'
-    }
-    testCompile 'junit:junit:4.12'
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-
+        minSdkVersion 14
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDir 'src'
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 
     aaptOptions {
@@ -44,52 +25,8 @@
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support VectorDrawable'
-                description "Android Support VectorDrawable"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2015'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support VectorDrawable'
+    inceptionYear '2015'
+    description 'Android Support VectorDrawable'
 }
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
index 3166df7..5704d6f 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
@@ -81,36 +81,27 @@
  * <dl>
  * <dt><code>android:name</code></dt>
  * <dd>Defines the name of this vector drawable.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:width</code></dt>
  * <dd>Used to define the intrinsic width of the drawable.
  * This support all the dimension units, normally specified with dp.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:height</code></dt>
  * <dd>Used to define the intrinsic height the drawable.
  * This support all the dimension units, normally specified with dp.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:viewportWidth</code></dt>
  * <dd>Used to define the width of the viewport space. Viewport is basically
  * the virtual canvas where the paths are drawn on.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:viewportHeight</code></dt>
  * <dd>Used to define the height of the viewport space. Viewport is basically
  * the virtual canvas where the paths are drawn on.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:tint</code></dt>
  * <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:tintMode</code></dt>
- * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>The Porter-Duff blending mode for the tint color. Default is src_in.</dd>
  * <dt><code>android:autoMirrored</code></dt>
  * <dd>Indicates if the drawable needs to be mirrored when its layout direction is
- * RTL (right-to-left).</dd>
- * <dd>Animatable : No.</dd>
+ * RTL (right-to-left). Default is false.</dd>
  * <dt><code>android:alpha</code></dt>
- * <dd>The opacity of this drawable.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The opacity of this drawable. Default is 1.</dd>
  * </dl></dd>
  * </dl>
  *
@@ -122,32 +113,24 @@
  * <dl>
  * <dt><code>android:name</code></dt>
  * <dd>Defines the name of the group.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:rotation</code></dt>
- * <dd>The degrees of rotation of the group.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The degrees of rotation of the group. Default is 0.</dd>
  * <dt><code>android:pivotX</code></dt>
  * <dd>The X coordinate of the pivot for the scale and rotation of the group.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
  * <dt><code>android:pivotY</code></dt>
  * <dd>The Y coordinate of the pivot for the scale and rotation of the group.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
  * <dt><code>android:scaleX</code></dt>
- * <dd>The amount of scale on the X Coordinate.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The amount of scale on the X Coordinate. Default is 1.</dd>
  * <dt><code>android:scaleY</code></dt>
- * <dd>The amount of scale on the Y coordinate.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The amount of scale on the Y coordinate. Default is 1.</dd>
  * <dt><code>android:translateX</code></dt>
  * <dd>The amount of translation on the X coordinate.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
  * <dt><code>android:translateY</code></dt>
  * <dd>The amount of translation on the Y coordinate.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
  * </dl></dd>
  * </dl>
  *
@@ -157,49 +140,36 @@
  * <dl>
  * <dt><code>android:name</code></dt>
  * <dd>Defines the name of the path.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:pathData</code></dt>
  * <dd>Defines path data using exactly same format as "d" attribute
  * in the SVG's path data. This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
  * <dt><code>android:fillColor</code></dt>
  * <dd>Specifies the color used to fill the path.
  * If this property is animated, any value set by the animation will override the original value.
  * No path fill is drawn if this property is not specified.</dd>
- * <dd>Animatable : Yes.</dd>
  * <dt><code>android:strokeColor</code></dt>
  * <dd>Specifies the color used to draw the path outline.
  * If this property is animated, any value set by the animation will override the original value.
  * No path outline is drawn if this property is not specified.</dd>
- * <dd>Animatable : Yes.</dd>
  * <dt><code>android:strokeWidth</code></dt>
- * <dd>The width a path stroke.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The width a path stroke. Default is 0.</dd>
  * <dt><code>android:strokeAlpha</code></dt>
- * <dd>The opacity of a path stroke.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The opacity of a path stroke. Default is 1.</dd>
  * <dt><code>android:fillAlpha</code></dt>
- * <dd>The opacity to fill the path with.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The opacity to fill the path with. Default is 1.</dd>
  * <dt><code>android:trimPathStart</code></dt>
- * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The fraction of the path to trim from the start, in the range from 0 to 1. Default is 0.</dd>
  * <dt><code>android:trimPathEnd</code></dt>
- * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The fraction of the path to trim from the end, in the range from 0 to 1. Default is 1.</dd>
  * <dt><code>android:trimPathOffset</code></dt>
  * <dd>Shift trim region (allows showed region to include the start and end), in the range
- * from 0 to 1.</dd>
- * <dd>Animatable : Yes.</dd>
+ * from 0 to 1. Default is 0.</dd>
  * <dt><code>android:strokeLineCap</code></dt>
- * <dd>Sets the linecap for a stroked path: butt, round, square.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>Sets the linecap for a stroked path: butt, round, square. Default is butt.</dd>
  * <dt><code>android:strokeLineJoin</code></dt>
- * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>Sets the lineJoin for a stroked path: miter,round,bevel. Default is miter.</dd>
  * <dt><code>android:strokeMiterLimit</code></dt>
- * <dd>Sets the Miter limit for a stroked path.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>Sets the Miter limit for a stroked path. Default is 4.</dd>
  * </dl></dd>
  * </dl>
  *
@@ -210,13 +180,14 @@
  * <dl>
  * <dt><code>android:name</code></dt>
  * <dd>Defines the name of the clip path.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:pathData</code></dt>
  * <dd>Defines clip path using the same format as "d" attribute
  * in the SVG's path data.</dd>
- * <dd>Animatable : Yes.</dd>
  * </dl></dd>
  * </dl>
+ * <p/>
+ * Note that theme attributes in XML file are supported through
+ * <code>{@link #inflate(Resources, XmlPullParser, AttributeSet, Theme)}</code>.
  */
 public class VectorDrawableCompat extends VectorDrawableCommon {
     static final String LOGTAG = "VectorDrawableCompat";
diff --git a/graphics/drawable/static/tests/AndroidManifest.xml b/graphics/drawable/static/tests/AndroidManifest.xml
index 3a6942d..9b7bc90 100644
--- a/graphics/drawable/static/tests/AndroidManifest.xml
+++ b/graphics/drawable/static/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.graphics.drawable.test">
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                 android.support.test.espresso, android.support.test.espresso.idling" />
diff --git a/documents-archive/Android.mk b/instantvideo/Android.mk
similarity index 69%
copy from documents-archive/Android.mk
copy to instantvideo/Android.mk
index 32ec7d6..2de711e 100644
--- a/documents-archive/Android.mk
+++ b/instantvideo/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 The Android Open Source Project
+# Copyright (C) 2017 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.
@@ -15,24 +15,19 @@
 LOCAL_PATH := $(call my-dir)
 
 # Here is the final static library that apps can link against.
-# Applications that use this library must specify
+# Applications that use this library must include it with
 #
-#   LOCAL_STATIC_ANDROID_LIBRARIES := \
-#       android-support-documents-archive \
-#       android-support-v4 \
-#       android-support-annotations
+#   LOCAL_STATIC_ANDROID_LIBRARIES := android-support-instantvideo
 #
-# in their makefiles to include the resources and their dependencies in their package.
 include $(CLEAR_VARS)
 LOCAL_USE_AAPT2 := true
-LOCAL_MODULE := android-support-documents-archive
+LOCAL_MODULE := android-support-instantvideo
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-annotations \
-    android-support-v4
+    android-support-compat
 LOCAL_JAR_EXCLUDE_FILES := none
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
diff --git a/v7/palette/src/main/AndroidManifest.xml b/instantvideo/AndroidManifest.xml
similarity index 83%
copy from v7/palette/src/main/AndroidManifest.xml
copy to instantvideo/AndroidManifest.xml
index 52e90a2..08ebcbe 100644
--- a/v7/palette/src/main/AndroidManifest.xml
+++ b/instantvideo/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2017 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.
@@ -14,8 +14,8 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.v7.palette">
-    <uses-sdk android:minSdkVersion="9"/>
+          package="android.support.media.instantvideo">
+    <uses-sdk android:minSdkVersion="14"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/instantvideo/build.gradle b/instantvideo/build.gradle
new file mode 100644
index 0000000..068de5a
--- /dev/null
+++ b/instantvideo/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: android.support.SupportLibraryPlugin
+archivesBaseName = 'support-instantvideo'
+
+dependencies {
+    compile project(':support-annotations')
+    compile project(':support-compat')
+    androidTestCompile (libs.test_runner) {
+        exclude module: 'support-annotations'
+    }
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 14
+    }
+
+    sourceSets {
+        main.java.srcDirs = ['src']
+        main.res.srcDir 'res'
+    }
+}
+
+supportLibrary {
+    name 'Android Support Instant Video'
+    inceptionYear '2017'
+    description 'Android Support Library for Instant Video'
+}
\ No newline at end of file
diff --git a/instantvideo/src/android/support/media/instantvideo/preload/InstantVideoPreloadManager.java b/instantvideo/src/android/support/media/instantvideo/preload/InstantVideoPreloadManager.java
new file mode 100644
index 0000000..6b9fbbf
--- /dev/null
+++ b/instantvideo/src/android/support/media/instantvideo/preload/InstantVideoPreloadManager.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.instantvideo.preload;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.util.LruCache;
+import android.util.Log;
+
+/**
+ * A singleton to present a simple interface for preloading videos.
+ *
+ * <p>This class is used in {@link android.support.media.instantvideo.widget.InstantVideoView}
+ * internally to play the preloaded video.
+ */
+public class InstantVideoPreloadManager {
+    private static final String TAG = "InstantVideoPreloadMgr";
+    private static final boolean DEBUG = false;
+
+    private static final int DEFAULT_MAX_VIDEO_COUNT = 20;
+
+    private static InstantVideoPreloadManager sInstance;
+
+    /**
+     * Returns the singleton instance of this class.
+     */
+    public static synchronized InstantVideoPreloadManager getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance =
+                    new InstantVideoPreloadManager(context, new InternalVideoPreloaderFactory());
+        }
+        return sInstance;
+    }
+
+    private final LruCache<Uri, VideoPreloader> mVideoCache =
+            new LruCache<Uri, VideoPreloader>(DEFAULT_MAX_VIDEO_COUNT) {
+                @Override
+                protected void entryRemoved(boolean evicted, Uri key, VideoPreloader oldValue,
+                        VideoPreloader newValue) {
+                    if (newValue != null) {
+                        onEntryRemovedFromCache(key, oldValue);
+                    }
+                }
+            };
+
+    private final Context mAppContext;
+    private final VideoPreloaderFactory mVideoPreloaderFactory;
+
+    private int mMaxVideoCount = DEFAULT_MAX_VIDEO_COUNT;
+
+    @VisibleForTesting
+    InstantVideoPreloadManager(Context context, VideoPreloaderFactory factory) {
+        mAppContext = context.getApplicationContext();
+        mVideoPreloaderFactory = factory;
+    }
+
+    /**
+     * Starts to preload the video with the given URI.
+     *
+     * @param videoUri The URI of the video to preload.
+     */
+    public void preload(@NonNull Uri videoUri) {
+        if (videoUri == null) {
+            throw new IllegalArgumentException("The video URI shouldn't be null.");
+        }
+        if (DEBUG) Log.d(TAG, "Preload " + videoUri);
+        VideoPreloader preloader = mVideoCache.get(videoUri);
+        if (preloader == null) {
+            mVideoCache.put(videoUri, startVideoPreloading(videoUri));
+        } else {
+            mVideoCache.put(videoUri, preloader);
+        }
+        if (mVideoCache.size() > mMaxVideoCount) {
+            if (DEBUG) {
+                Log.d(TAG, "Reached the limit of the video count. Resizing to " + mMaxVideoCount);
+            }
+            mVideoCache.resize(mMaxVideoCount);
+        }
+    }
+
+    @VisibleForTesting
+    int getCacheSize() {
+        return mVideoCache.size();
+    }
+
+    private void onEntryRemovedFromCache(Uri videoUri, VideoPreloader preloader) {
+        preloader.stop();
+    }
+
+    /**
+     * Clears the cache and evict all the videos.
+     */
+    public void clearCache() {
+        mVideoCache.evictAll();
+    }
+
+    /**
+     * Sets the limit of the total size of the preloaded video contents in bytes.
+     *
+     * @param size The maximum cache size in bytes.
+     */
+    public void setMaxCacheSize(int size) {
+        if (size <= 0) {
+            throw new IllegalArgumentException("The maximum cache size should be greater than 0.");
+        }
+        // TODO: Implement.
+    }
+
+    /**
+     * Sets the maximum count of videos to preload.
+     *
+     * @param count The maximum count of the videos to be preloaded.
+     */
+    public void setMaxPreloadVideoCount(int count) {
+        if (count <= 0) {
+            throw new IllegalArgumentException("The maximum video count should be greater than 0.");
+        }
+        mMaxVideoCount = count;
+        mVideoCache.resize(count);
+    }
+
+    private VideoPreloader startVideoPreloading(Uri videoUri) {
+        VideoPreloader preloader = mVideoPreloaderFactory.createVideoPreloader(videoUri);
+        preloader.start();
+        return preloader;
+    }
+
+    @VisibleForTesting
+    interface VideoPreloaderFactory {
+        VideoPreloader createVideoPreloader(Uri videoUri);
+    }
+
+    @VisibleForTesting
+    interface VideoPreloader {
+        void start();
+        void stop();
+    }
+
+    private static class InternalVideoPreloaderFactory implements VideoPreloaderFactory {
+        @Override
+        public VideoPreloader createVideoPreloader(Uri videoUri) {
+            return new AsyncTaskVideoPreloader(videoUri);
+        }
+    }
+
+    private static class AsyncTaskVideoPreloader extends AsyncTask<Void, Void, Void>
+            implements VideoPreloader {
+        private Uri mVideoUri;
+
+        private AsyncTaskVideoPreloader(Uri videoUri) {
+            mVideoUri = videoUri;
+        }
+
+        @Override
+        public void start() {
+            executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+        }
+
+        @Override
+        public void stop() {
+            cancel(true);
+        }
+
+        @Override
+        protected Void doInBackground(Void... params) {
+            // TODO: Implement.
+            return null;
+        }
+    }
+}
diff --git a/instantvideo/src/android/support/media/instantvideo/widget/InstantVideoView.java b/instantvideo/src/android/support/media/instantvideo/widget/InstantVideoView.java
new file mode 100644
index 0000000..84ebfb6
--- /dev/null
+++ b/instantvideo/src/android/support/media/instantvideo/widget/InstantVideoView.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.instantvideo.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.VideoView;
+
+/**
+ * Displays a video or an image. This class provides a high level interface for applications to play
+ * a video. When the video isn't playing, it displays an image instead if set.
+ *
+ * <p>A developer can preload a video by calling
+ * {@link android.support.media.instantvideo.preload.InstantVideoPreloadManager#preload}, so that
+ * the video can play right after {@link #start} is called.
+ *
+ * @see android.support.media.instantvideo.preload.InstantVideoPreloadManager
+ */
+public class InstantVideoView extends FrameLayout {
+    private static final String TAG = "InstantVideoView";
+
+    private final VideoView mVideoView;
+    private final ImageView mImageView;
+
+    public InstantVideoView(Context context) {
+        this(context, null, 0);
+    }
+
+    public InstantVideoView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public InstantVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        mVideoView = new VideoView(context, attrs, defStyleAttr);
+        mImageView = new ImageView(context, attrs, defStyleAttr);
+        addView(mVideoView, new FrameLayout.LayoutParams(
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Gravity.CENTER));
+        addView(mImageView, new FrameLayout.LayoutParams(
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Gravity.CENTER));
+        mVideoView.setVisibility(GONE);
+    }
+
+    /**
+     * Sets a video URI.
+     *
+     * <p>This method is used to set the video URI to play in this view.
+     *
+     * @param uri the URI of the video.
+     */
+    public void setVideoUri(Uri uri) {
+        mVideoView.setVideoURI(uri);
+    }
+
+    /**
+     * Sets a drawable as the default image of this view.
+     *
+     * @param drawable the Drawable to set, or {@code null} to clear the content.
+     *
+     * @see ImageView#setImageDrawable
+     */
+    public void setImageDrawable(Drawable drawable) {
+        mImageView.setImageDrawable(drawable);
+    }
+
+    /**
+     * Starts the video playback.
+     */
+    public void start() {
+        reset();
+        mVideoView.setVisibility(VISIBLE);
+        mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+            @Override
+            public void onPrepared(MediaPlayer mp) {
+                mVideoView.start();
+                mImageView.setVisibility(GONE);
+            }
+        });
+        mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+            @Override
+            public boolean onError(MediaPlayer mp, int what, int extra) {
+                mVideoView.setVisibility(GONE);
+                return false;
+            }
+        });
+    }
+
+    /**
+     * Stops the video playback.
+     */
+    public void stop() {
+        mVideoView.stopPlayback();
+        mVideoView.setVisibility(GONE);
+        mImageView.setVisibility(VISIBLE);
+    }
+
+    /**
+     * Seeks to the given position.
+     *
+     * @param position The position of the video to seek to. It's the offset from the start of the
+     * video.
+     */
+    public void seekTo(int position) {
+        mVideoView.seekTo(position);
+    }
+
+    /**
+     * Returns the current playback position which is the offset from the start of the video.
+     */
+    public int getCurrentPosition() {
+        return mVideoView.getCurrentPosition();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        // In case the view is recycled, reset the view when it's detached.
+        reset();
+        super.onDetachedFromWindow();
+    }
+
+    private void reset() {
+        mVideoView.setOnPreparedListener(null);
+        stop();
+    }
+}
diff --git a/instantvideo/tests/AndroidManifest.xml b/instantvideo/tests/AndroidManifest.xml
new file mode 100644
index 0000000..7127c0a
--- /dev/null
+++ b/instantvideo/tests/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+   Copyright (C) 2017 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:tools="http://schemas.android.com/tools"
+          package="android.support.media.instantvideo.test">
+
+    <uses-sdk
+            android:minSdkVersion="14"
+            tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
+                      android.support.test.espresso, android.support.test.espresso.idling"/>
+
+    <application>
+        <uses-library android:name="android.test.runner"/>
+    </application>
+
+    <instrumentation
+            android:name="android.test.InstrumentationTestRunner"
+            android:targetPackage="android.support.media.instantvideo.test"/>
+
+</manifest>
diff --git a/v8/Android.mk b/instantvideo/tests/NO_DOCS
similarity index 69%
rename from v8/Android.mk
rename to instantvideo/tests/NO_DOCS
index 14ff0aa..4dad694 100644
--- a/v8/Android.mk
+++ b/instantvideo/tests/NO_DOCS
@@ -1,4 +1,4 @@
-# Copyright (C) 2014 The Android Open Source Project
+# Copyright (C) 2017 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.
@@ -12,5 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH:= $(call my-dir)
-include $(call all-makefiles-under,$(LOCAL_PATH))
+Having this file, named NO_DOCS, in a directory will prevent
+Android javadocs from being generated for java files under
+the directory. This is especially useful for test projects.
diff --git a/instantvideo/tests/src/android/support/media/instantvideo/preload/InstantVideoPreloadManagerTest.java b/instantvideo/tests/src/android/support/media/instantvideo/preload/InstantVideoPreloadManagerTest.java
new file mode 100644
index 0000000..d50ece8
--- /dev/null
+++ b/instantvideo/tests/src/android/support/media/instantvideo/preload/InstantVideoPreloadManagerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.instantvideo.preload;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.when;
+
+import android.net.Uri;
+import android.support.media.instantvideo.preload.InstantVideoPreloadManager.VideoPreloader;
+import android.support.media.instantvideo.preload.InstantVideoPreloadManager.VideoPreloaderFactory;
+import android.support.test.filters.SmallTest;
+import android.test.AndroidTestCase;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for IntentVideoPreloadManager.
+ */
+@SmallTest
+public class InstantVideoPreloadManagerTest extends AndroidTestCase {
+    private static final Uri PRELOAD_VIDEO_URI_1 = Uri.parse("http://test/test1.mp4");
+    private static final Uri PRELOAD_VIDEO_URI_2 = Uri.parse("http://test/test2.mp4");
+
+    private InstantVideoPreloadManager mPreloadManager;
+    @Mock private VideoPreloaderFactory mMockVideoPreloaderFactory;
+    @Mock private VideoPreloader mMockVideoPreloader;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        when(mMockVideoPreloaderFactory.createVideoPreloader(any(Uri.class)))
+                .thenReturn(mMockVideoPreloader);
+        mPreloadManager = new InstantVideoPreloadManager(getContext(), mMockVideoPreloaderFactory);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mPreloadManager.clearCache();
+        super.tearDown();
+    }
+
+    public void testPreload() {
+        mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
+        assertCacheSize(1);
+        mPreloadManager.preload(PRELOAD_VIDEO_URI_2);
+        assertCacheSize(2);
+    }
+
+    public void testPreload_duplicate() {
+        mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
+        mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
+        assertCacheSize(1);
+    }
+
+    public void testMaxPreloadVideoCount() {
+        mPreloadManager.setMaxPreloadVideoCount(1);
+        mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
+        assertCacheSize(1);
+        mPreloadManager.preload(PRELOAD_VIDEO_URI_2);
+        assertCacheSize(1);
+    }
+
+    public void testClearCache() {
+        mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
+        mPreloadManager.preload(PRELOAD_VIDEO_URI_2);
+        mPreloadManager.clearCache();
+        assertCacheSize(0);
+    }
+
+    private void assertCacheSize(int expected) {
+        int cacheSize = mPreloadManager.getCacheSize();
+        assertEquals("The cache size should be " + expected + ", but was " + cacheSize, expected,
+                cacheSize);
+    }
+}
diff --git a/media-compat/Android.mk b/media-compat/Android.mk
index 0050ea4..37acd06 100644
--- a/media-compat/Android.mk
+++ b/media-compat/Android.mk
@@ -35,10 +35,10 @@
     $(call all-java-files-under,api22) \
     $(call all-java-files-under,api23) \
     $(call all-java-files-under,api24) \
+    $(call all-java-files-under,api26) \
     $(call all-java-files-under,java) \
     $(call all-Iaidl-files-under,java)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-annotations
diff --git a/media-compat/AndroidManifest-make.xml b/media-compat/AndroidManifest-make.xml
deleted file mode 100644
index c971549..0000000
--- a/media-compat/AndroidManifest-make.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.support.mediacompat">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.mediacompat"/>
-    <application />
-</manifest>
diff --git a/media-compat/AndroidManifest.xml b/media-compat/AndroidManifest.xml
index 5f7b051..4e73a70 100644
--- a/media-compat/AndroidManifest.xml
+++ b/media-compat/AndroidManifest.xml
@@ -16,7 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.mediacompat">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.mediacompat"/>
+    <uses-sdk android:minSdkVersion="14" tools:overrideLibrary="android.support.mediacompat"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/media-compat/api21/android/support/v4/media/MediaBrowserCompatApi21.java b/media-compat/api21/android/support/v4/media/MediaBrowserCompatApi21.java
index 9a0b0f3..0634309 100644
--- a/media-compat/api21/android/support/v4/media/MediaBrowserCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/MediaBrowserCompatApi21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.media.browse.MediaBrowser;
@@ -27,7 +26,6 @@
 import java.util.List;
 
 @RequiresApi(21)
-@TargetApi(21)
 class MediaBrowserCompatApi21 {
     static final String NULL_MEDIA_ITEM_ID =
             "android.support.v4.media.MediaBrowserCompat.NULL_MEDIA_ITEM";
diff --git a/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java b/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
index 4035e63..60b5d63 100644
--- a/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.Intent;
 import android.media.browse.MediaBrowser;
@@ -31,7 +30,6 @@
 import java.util.List;
 
 @RequiresApi(21)
-@TargetApi(21)
 class MediaBrowserServiceCompatApi21 {
 
     public static Object createService(Context context, ServiceCompatProxy serviceProxy) {
diff --git a/media-compat/api21/android/support/v4/media/MediaDescriptionCompatApi21.java b/media-compat/api21/android/support/v4/media/MediaDescriptionCompatApi21.java
index 556d092..8361711 100644
--- a/media-compat/api21/android/support/v4/media/MediaDescriptionCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/MediaDescriptionCompatApi21.java
@@ -15,7 +15,6 @@
  */
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.graphics.Bitmap;
 import android.media.MediaDescription;
 import android.net.Uri;
@@ -24,7 +23,6 @@
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(21)
-@TargetApi(21)
 class MediaDescriptionCompatApi21 {
 
     public static String getMediaId(Object descriptionObj) {
diff --git a/media-compat/api21/android/support/v4/media/MediaMetadataCompatApi21.java b/media-compat/api21/android/support/v4/media/MediaMetadataCompatApi21.java
index ed30c29..6020a08 100644
--- a/media-compat/api21/android/support/v4/media/MediaMetadataCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/MediaMetadataCompatApi21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.graphics.Bitmap;
 import android.media.MediaMetadata;
 import android.media.Rating;
@@ -26,7 +25,6 @@
 import java.util.Set;
 
 @RequiresApi(21)
-@TargetApi(21)
 class MediaMetadataCompatApi21 {
     public static Set<String> keySet(Object metadataObj) {
         return ((MediaMetadata)metadataObj).keySet();
diff --git a/media-compat/api21/android/support/v4/media/ParceledListSliceAdapterApi21.java b/media-compat/api21/android/support/v4/media/ParceledListSliceAdapterApi21.java
index ab5e4ef..6af9903 100644
--- a/media-compat/api21/android/support/v4/media/ParceledListSliceAdapterApi21.java
+++ b/media-compat/api21/android/support/v4/media/ParceledListSliceAdapterApi21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.media.browse.MediaBrowser;
 import android.support.annotation.RequiresApi;
 
@@ -28,7 +27,6 @@
  * An adapter class for accessing the hidden framework classes, ParceledListSlice using reflection.
  */
 @RequiresApi(21)
-@TargetApi(21)
 class ParceledListSliceAdapterApi21 {
     private static Constructor sConstructor;
     static {
diff --git a/media-compat/api21/android/support/v4/media/VolumeProviderCompatApi21.java b/media-compat/api21/android/support/v4/media/VolumeProviderCompatApi21.java
index 66f5144..cefbf59 100644
--- a/media-compat/api21/android/support/v4/media/VolumeProviderCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/VolumeProviderCompatApi21.java
@@ -16,12 +16,10 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.media.VolumeProvider;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(21)
-@TargetApi(21)
 class VolumeProviderCompatApi21 {
     public static Object createVolumeProvider(int volumeControl, int maxVolume, int currentVolume,
             final Delegate delegate) {
diff --git a/media-compat/api21/android/support/v4/media/session/MediaControllerCompatApi21.java b/media-compat/api21/android/support/v4/media/session/MediaControllerCompatApi21.java
index c498f7f..c13d901 100644
--- a/media-compat/api21/android/support/v4/media/session/MediaControllerCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/session/MediaControllerCompatApi21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -37,7 +36,6 @@
 import java.util.List;
 
 @RequiresApi(21)
-@TargetApi(21)
 class MediaControllerCompatApi21 {
     public static Object fromToken(Context context, Object sessionToken) {
         return new MediaController(context, (MediaSession.Token) sessionToken);
diff --git a/media-compat/api21/android/support/v4/media/session/MediaSessionCompatApi21.java b/media-compat/api21/android/support/v4/media/session/MediaSessionCompatApi21.java
index 38c42cb..72c5c8c 100644
--- a/media-compat/api21/android/support/v4/media/session/MediaSessionCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/session/MediaSessionCompatApi21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
@@ -37,7 +36,6 @@
 import java.util.List;
 
 @RequiresApi(21)
-@TargetApi(21)
 class MediaSessionCompatApi21 {
     public static Object createSession(Context context, String tag) {
         return new MediaSession(context, tag);
diff --git a/media-compat/api21/android/support/v4/media/session/PlaybackStateCompatApi21.java b/media-compat/api21/android/support/v4/media/session/PlaybackStateCompatApi21.java
index df6a203..577f35d 100644
--- a/media-compat/api21/android/support/v4/media/session/PlaybackStateCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/session/PlaybackStateCompatApi21.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
@@ -24,7 +23,6 @@
 import java.util.List;
 
 @RequiresApi(21)
-@TargetApi(21)
 class PlaybackStateCompatApi21 {
     public static int getState(Object stateObj) {
         return ((PlaybackState)stateObj).getState();
diff --git a/media-compat/api22/android/support/v4/media/session/MediaSessionCompatApi22.java b/media-compat/api22/android/support/v4/media/session/MediaSessionCompatApi22.java
index 687e965..b7ddc99 100644
--- a/media-compat/api22/android/support/v4/media/session/MediaSessionCompatApi22.java
+++ b/media-compat/api22/android/support/v4/media/session/MediaSessionCompatApi22.java
@@ -15,12 +15,10 @@
  */
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.media.session.MediaSession;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(22)
-@TargetApi(22)
 class MediaSessionCompatApi22 {
 
     public static void setRatingType(Object sessionObj, int type) {
diff --git a/media-compat/api22/android/support/v4/media/session/PlaybackStateCompatApi22.java b/media-compat/api22/android/support/v4/media/session/PlaybackStateCompatApi22.java
index ff398b9..6be3f4b 100644
--- a/media-compat/api22/android/support/v4/media/session/PlaybackStateCompatApi22.java
+++ b/media-compat/api22/android/support/v4/media/session/PlaybackStateCompatApi22.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
@@ -24,7 +23,6 @@
 import java.util.List;
 
 @RequiresApi(22)
-@TargetApi(22)
 class PlaybackStateCompatApi22 {
     public static Bundle getExtras(Object stateObj) {
         return ((PlaybackState)stateObj).getExtras();
diff --git a/media-compat/api23/android/support/v4/media/MediaBrowserCompatApi23.java b/media-compat/api23/android/support/v4/media/MediaBrowserCompatApi23.java
index 308c490..0e37570 100644
--- a/media-compat/api23/android/support/v4/media/MediaBrowserCompatApi23.java
+++ b/media-compat/api23/android/support/v4/media/MediaBrowserCompatApi23.java
@@ -16,14 +16,12 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.media.browse.MediaBrowser;
 import android.os.Parcel;
 import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(23)
-@TargetApi(23)
 class MediaBrowserCompatApi23 {
 
     public static Object createItemCallback(ItemCallback callback) {
diff --git a/media-compat/api23/android/support/v4/media/MediaBrowserServiceCompatApi23.java b/media-compat/api23/android/support/v4/media/MediaBrowserServiceCompatApi23.java
index 1091dec..7b30ad5 100644
--- a/media-compat/api23/android/support/v4/media/MediaBrowserServiceCompatApi23.java
+++ b/media-compat/api23/android/support/v4/media/MediaBrowserServiceCompatApi23.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.media.browse.MediaBrowser;
 import android.os.Parcel;
@@ -24,7 +23,6 @@
 import android.support.v4.media.MediaBrowserServiceCompatApi21.ResultWrapper;
 
 @RequiresApi(23)
-@TargetApi(23)
 class MediaBrowserServiceCompatApi23 {
 
     public static Object createService(Context context, ServiceCompatProxy serviceProxy) {
diff --git a/media-compat/api23/android/support/v4/media/MediaDescriptionCompatApi23.java b/media-compat/api23/android/support/v4/media/MediaDescriptionCompatApi23.java
index 862fbbf..957cc54 100644
--- a/media-compat/api23/android/support/v4/media/MediaDescriptionCompatApi23.java
+++ b/media-compat/api23/android/support/v4/media/MediaDescriptionCompatApi23.java
@@ -15,13 +15,11 @@
  */
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.media.MediaDescription;
 import android.net.Uri;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(23)
-@TargetApi(23)
 class MediaDescriptionCompatApi23 extends MediaDescriptionCompatApi21 {
     public static Uri getMediaUri(Object descriptionObj) {
         return ((MediaDescription) descriptionObj).getMediaUri();
diff --git a/media-compat/api23/android/support/v4/media/session/MediaControllerCompatApi23.java b/media-compat/api23/android/support/v4/media/session/MediaControllerCompatApi23.java
index 92e49fc..12ce345 100644
--- a/media-compat/api23/android/support/v4/media/session/MediaControllerCompatApi23.java
+++ b/media-compat/api23/android/support/v4/media/session/MediaControllerCompatApi23.java
@@ -16,14 +16,12 @@
 
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.media.session.MediaController;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(23)
-@TargetApi(23)
 class MediaControllerCompatApi23 {
 
     public static class TransportControls extends MediaControllerCompatApi21.TransportControls {
diff --git a/media-compat/api23/android/support/v4/media/session/MediaSessionCompatApi23.java b/media-compat/api23/android/support/v4/media/session/MediaSessionCompatApi23.java
index ddb25fc..2818f02 100644
--- a/media-compat/api23/android/support/v4/media/session/MediaSessionCompatApi23.java
+++ b/media-compat/api23/android/support/v4/media/session/MediaSessionCompatApi23.java
@@ -16,13 +16,11 @@
 
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(23)
-@TargetApi(23)
 class MediaSessionCompatApi23 {
 
     public static Object createCallback(Callback callback) {
diff --git a/media-compat/api24/android/support/v4/media/MediaBrowserCompatApi24.java b/media-compat/api24/android/support/v4/media/MediaBrowserCompatApi24.java
index 45a428c..4842cc1 100644
--- a/media-compat/api24/android/support/v4/media/MediaBrowserCompatApi24.java
+++ b/media-compat/api24/android/support/v4/media/MediaBrowserCompatApi24.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.media.browse.MediaBrowser;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
@@ -25,7 +24,6 @@
 import java.util.List;
 
 @RequiresApi(24)
-@TargetApi(24)
 class MediaBrowserCompatApi24 {
     public static Object createSubscriptionCallback(SubscriptionCallback callback) {
         return new SubscriptionCallbackProxy<>(callback);
diff --git a/media-compat/api24/android/support/v4/media/MediaBrowserServiceCompatApi24.java b/media-compat/api24/android/support/v4/media/MediaBrowserServiceCompatApi24.java
index 2440864..a7e5e19 100644
--- a/media-compat/api24/android/support/v4/media/MediaBrowserServiceCompatApi24.java
+++ b/media-compat/api24/android/support/v4/media/MediaBrowserServiceCompatApi24.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.media.browse.MediaBrowser;
 import android.os.Bundle;
@@ -30,7 +29,6 @@
 import java.util.List;
 
 @RequiresApi(24)
-@TargetApi(24)
 class MediaBrowserServiceCompatApi24 {
     private static final String TAG = "MBSCompatApi24";
 
diff --git a/media-compat/api24/android/support/v4/media/session/MediaControllerCompatApi24.java b/media-compat/api24/android/support/v4/media/session/MediaControllerCompatApi24.java
index 3c8b650..c336d70 100644
--- a/media-compat/api24/android/support/v4/media/session/MediaControllerCompatApi24.java
+++ b/media-compat/api24/android/support/v4/media/session/MediaControllerCompatApi24.java
@@ -16,14 +16,12 @@
 
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.media.session.MediaController;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(24)
-@TargetApi(24)
 class MediaControllerCompatApi24 {
 
     public static class TransportControls extends MediaControllerCompatApi23.TransportControls {
diff --git a/media-compat/api24/android/support/v4/media/session/MediaSessionCompatApi24.java b/media-compat/api24/android/support/v4/media/session/MediaSessionCompatApi24.java
index 506b04f..cd358e5 100644
--- a/media-compat/api24/android/support/v4/media/session/MediaSessionCompatApi24.java
+++ b/media-compat/api24/android/support/v4/media/session/MediaSessionCompatApi24.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.media.session.MediaSession;
 import android.net.Uri;
 import android.os.Bundle;
@@ -27,7 +26,6 @@
 import java.lang.reflect.Method;
 
 @RequiresApi(24)
-@TargetApi(24)
 class MediaSessionCompatApi24 {
     private static final String TAG = "MediaSessionCompatApi24";
 
diff --git a/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java b/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
new file mode 100644
index 0000000..b2c4ac0
--- /dev/null
+++ b/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.media.session;
+
+import android.media.session.MediaController;
+
+class MediaControllerCompatApi26 {
+    public static Object createCallback(Callback callback) {
+        return new CallbackProxy<Callback>(callback);
+    }
+
+    public static int getRepeatMode(Object controllerObj) {
+        return ((MediaController) controllerObj).getRepeatMode();
+    }
+
+    public static boolean isShuffleModeEnabled(Object controllerObj) {
+        return ((MediaController) controllerObj).isShuffleModeEnabled();
+    }
+
+    public static class TransportControls extends MediaControllerCompatApi23.TransportControls {
+        public static void setRepeatMode(Object controlsObj, int repeatMode) {
+            ((MediaController.TransportControls) controlsObj).setRepeatMode(repeatMode);
+        }
+
+        public static void setShuffleModeEnabled(Object controlsObj, boolean enabled) {
+            ((MediaController.TransportControls) controlsObj).setShuffleModeEnabled(enabled);
+        }
+    }
+
+    public interface Callback extends MediaControllerCompatApi21.Callback {
+        void onRepeatModeChanged(int repeatMode);
+        void onShuffleModeChanged(boolean enabled);
+    }
+
+    static class CallbackProxy<T extends Callback> extends MediaControllerCompatApi21
+            .CallbackProxy<T> {
+        CallbackProxy(T callback) {
+            super(callback);
+        }
+
+        @Override
+        public void onRepeatModeChanged(int repeatMode) {
+            mCallback.onRepeatModeChanged(repeatMode);
+        }
+
+        @Override
+        public void onShuffleModeChanged(boolean enabled) {
+            mCallback.onShuffleModeChanged(enabled);
+        }
+    }
+}
diff --git a/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java b/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java
new file mode 100644
index 0000000..80c5fd0
--- /dev/null
+++ b/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.media.session;
+
+import android.media.session.MediaSession;
+
+class MediaSessionCompatApi26 {
+
+    public static Object createCallback(Callback callback) {
+        return new CallbackProxy<Callback>(callback);
+    }
+
+    public static void setRepeatMode(Object sessionObj, int repeatMode) {
+        ((MediaSession) sessionObj).setRepeatMode(repeatMode);
+    }
+
+    public static void setShuffleModeEnabled(Object sessionObj, boolean enabled) {
+        ((MediaSession) sessionObj).setShuffleModeEnabled(enabled);
+    }
+
+    public interface Callback extends MediaSessionCompatApi24.Callback {
+        void onSetRepeatMode(int repeatMode);
+        void onSetShuffleModeEnabled(boolean enabled);
+    }
+
+    static class CallbackProxy<T extends Callback>
+            extends MediaSessionCompatApi24.CallbackProxy<T> {
+        CallbackProxy(T callback) {
+            super(callback);
+        }
+
+        @Override
+        public void onSetRepeatMode(int repeatMode) {
+            mCallback.onSetRepeatMode(repeatMode);
+        }
+
+        @Override
+        public void onSetShuffleModeEnabled(boolean enabled) {
+            mCallback.onSetShuffleModeEnabled(enabled);
+        }
+    }
+}
diff --git a/media-compat/build.gradle b/media-compat/build.gradle
index 8dd44bf..e7c487c 100644
--- a/media-compat/build.gradle
+++ b/media-compat/build.gradle
@@ -1,31 +1,27 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'support-media-compat'
 
 dependencies {
     compile project(':support-annotations')
     compile project(':support-compat')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile 'org.mockito:mockito-core:1.9.5'
-    androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
-    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'ics',
                 'jellybean-mr2',
@@ -34,70 +30,15 @@
                 'api22',
                 'api23',
                 'api24',
+                'api26',
                 'java'
         ]
         main.aidl.srcDirs = ['java']
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-        exclude('android/content/pm/**')
-        exclude('android/service/media/**')
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Library v4'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support Library v4'
+    inceptionYear '2011'
+    description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
 }
diff --git a/media-compat/ics/android/support/v4/media/session/MediaSessionCompatApi14.java b/media-compat/ics/android/support/v4/media/session/MediaSessionCompatApi14.java
index b6f7a38..cb86b2b 100644
--- a/media-compat/ics/android/support/v4/media/session/MediaSessionCompatApi14.java
+++ b/media-compat/ics/android/support/v4/media/session/MediaSessionCompatApi14.java
@@ -15,7 +15,6 @@
  */
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.graphics.Bitmap;
@@ -26,7 +25,6 @@
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(14)
-@TargetApi(14)
 class MediaSessionCompatApi14 {
     /***** RemoteControlClient States, we only need none as the others were public *******/
     final static int RCC_PLAYSTATE_NONE = 0;
diff --git a/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl b/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl
index d905350..d1d143d 100644
--- a/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl
+++ b/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl
@@ -37,4 +37,6 @@
     void onQueueTitleChanged(CharSequence title);
     void onExtrasChanged(in Bundle extras);
     void onVolumeInfoChanged(in ParcelableVolumeInfo info);
+    void onRepeatModeChanged(int repeatMode);
+    void onShuffleModeChanged(boolean enabled);
 }
diff --git a/media-compat/java/android/support/v4/media/session/IMediaSession.aidl b/media-compat/java/android/support/v4/media/session/IMediaSession.aidl
index c7705e8..4f2e38a 100644
--- a/media-compat/java/android/support/v4/media/session/IMediaSession.aidl
+++ b/media-compat/java/android/support/v4/media/session/IMediaSession.aidl
@@ -52,6 +52,8 @@
     CharSequence getQueueTitle() = 29;
     Bundle getExtras() = 30;
     int getRatingType() = 31;
+    int getRepeatMode() = 36;
+    boolean isShuffleModeEnabled() = 37;
 
     // These commands are for the TransportControls
     void prepare() = 32;
@@ -71,5 +73,7 @@
     void rewind() = 22;
     void seekTo(long pos) = 23;
     void rate(in RatingCompat rating) = 24;
+    void setRepeatMode(int repeatMode) = 38;
+    void setShuffleModeEnabled(boolean shuffleMode) = 39;
     void sendCustomAction(String action, in Bundle args) = 25;
 }
diff --git a/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java b/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
index 74658a8..94030bc 100644
--- a/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
@@ -149,7 +149,9 @@
         }
         mToken = session.getSessionToken();
 
-        if (android.os.Build.VERSION.SDK_INT >= 24) {
+        if (android.os.Build.VERSION.SDK_INT >= 26) {
+            mImpl = new MediaControllerImplApi26(context, session);
+        } else if (android.os.Build.VERSION.SDK_INT >= 24) {
             mImpl = new MediaControllerImplApi24(context, session);
         } else if (android.os.Build.VERSION.SDK_INT >= 23) {
             mImpl = new MediaControllerImplApi23(context, session);
@@ -174,7 +176,9 @@
         }
         mToken = sessionToken;
 
-        if (android.os.Build.VERSION.SDK_INT >= 24) {
+        if (android.os.Build.VERSION.SDK_INT >= 26) {
+            mImpl = new MediaControllerImplApi26(context, sessionToken);
+        } else if (android.os.Build.VERSION.SDK_INT >= 24) {
             mImpl = new MediaControllerImplApi24(context, sessionToken);
         } else if (android.os.Build.VERSION.SDK_INT >= 23) {
             mImpl = new MediaControllerImplApi23(context, sessionToken);
@@ -269,6 +273,25 @@
     }
 
     /**
+     * Get the repeat mode for this session.
+     *
+     * @return The latest repeat mode set to the session, or
+     *         {@link PlaybackStateCompat#REPEAT_MODE_NONE} if not set.
+     */
+    public int getRepeatMode() {
+        return mImpl.getRepeatMode();
+    }
+
+    /**
+     * Return whether the shuffle mode is enabled for this session.
+     *
+     * @return {@code true} if the shuffle mode is enabled, {@code false} if disabled or not set.
+     */
+    public boolean isShuffleModeEnabled() {
+        return mImpl.isShuffleModeEnabled();
+    }
+
+    /**
      * Get the flags for this session. Flags are defined in
      * {@link MediaSessionCompat}.
      *
@@ -430,7 +453,9 @@
         boolean mRegistered = false;
 
         public Callback() {
-            if (android.os.Build.VERSION.SDK_INT >= 21) {
+            if (android.os.Build.VERSION.SDK_INT >= 26) {
+                mCallbackObj = MediaControllerCompatApi26.createCallback(new StubApi26());
+            } else if (android.os.Build.VERSION.SDK_INT >= 21) {
                 mCallbackObj = MediaControllerCompatApi21.createCallback(new StubApi21());
             } else {
                 mCallbackObj = new StubCompat();
@@ -510,6 +535,25 @@
         public void onAudioInfoChanged(PlaybackInfo info) {
         }
 
+        /**
+         * Override to handle changes to the repeat mode.
+         *
+         * @param repeatMode The repeat mode. It should be one of followings:
+         *            {@link PlaybackStateCompat#REPEAT_MODE_NONE},
+         *            {@link PlaybackStateCompat#REPEAT_MODE_ONE},
+         *            {@link PlaybackStateCompat#REPEAT_MODE_ALL}
+         */
+        public void onRepeatModeChanged(@PlaybackStateCompat.RepeatMode int repeatMode) {
+        }
+
+        /**
+         * Override to handle changes to the shuffle mode.
+         *
+         * @param enabled {@code true} if the shuffle mode is enabled, {@code false} otherwise.
+         */
+        public void onShuffleModeChanged(boolean enabled) {
+        }
+
         @Override
         public void binderDied() {
             onSessionDestroyed();
@@ -578,6 +622,18 @@
             }
         }
 
+        private class StubApi26 extends StubApi21 implements MediaControllerCompatApi26.Callback {
+            @Override
+            public void onRepeatModeChanged(@PlaybackStateCompat.RepeatMode int repeatMode) {
+                Callback.this.onRepeatModeChanged(repeatMode);
+            }
+
+            @Override
+            public void onShuffleModeChanged(boolean enabled) {
+                Callback.this.onShuffleModeChanged(enabled);
+            }
+        }
+
         private class StubCompat extends IMediaControllerCallback.Stub {
 
             StubCompat() {
@@ -614,6 +670,16 @@
             }
 
             @Override
+            public void onRepeatModeChanged(int repeatMode) throws RemoteException {
+                mHandler.post(MessageHandler.MSG_UPDATE_REPEAT_MODE, repeatMode, null);
+            }
+
+            @Override
+            public void onShuffleModeChanged(boolean enabled) throws RemoteException {
+                mHandler.post(MessageHandler.MSG_UPDATE_SHUFFLE_MODE, enabled, null);
+            }
+
+            @Override
             public void onExtrasChanged(Bundle extras) throws RemoteException {
                 mHandler.post(MessageHandler.MSG_UPDATE_EXTRAS, extras, null);
             }
@@ -638,6 +704,8 @@
             private static final int MSG_UPDATE_QUEUE_TITLE = 6;
             private static final int MSG_UPDATE_EXTRAS = 7;
             private static final int MSG_DESTROYED = 8;
+            private static final int MSG_UPDATE_REPEAT_MODE = 9;
+            private static final int MSG_UPDATE_SHUFFLE_MODE = 10;
 
             public MessageHandler(Looper looper) {
                 super(looper);
@@ -664,6 +732,12 @@
                     case MSG_UPDATE_QUEUE_TITLE:
                         onQueueTitleChanged((CharSequence) msg.obj);
                         break;
+                    case MSG_UPDATE_REPEAT_MODE:
+                        onRepeatModeChanged((int) msg.obj);
+                        break;
+                    case MSG_UPDATE_SHUFFLE_MODE:
+                        onShuffleModeChanged((boolean) msg.obj);
+                        break;
                     case MSG_UPDATE_EXTRAS:
                         onExtrasChanged((Bundle) msg.obj);
                         break;
@@ -839,6 +913,23 @@
         public abstract void setRating(RatingCompat rating);
 
         /**
+         * Set the repeat mode for this session.
+         *
+         * @param repeatMode The repeat mode. Must be one of the followings:
+         *            {@link PlaybackStateCompat#REPEAT_MODE_NONE},
+         *            {@link PlaybackStateCompat#REPEAT_MODE_ONE},
+         *            {@link PlaybackStateCompat#REPEAT_MODE_ALL}
+         */
+        public abstract void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode);
+
+        /**
+         * Set the shuffle mode for this session.
+         *
+         * @param enabled {@code true} to enable the shuffle mode, {@code false} to disable.
+         */
+        public abstract void setShuffleModeEnabled(boolean enabled);
+
+        /**
          * Send a custom action for the {@link MediaSessionCompat} to perform.
          *
          * @param customAction The action to perform.
@@ -963,6 +1054,8 @@
         CharSequence getQueueTitle();
         Bundle getExtras();
         int getRatingType();
+        int getRepeatMode();
+        boolean isShuffleModeEnabled();
         long getFlags();
         PlaybackInfo getPlaybackInfo();
         PendingIntent getSessionActivity();
@@ -1099,6 +1192,26 @@
         }
 
         @Override
+        public int getRepeatMode() {
+            try {
+                return mBinder.getRepeatMode();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in getRepeatMode. " + e);
+            }
+            return 0;
+        }
+
+        @Override
+        public boolean isShuffleModeEnabled() {
+            try {
+                return mBinder.isShuffleModeEnabled();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in isShuffleModeEnabled. " + e);
+            }
+            return false;
+        }
+
+        @Override
         public long getFlags() {
             try {
                 return mBinder.getFlags();
@@ -1336,6 +1449,24 @@
         }
 
         @Override
+        public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
+            try {
+                mBinder.setRepeatMode(repeatMode);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in setRepeatMode. " + e);
+            }
+        }
+
+        @Override
+        public void setShuffleModeEnabled(boolean enabled) {
+            try {
+                mBinder.setShuffleModeEnabled(enabled);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in setShuffleModeEnabled. " + e);
+            }
+        }
+
+        @Override
         public void sendCustomAction(CustomAction customAction, Bundle args) {
             sendCustomAction(customAction.getAction(), args);
         }
@@ -1362,7 +1493,9 @@
         public MediaControllerImplApi21(Context context, MediaSessionCompat session) {
             mControllerObj = MediaControllerCompatApi21.fromToken(context,
                     session.getSessionToken().getToken());
-            requestExtraBinder();
+            if (android.os.Build.VERSION.SDK_INT < 26) {
+                requestExtraBinder();
+            }
         }
 
         public MediaControllerImplApi21(Context context, MediaSessionCompat.Token sessionToken)
@@ -1370,7 +1503,9 @@
             mControllerObj = MediaControllerCompatApi21.fromToken(context,
                     sessionToken.getToken());
             if (mControllerObj == null) throw new RemoteException();
-            requestExtraBinder();
+            if (android.os.Build.VERSION.SDK_INT < 26) {
+                requestExtraBinder();
+            }
         }
 
         @Override
@@ -1387,7 +1522,7 @@
                 } catch (RemoteException e) {
                     Log.e(TAG, "Dead object in registerCallback. " + e);
                 }
-            } else {
+            } else if (android.os.Build.VERSION.SDK_INT < 26) {
                 if (mPendingCallbacks == null) {
                     mPendingCallbacks = new ArrayList<>();
                 }
@@ -1408,7 +1543,7 @@
                 } catch (RemoteException e) {
                     Log.e(TAG, "Dead object in unregisterCallback. " + e);
                 }
-            } else {
+            } else if (android.os.Build.VERSION.SDK_INT < 26) {
                 if (mPendingCallbacks == null) {
                     mPendingCallbacks = new ArrayList<>();
                 }
@@ -1476,6 +1611,30 @@
         }
 
         @Override
+        public int getRepeatMode() {
+            if (mExtraBinder != null) {
+                try {
+                    return mExtraBinder.getRepeatMode();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Dead object in getRepeatMode. " + e);
+                }
+            }
+            return PlaybackStateCompat.REPEAT_MODE_NONE;
+        }
+
+        @Override
+        public boolean isShuffleModeEnabled() {
+            if (mExtraBinder != null) {
+                try {
+                    return mExtraBinder.isShuffleModeEnabled();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Dead object in isShuffleModeEnabled. " + e);
+                }
+            }
+            return false;
+        }
+
+        @Override
         public long getFlags() {
             return MediaControllerCompatApi21.getFlags(mControllerObj);
         }
@@ -1619,6 +1778,26 @@
             }
 
             @Override
+            public void onRepeatModeChanged(final int repeatMode) throws RemoteException {
+                mCallback.mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onRepeatModeChanged(repeatMode);
+                    }
+                });
+            }
+
+            @Override
+            public void onShuffleModeChanged(final boolean enabled) throws RemoteException {
+                mCallback.mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onShuffleModeChanged(enabled);
+                    }
+                });
+            }
+
+            @Override
             public void onExtrasChanged(Bundle extras) throws RemoteException {
                 // Will not be called.
                 throw new AssertionError();
@@ -1715,6 +1894,20 @@
         }
 
         @Override
+        public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
+            Bundle bundle = new Bundle();
+            bundle.putInt(MediaSessionCompat.ACTION_ARGUMENT_REPEAT_MODE, repeatMode);
+            sendCustomAction(MediaSessionCompat.ACTION_SET_REPEAT_MODE, bundle);
+        }
+
+        @Override
+        public void setShuffleModeEnabled(boolean enabled) {
+            Bundle bundle = new Bundle();
+            bundle.putBoolean(MediaSessionCompat.ACTION_ARGUMENT_SHUFFLE_MODE_ENABLED, enabled);
+            sendCustomAction(MediaSessionCompat.ACTION_SET_SHUFFLE_MODE_ENABLED, bundle);
+        }
+
+        @Override
         public void playFromMediaId(String mediaId, Bundle extras) {
             MediaControllerCompatApi21.TransportControls.playFromMediaId(mControlsObj, mediaId,
                     extras);
@@ -1834,4 +2027,50 @@
         }
     }
 
+    static class MediaControllerImplApi26 extends MediaControllerImplApi24 {
+
+        MediaControllerImplApi26(Context context, MediaSessionCompat session) {
+            super(context, session);
+        }
+
+        MediaControllerImplApi26(Context context, MediaSessionCompat.Token sessionToken)
+                throws RemoteException {
+            super(context, sessionToken);
+        }
+
+        @Override
+        public TransportControls getTransportControls() {
+            Object controlsObj = MediaControllerCompatApi21.getTransportControls(mControllerObj);
+            return controlsObj != null ? new TransportControlsApi26(controlsObj) : null;
+        }
+
+        @Override
+        public int getRepeatMode() {
+            return MediaControllerCompatApi26.getRepeatMode(mControllerObj);
+        }
+
+        @Override
+        public boolean isShuffleModeEnabled() {
+            return MediaControllerCompatApi26.isShuffleModeEnabled(mControllerObj);
+        }
+    }
+
+    static class TransportControlsApi26 extends TransportControlsApi24 {
+
+        TransportControlsApi26(Object controlsObj) {
+            super(controlsObj);
+        }
+
+        @Override
+        public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
+            MediaControllerCompatApi26.TransportControls.setRepeatMode(mControlsObj, repeatMode);
+        }
+
+        @Override
+        public void setShuffleModeEnabled(boolean enabled) {
+            MediaControllerCompatApi26.TransportControls.setShuffleModeEnabled(mControlsObj,
+                    enabled);
+        }
+    }
+
 }
diff --git a/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java b/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
index 53e6c70..d57df36 100644
--- a/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -140,6 +140,18 @@
             "android.support.v4.media.session.action.PREPARE_FROM_URI";
 
     /**
+     * Custom action to invoke setRepeatMode() for the forward compatibility.
+     */
+    static final String ACTION_SET_REPEAT_MODE =
+            "android.support.v4.media.session.action.SET_REPEAT_MODE";
+
+    /**
+     * Custom action to invoke setShuffleModeEnabled() for the forward compatibility.
+     */
+    static final String ACTION_SET_SHUFFLE_MODE_ENABLED =
+            "android.support.v4.media.session.action.SET_SHUFFLE_MODE_ENABLED";
+
+    /**
      * Argument for use with {@link #ACTION_PREPARE_FROM_MEDIA_ID} indicating media id to play.
      */
     static final String ACTION_ARGUMENT_MEDIA_ID =
@@ -164,6 +176,19 @@
     static final String ACTION_ARGUMENT_EXTRAS =
             "android.support.v4.media.session.action.ARGUMENT_EXTRAS";
 
+    /**
+     * Argument for use with {@link #ACTION_SET_REPEAT_MODE} indicating repeat mode.
+     */
+    static final String ACTION_ARGUMENT_REPEAT_MODE =
+            "android.support.v4.media.session.action.ARGUMENT_REPEAT_MODE";
+
+    /**
+     * Argument for use with {@link #ACTION_SET_SHUFFLE_MODE_ENABLED} indicating that shuffle mode
+     * is enabled.
+     */
+    static final String ACTION_ARGUMENT_SHUFFLE_MODE_ENABLED =
+            "android.support.v4.media.session.action.ARGUMENT_SHUFFLE_MODE_ENABLED";
+
     static final String EXTRA_BINDER = "android.support.v4.media.session.EXTRA_BINDER";
 
     // Maximum size of the bitmap in dp.
@@ -237,6 +262,10 @@
         }
         if (android.os.Build.VERSION.SDK_INT >= 21) {
             mImpl = new MediaSessionImplApi21(context, tag);
+            if (android.os.Build.VERSION.SDK_INT < 26) {
+                // Set default callback to respond to controllers' extra binder requests.
+                setCallback(new Callback() {});
+            }
             mImpl.setMediaButtonReceiver(mbrIntent);
         } else {
             mImpl = new MediaSessionImplBase(context, tag, mbrComponent, mbrIntent);
@@ -251,7 +280,7 @@
 
     private MediaSessionCompat(Context context, MediaSessionImpl impl) {
         mImpl = impl;
-        if (android.os.Build.VERSION.SDK_INT >= 21) {
+        if (android.os.Build.VERSION.SDK_INT >= 21 && android.os.Build.VERSION.SDK_INT < 26) {
             // Set default callback to respond to controllers' extra binder requests.
             setCallback(new Callback() {});
         }
@@ -501,6 +530,33 @@
     }
 
     /**
+     * Set the repeat mode for this session.
+     * <p>
+     * Note that if this method is not called before, {@link MediaControllerCompat#getRepeatMode}
+     * will return {@link PlaybackStateCompat#REPEAT_MODE_NONE}.
+     *
+     * @param repeatMode The repeat mode. Must be one of the followings:
+     *            {@link PlaybackStateCompat#REPEAT_MODE_NONE},
+     *            {@link PlaybackStateCompat#REPEAT_MODE_ONE},
+     *            {@link PlaybackStateCompat#REPEAT_MODE_ALL}
+     */
+    public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
+        mImpl.setRepeatMode(repeatMode);
+    }
+
+    /**
+     * Set the shuffle mode for this session.
+     * <p>
+     * Note that if this method is not called before,
+     * {@link MediaControllerCompat#isShuffleModeEnabled} will return {@code false}.
+     *
+     * @param enabled {@code true} to enable the shuffle mode, {@code false} to disable.
+     */
+    public void setShuffleModeEnabled(boolean enabled) {
+        mImpl.setShuffleModeEnabled(enabled);
+    }
+
+    /**
      * Set some extras that can be associated with the
      * {@link MediaSessionCompat}. No assumptions should be made as to how a
      * {@link MediaControllerCompat} will handle these extras. Keys should be
@@ -621,7 +677,9 @@
         WeakReference<MediaSessionImpl> mSessionImpl;
 
         public Callback() {
-            if (android.os.Build.VERSION.SDK_INT >= 24) {
+            if (android.os.Build.VERSION.SDK_INT >= 26) {
+                mCallbackObj = MediaSessionCompatApi26.createCallback(new StubApi26());
+            } else if (android.os.Build.VERSION.SDK_INT >= 24) {
                 mCallbackObj = MediaSessionCompatApi24.createCallback(new StubApi24());
             } else if (android.os.Build.VERSION.SDK_INT >= 23) {
                 mCallbackObj = MediaSessionCompatApi23.createCallback(new StubApi23());
@@ -787,6 +845,33 @@
         }
 
         /**
+         * Override to handle the setting of the repeat mode.
+         * <p>
+         * You should call {@link #setRepeatMode} before end of this method in order to notify
+         * the change to the {@link MediaControllerCompat}, or
+         * {@link MediaControllerCompat#getRepeatMode} could return an invalid value.
+         *
+         * @param repeatMode The repeat mode which is one of followings:
+         *            {@link PlaybackStateCompat#REPEAT_MODE_NONE},
+         *            {@link PlaybackStateCompat#REPEAT_MODE_ONE},
+         *            {@link PlaybackStateCompat#REPEAT_MODE_ALL}
+         */
+        public void onSetRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
+        }
+
+        /**
+         * Override to handle the setting of the shuffle mode.
+         * <p>
+         * You should call {@link #setShuffleModeEnabled} before the end of this method in order to
+         * notify the change to the {@link MediaControllerCompat}, or
+         * {@link MediaControllerCompat#isShuffleModeEnabled} could return an invalid value.
+         *
+         * @param enabled true when the shuffle mode is enabled, false otherwise.
+         */
+        public void onSetShuffleModeEnabled(boolean enabled) {
+        }
+
+        /**
          * Called when a {@link MediaControllerCompat} wants a
          * {@link PlaybackStateCompat.CustomAction} to be performed.
          *
@@ -902,6 +987,12 @@
                     Uri uri = extras.getParcelable(ACTION_ARGUMENT_URI);
                     Bundle bundle = extras.getBundle(ACTION_ARGUMENT_EXTRAS);
                     Callback.this.onPrepareFromUri(uri, bundle);
+                } else if (action.equals(ACTION_SET_REPEAT_MODE)) {
+                    int repeatMode = extras.getInt(ACTION_ARGUMENT_REPEAT_MODE);
+                    Callback.this.onSetRepeatMode(repeatMode);
+                } else if (action.equals(ACTION_SET_SHUFFLE_MODE_ENABLED)) {
+                    boolean enabled = extras.getBoolean(ACTION_ARGUMENT_SHUFFLE_MODE_ENABLED);
+                    Callback.this.onSetShuffleModeEnabled(enabled);
                 } else {
                     Callback.this.onCustomAction(action, extras);
                 }
@@ -944,6 +1035,18 @@
                 Callback.this.onPrepareFromUri(uri, extras);
             }
         }
+
+        private class StubApi26 extends StubApi24 implements MediaSessionCompatApi26.Callback {
+            @Override
+            public void onSetRepeatMode(int repeatMode) {
+                Callback.this.onSetRepeatMode(repeatMode);
+            }
+
+            @Override
+            public void onSetShuffleModeEnabled(boolean enabled) {
+                Callback.this.onSetShuffleModeEnabled(enabled);
+            }
+        }
     }
 
     /**
@@ -1281,6 +1384,8 @@
         void setQueueTitle(CharSequence title);
 
         void setRatingType(@RatingCompat.Style int type);
+        void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode);
+        void setShuffleModeEnabled(boolean enabled);
         void setExtras(Bundle extras);
 
         Object getMediaSession();
@@ -1320,6 +1425,8 @@
         List<QueueItem> mQueue;
         CharSequence mQueueTitle;
         @RatingCompat.Style int mRatingType;
+        @PlaybackStateCompat.RepeatMode int mRepeatMode;
+        boolean mShuffleModeEnabled;
         Bundle mExtras;
 
         int mVolumeType;
@@ -1607,6 +1714,22 @@
         }
 
         @Override
+        public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
+            if (mRepeatMode != repeatMode) {
+                mRepeatMode = repeatMode;
+                sendRepeatMode(repeatMode);
+            }
+        }
+
+        @Override
+        public void setShuffleModeEnabled(boolean enabled) {
+            if (mShuffleModeEnabled != enabled) {
+                mShuffleModeEnabled = enabled;
+                sendShuffleModeEnabled(enabled);
+            }
+        }
+
+        @Override
         public void setExtras(Bundle extras) {
             mExtras = extras;
             sendExtras(extras);
@@ -1825,6 +1948,30 @@
             mControllerCallbacks.finishBroadcast();
         }
 
+        private void sendRepeatMode(int repeatMode) {
+            int size = mControllerCallbacks.beginBroadcast();
+            for (int i = size - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.getBroadcastItem(i);
+                try {
+                    cb.onRepeatModeChanged(repeatMode);
+                } catch (RemoteException e) {
+                }
+            }
+            mControllerCallbacks.finishBroadcast();
+        }
+
+        private void sendShuffleModeEnabled(boolean enabled) {
+            int size = mControllerCallbacks.beginBroadcast();
+            for (int i = size - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.getBroadcastItem(i);
+                try {
+                    cb.onShuffleModeChanged(enabled);
+                } catch (RemoteException e) {
+                }
+            }
+            mControllerCallbacks.finishBroadcast();
+        }
+
         private void sendExtras(Bundle extras) {
             int size = mControllerCallbacks.beginBroadcast();
             for (int i = size - 1; i >= 0; i--) {
@@ -2021,6 +2168,16 @@
             }
 
             @Override
+            public void setRepeatMode(int repeatMode) throws RemoteException {
+                postToHandler(MessageHandler.MSG_SET_REPEAT_MODE, repeatMode);
+            }
+
+            @Override
+            public void setShuffleModeEnabled(boolean enabled) throws RemoteException {
+                postToHandler(MessageHandler.MSG_SET_SHUFFLE_MODE_ENABLED, enabled);
+            }
+
+            @Override
             public void sendCustomAction(String action, Bundle args)
                     throws RemoteException {
                 postToHandler(MessageHandler.MSG_CUSTOM_ACTION, action, args);
@@ -2062,6 +2219,17 @@
             }
 
             @Override
+            @PlaybackStateCompat.RepeatMode
+            public int getRepeatMode() {
+                return mRepeatMode;
+            }
+
+            @Override
+            public boolean isShuffleModeEnabled() {
+                return mShuffleModeEnabled;
+            }
+
+            @Override
             public boolean isTransportControlEnabled() {
                 return (mFlags & FLAG_HANDLES_TRANSPORT_CONTROLS) != 0;
             }
@@ -2103,6 +2271,8 @@
             private static final int MSG_CUSTOM_ACTION = 20;
             private static final int MSG_MEDIA_BUTTON = 21;
             private static final int MSG_SET_VOLUME = 22;
+            private static final int MSG_SET_REPEAT_MODE = 23;
+            private static final int MSG_SET_SHUFFLE_MODE_ENABLED = 24;
 
             // KeyEvent constants only available on API 11+
             private static final int KEYCODE_MEDIA_PAUSE = 127;
@@ -2210,6 +2380,12 @@
                     case MSG_SET_VOLUME:
                         setVolumeTo((int) msg.obj, 0);
                         break;
+                    case MSG_SET_REPEAT_MODE:
+                        cb.onSetRepeatMode((int) msg.obj);
+                        break;
+                    case MSG_SET_SHUFFLE_MODE_ENABLED:
+                        cb.onSetShuffleModeEnabled((boolean) msg.obj);
+                        break;
                 }
             }
 
@@ -2286,6 +2462,8 @@
 
         private PlaybackStateCompat mPlaybackState;
         @RatingCompat.Style int mRatingType;
+        @PlaybackStateCompat.RepeatMode int mRepeatMode;
+        boolean mShuffleModeEnabled;
 
         public MediaSessionImplApi21(Context context, String tag) {
             mSessionObj = MediaSessionCompatApi21.createSession(context, tag);
@@ -2301,7 +2479,7 @@
         public void setCallback(Callback callback, Handler handler) {
             MediaSessionCompatApi21.setCallback(mSessionObj,
                     callback == null ? null : callback.mCallbackObj, handler);
-            if (callback != null) {
+            if (android.os.Build.VERSION.SDK_INT < 26 && callback != null) {
                 callback.mSessionImpl = new WeakReference<MediaSessionImpl>(this);
             }
         }
@@ -2420,6 +2598,46 @@
         }
 
         @Override
+        public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
+            if (android.os.Build.VERSION.SDK_INT < 26) {
+                if (mRepeatMode != repeatMode) {
+                    mRepeatMode = repeatMode;
+                    int size = mExtraControllerCallbacks.beginBroadcast();
+                    for (int i = size - 1; i >= 0; i--) {
+                        IMediaControllerCallback cb = mExtraControllerCallbacks.getBroadcastItem(i);
+                        try {
+                            cb.onRepeatModeChanged(repeatMode);
+                        } catch (RemoteException e) {
+                        }
+                    }
+                    mExtraControllerCallbacks.finishBroadcast();
+                }
+            } else {
+                MediaSessionCompatApi26.setRepeatMode(mSessionObj, repeatMode);
+            }
+        }
+
+        @Override
+        public void setShuffleModeEnabled(boolean enabled) {
+            if (android.os.Build.VERSION.SDK_INT < 26) {
+                if (mShuffleModeEnabled != enabled) {
+                    mShuffleModeEnabled = enabled;
+                    int size = mExtraControllerCallbacks.beginBroadcast();
+                    for (int i = size - 1; i >= 0; i--) {
+                        IMediaControllerCallback cb = mExtraControllerCallbacks.getBroadcastItem(i);
+                        try {
+                            cb.onShuffleModeChanged(enabled);
+                        } catch (RemoteException e) {
+                        }
+                    }
+                    mExtraControllerCallbacks.finishBroadcast();
+                }
+            } else {
+                MediaSessionCompatApi26.setShuffleModeEnabled(mSessionObj, enabled);
+            }
+        }
+
+        @Override
         public void setExtras(Bundle extras) {
             MediaSessionCompatApi21.setExtras(mSessionObj, extras);
         }
@@ -2621,6 +2839,18 @@
             }
 
             @Override
+            public void setRepeatMode(int repeatMode) throws RemoteException {
+                // Will not be called.
+                throw new AssertionError();
+            }
+
+            @Override
+            public void setShuffleModeEnabled(boolean enabled) throws RemoteException {
+                // Will not be called.
+                throw new AssertionError();
+            }
+
+            @Override
             public void sendCustomAction(String action, Bundle args) throws RemoteException {
                 // Will not be called.
                 throw new AssertionError();
@@ -2662,6 +2892,17 @@
             }
 
             @Override
+            @PlaybackStateCompat.RepeatMode
+            public int getRepeatMode() {
+                return mRepeatMode;
+            }
+
+            @Override
+            public boolean isShuffleModeEnabled() {
+                return mShuffleModeEnabled;
+            }
+
+            @Override
             public boolean isTransportControlEnabled() {
                 // Will not be called.
                 throw new AssertionError();
diff --git a/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java b/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
index 0321fd7..815fe95 100644
--- a/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
+++ b/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
@@ -49,7 +49,8 @@
             ACTION_SKIP_TO_PREVIOUS, ACTION_SKIP_TO_NEXT, ACTION_FAST_FORWARD, ACTION_SET_RATING,
             ACTION_SEEK_TO, ACTION_PLAY_PAUSE, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH,
             ACTION_SKIP_TO_QUEUE_ITEM, ACTION_PLAY_FROM_URI, ACTION_PREPARE,
-            ACTION_PREPARE_FROM_MEDIA_ID, ACTION_PREPARE_FROM_SEARCH, ACTION_PREPARE_FROM_URI})
+            ACTION_PREPARE_FROM_MEDIA_ID, ACTION_PREPARE_FROM_SEARCH, ACTION_PREPARE_FROM_URI,
+            ACTION_SET_REPEAT_MODE, ACTION_SET_SHUFFLE_MODE_ENABLED})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Actions {}
 
@@ -189,6 +190,20 @@
     public static final long ACTION_PREPARE_FROM_URI = 1 << 17;
 
     /**
+     * Indicates this session supports the set repeat mode command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_SET_REPEAT_MODE = 1 << 18;
+
+    /**
+     * Indicates this session supports the set shuffle mode enabled command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 1 << 19;
+
+    /**
      * @hide
      */
     @RestrictTo(LIBRARY_GROUP)
@@ -304,6 +319,31 @@
     /**
      * @hide
      */
+    @IntDef({REPEAT_MODE_NONE, REPEAT_MODE_ONE, REPEAT_MODE_ALL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RepeatMode {}
+
+    /**
+     * Use this value with {@link MediaControllerCompat.TransportControls#setRepeatMode}
+     * to indicate that the playback will be stopped at the end of the playing media list.
+     */
+    public static final int REPEAT_MODE_NONE = 0;
+
+    /**
+     * Use this value with {@link MediaControllerCompat.TransportControls#setRepeatMode}
+     * to indicate that the playback of the current playing media item will be repeated.
+     */
+    public static final int REPEAT_MODE_ONE = 1;
+
+    /**
+     * Use this value with {@link MediaControllerCompat.TransportControls#setRepeatMode}
+     * to indicate that the playback of the playing media list will be repeated.
+     */
+    public static final int REPEAT_MODE_ALL = 2;
+
+    /**
+     * @hide
+     */
     @RestrictTo(LIBRARY_GROUP)
     @IntDef({ERROR_CODE_UNKNOWN_ERROR, ERROR_CODE_APP_ERROR, ERROR_CODE_NOT_SUPPORTED,
             ERROR_CODE_AUTHENTICATION_EXPIRED, ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED,
@@ -583,6 +623,8 @@
      * <li> {@link PlaybackStateCompat#ACTION_PREPARE_FROM_MEDIA_ID}</li>
      * <li> {@link PlaybackStateCompat#ACTION_PREPARE_FROM_SEARCH}</li>
      * <li> {@link PlaybackStateCompat#ACTION_PREPARE_FROM_URI}</li>
+     * <li> {@link PlaybackStateCompat#ACTION_SET_REPEAT_MODE}</li>
+     * <li> {@link PlaybackStateCompat#ACTION_SET_SHUFFLE_MODE_ENABLED}</li>
      * </ul>
      */
     @Actions
@@ -1121,6 +1163,8 @@
          * <li> {@link PlaybackStateCompat#ACTION_PREPARE_FROM_MEDIA_ID}</li>
          * <li> {@link PlaybackStateCompat#ACTION_PREPARE_FROM_SEARCH}</li>
          * <li> {@link PlaybackStateCompat#ACTION_PREPARE_FROM_URI}</li>
+         * <li> {@link PlaybackStateCompat#ACTION_SET_REPEAT_MODE}</li>
+         * <li> {@link PlaybackStateCompat#ACTION_SET_SHUFFLE_MODE_ENABLED}</li>
          * </ul>
          *
          * @return this
diff --git a/media-compat/jellybean-mr2/android/support/v4/media/TransportMediatorCallback.java b/media-compat/jellybean-mr2/android/support/v4/media/TransportMediatorCallback.java
index 4abf568..f5b41fd 100644
--- a/media-compat/jellybean-mr2/android/support/v4/media/TransportMediatorCallback.java
+++ b/media-compat/jellybean-mr2/android/support/v4/media/TransportMediatorCallback.java
@@ -16,12 +16,10 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.view.KeyEvent;
 
 @RequiresApi(18)
-@TargetApi(18)
 interface TransportMediatorCallback {
     public void handleKey(KeyEvent key);
     public void handleAudioFocusChange(int focusChange);
diff --git a/media-compat/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java b/media-compat/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java
index aebf7ca..c27a716 100644
--- a/media-compat/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java
+++ b/media-compat/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java
@@ -16,7 +16,6 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -31,7 +30,6 @@
 import android.view.ViewTreeObserver;
 
 @RequiresApi(18)
-@TargetApi(18)
 class TransportMediatorJellybeanMR2 {
     final Context mContext;
     final AudioManager mAudioManager;
diff --git a/media-compat/jellybean-mr2/android/support/v4/media/session/MediaSessionCompatApi18.java b/media-compat/jellybean-mr2/android/support/v4/media/session/MediaSessionCompatApi18.java
index 3f323a1..cba1a31 100644
--- a/media-compat/jellybean-mr2/android/support/v4/media/session/MediaSessionCompatApi18.java
+++ b/media-compat/jellybean-mr2/android/support/v4/media/session/MediaSessionCompatApi18.java
@@ -15,7 +15,6 @@
  */
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
@@ -26,7 +25,6 @@
 import android.util.Log;
 
 @RequiresApi(18)
-@TargetApi(18)
 class MediaSessionCompatApi18 {
     private static final String TAG = "MediaSessionCompatApi18";
 
diff --git a/media-compat/kitkat/android/support/v4/media/RatingCompatKitkat.java b/media-compat/kitkat/android/support/v4/media/RatingCompatKitkat.java
index 5efdc58..1d3fa50 100644
--- a/media-compat/kitkat/android/support/v4/media/RatingCompatKitkat.java
+++ b/media-compat/kitkat/android/support/v4/media/RatingCompatKitkat.java
@@ -16,12 +16,10 @@
 
 package android.support.v4.media;
 
-import android.annotation.TargetApi;
 import android.media.Rating;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(19)
-@TargetApi(19)
 class RatingCompatKitkat {
     public static Object newUnratedRating(int ratingStyle) {
         return Rating.newUnratedRating(ratingStyle);
diff --git a/media-compat/kitkat/android/support/v4/media/session/MediaSessionCompatApi19.java b/media-compat/kitkat/android/support/v4/media/session/MediaSessionCompatApi19.java
index 94b446b..489344c 100644
--- a/media-compat/kitkat/android/support/v4/media/session/MediaSessionCompatApi19.java
+++ b/media-compat/kitkat/android/support/v4/media/session/MediaSessionCompatApi19.java
@@ -15,7 +15,6 @@
  */
 package android.support.v4.media.session;
 
-import android.annotation.TargetApi;
 import android.media.MediaMetadataEditor;
 import android.media.MediaMetadataRetriever;
 import android.media.Rating;
@@ -24,7 +23,6 @@
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(19)
-@TargetApi(19)
 class MediaSessionCompatApi19 {
     /***** PlaybackState actions *****/
     private static final long ACTION_SET_RATING = 1 << 7;
diff --git a/media-compat/tests/AndroidManifest.xml b/media-compat/tests/AndroidManifest.xml
index b118de4..1afbcdf 100644
--- a/media-compat/tests/AndroidManifest.xml
+++ b/media-compat/tests/AndroidManifest.xml
@@ -19,14 +19,13 @@
           package="android.support.mediacompat.test">
 
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                       android.support.test.espresso, android.support.test.espresso.idling"/>
 
     <application android:supportsRtl="true">
         <uses-library android:name="android.test.runner"/>
-        <activity android:name="android.support.v4.media.session.TestActivity" />
         <receiver android:name="android.support.v4.media.session.MediaButtonReceiver" >
             <intent-filter>
                 <action android:name="android.intent.action.MEDIA_BUTTON" />
diff --git a/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java b/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
index d24ad27..a79e342 100644
--- a/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
@@ -389,9 +389,8 @@
         }
     }
 
-    // TODO(hdmoon): Uncomment after fixing failing tests. (Fails on API >= 24)
-    // @Test
-    // @SmallTest
+    @Test
+    @SmallTest
     public void testGetItem() {
         resetCallbacks();
         createMediaBrowser(TEST_BROWSER_SERVICE);
diff --git a/media-compat/tests/src/android/support/v4/media/MediaBrowserServiceCompatTest.java b/media-compat/tests/src/android/support/v4/media/MediaBrowserServiceCompatTest.java
index 85c64ea..d98008d 100644
--- a/media-compat/tests/src/android/support/v4/media/MediaBrowserServiceCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/MediaBrowserServiceCompatTest.java
@@ -24,6 +24,7 @@
 
 import android.content.ComponentName;
 import android.os.Bundle;
+import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -122,7 +123,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testDelayedNotifyChildrenChanged() throws Exception {
         synchronized (mWaitLock) {
             mSubscriptionCallback.reset();
@@ -147,9 +148,8 @@
         }
     }
 
-    // TODO(hdmoon): Uncomment after fixing failing tests. (Fails on API >= 24)
-    // @Test
-    // @SmallTest
+    @Test
+    @MediumTest
     public void testDelayedItem() throws Exception {
         synchronized (mWaitLock) {
             mItemCallback.reset();
diff --git a/media-compat/tests/src/android/support/v4/media/session/MediaControllerCompatTest.java b/media-compat/tests/src/android/support/v4/media/session/MediaControllerCompatTest.java
new file mode 100644
index 0000000..bf176ac
--- /dev/null
+++ b/media-compat/tests/src/android/support/v4/media/session/MediaControllerCompatTest.java
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.v4.media.session;
+
+import static android.support.test.InstrumentationRegistry.getContext;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ResultReceiver;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.media.PollingCheck;
+import android.support.v4.media.RatingCompat;
+import android.support.v4.media.VolumeProviderCompat;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test {@link MediaControllerCompat}.
+ */
+@RunWith(AndroidJUnit4.class)
+public class MediaControllerCompatTest {
+    // The maximum time to wait for an operation.
+    private static final long TIME_OUT_MS = 3000L;
+    private static final String SESSION_TAG = "test-session";
+    private static final String EXTRAS_KEY = "test-key";
+    private static final String EXTRAS_VALUE = "test-val";
+    private static final float DELTA = 1e-4f;
+
+    private final Object mWaitLock = new Object();
+    private Handler mHandler = new Handler(Looper.getMainLooper());
+    private MediaSessionCompat mSession;
+    private MediaSessionCallback mCallback = new MediaSessionCallback();
+    private MediaControllerCompat mController;
+
+    @Before
+    public void setUp() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mSession = new MediaSessionCompat(getContext(), SESSION_TAG);
+                mSession.setCallback(mCallback, mHandler);
+                mController = mSession.getController();
+            }
+        });
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mSession.release();
+    }
+
+    @Test
+    @SmallTest
+    public void testGetPackageName() {
+        assertEquals(getContext().getPackageName(), mController.getPackageName());
+    }
+
+    @Test
+    @SmallTest
+    public void testGetRatingType() {
+        assertEquals("Default rating type of a session must be RatingCompat.RATING_NONE",
+                RatingCompat.RATING_NONE, mController.getRatingType());
+
+        mSession.setRatingType(RatingCompat.RATING_5_STARS);
+        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
+            // Wait until the extra binder is ready.
+            new PollingCheck(TIME_OUT_MS) {
+                @Override
+                protected boolean check() {
+                    return mController.getRatingType() != RatingCompat.RATING_NONE;
+                }
+            }.run();
+        }
+        assertEquals(RatingCompat.RATING_5_STARS, mController.getRatingType());
+    }
+
+    @Test
+    @SmallTest
+    public void testGetSessionToken() throws Exception {
+        assertEquals(mSession.getSessionToken(), mController.getSessionToken());
+    }
+
+    @Test
+    @SmallTest
+    public void testSendCommand() throws Exception {
+        synchronized (mWaitLock) {
+            mCallback.reset();
+            final String command = "test-command";
+            final Bundle extras = new Bundle();
+            extras.putString(EXTRAS_KEY, EXTRAS_VALUE);
+            mController.sendCommand(command, extras, new ResultReceiver(null));
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnCommandCalled);
+            assertNotNull(mCallback.mCommandCallback);
+            assertEquals(command, mCallback.mCommand);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+        }
+    }
+
+    // TODO(hdmoon): Uncomment after fixing this test. This test causes an Exception on System UI.
+    // @Test
+    // @SmallTest
+    public void testVolumeControl() throws Exception {
+        VolumeProviderCompat vp =
+                new VolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE, 11, 5) {
+            @Override
+            public void onSetVolumeTo(int volume) {
+                synchronized (mWaitLock) {
+                    setCurrentVolume(volume);
+                    mWaitLock.notify();
+                }
+            }
+
+            @Override
+            public void onAdjustVolume(int direction) {
+                synchronized (mWaitLock) {
+                    switch (direction) {
+                        case AudioManager.ADJUST_LOWER:
+                            setCurrentVolume(getCurrentVolume() - 1);
+                            break;
+                        case AudioManager.ADJUST_RAISE:
+                            setCurrentVolume(getCurrentVolume() + 1);
+                            break;
+                    }
+                    mWaitLock.notify();
+                }
+            }
+        };
+        mSession.setPlaybackToRemote(vp);
+
+        synchronized (mWaitLock) {
+            // test setVolumeTo
+            mController.setVolumeTo(7, 0);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertEquals(7, vp.getCurrentVolume());
+
+            // test adjustVolume
+            mController.adjustVolume(AudioManager.ADJUST_LOWER, 0);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertEquals(6, vp.getCurrentVolume());
+
+            mController.adjustVolume(AudioManager.ADJUST_RAISE, 0);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertEquals(7, vp.getCurrentVolume());
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testTransportControlsAndMediaSessionCallback() throws Exception {
+        MediaControllerCompat.TransportControls controls = mController.getTransportControls();
+        synchronized (mWaitLock) {
+            mCallback.reset();
+            controls.play();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPlayCalled);
+
+            mCallback.reset();
+            controls.pause();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPauseCalled);
+
+            mCallback.reset();
+            controls.stop();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnStopCalled);
+
+            mCallback.reset();
+            controls.fastForward();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnFastForwardCalled);
+
+            mCallback.reset();
+            controls.rewind();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnRewindCalled);
+
+            mCallback.reset();
+            controls.skipToPrevious();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnSkipToPreviousCalled);
+
+            mCallback.reset();
+            controls.skipToNext();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnSkipToNextCalled);
+
+            mCallback.reset();
+            final long seekPosition = 1000;
+            controls.seekTo(seekPosition);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnSeekToCalled);
+            assertEquals(seekPosition, mCallback.mSeekPosition);
+
+            mCallback.reset();
+            final RatingCompat rating =
+                    RatingCompat.newStarRating(RatingCompat.RATING_5_STARS, 3f);
+            controls.setRating(rating);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnSetRatingCalled);
+            assertEquals(rating.getRatingStyle(), mCallback.mRating.getRatingStyle());
+            assertEquals(rating.getStarRating(), mCallback.mRating.getStarRating(), DELTA);
+
+            mCallback.reset();
+            final String mediaId = "test-media-id";
+            final Bundle extras = new Bundle();
+            extras.putString(EXTRAS_KEY, EXTRAS_VALUE);
+            controls.playFromMediaId(mediaId, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPlayFromMediaIdCalled);
+            assertEquals(mediaId, mCallback.mMediaId);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            final String query = "test-query";
+            controls.playFromSearch(query, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPlayFromSearchCalled);
+            assertEquals(query, mCallback.mQuery);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            final Uri uri = Uri.parse("content://test/popcorn.mod");
+            controls.playFromUri(uri, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPlayFromUriCalled);
+            assertEquals(uri, mCallback.mUri);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            final String action = "test-action";
+            controls.sendCustomAction(action, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnCustomActionCalled);
+            assertEquals(action, mCallback.mAction);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            mCallback.mOnCustomActionCalled = false;
+            final PlaybackStateCompat.CustomAction customAction =
+                    new PlaybackStateCompat.CustomAction.Builder(action, action, -1)
+                            .setExtras(extras)
+                            .build();
+            controls.sendCustomAction(customAction, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnCustomActionCalled);
+            assertEquals(action, mCallback.mAction);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            final long queueItemId = 1000;
+            controls.skipToQueueItem(queueItemId);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnSkipToQueueItemCalled);
+            assertEquals(queueItemId, mCallback.mQueueItemId);
+
+            mCallback.reset();
+            controls.prepare();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPrepareCalled);
+
+            mCallback.reset();
+            controls.prepareFromMediaId(mediaId, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPrepareFromMediaIdCalled);
+            assertEquals(mediaId, mCallback.mMediaId);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            controls.prepareFromSearch(query, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPrepareFromSearchCalled);
+            assertEquals(query, mCallback.mQuery);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            controls.prepareFromUri(uri, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPrepareFromUriCalled);
+            assertEquals(uri, mCallback.mUri);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
+            final int repeatMode = PlaybackStateCompat.REPEAT_MODE_ALL;
+            controls.setRepeatMode(repeatMode);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnSetRepeatModeCalled);
+            assertEquals(repeatMode, mCallback.mRepeatMode);
+
+            mCallback.reset();
+            final boolean shuffleModeEnabled = true;
+            controls.setShuffleModeEnabled(shuffleModeEnabled);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnSetShuffleModeEnabledCalled);
+            assertEquals(shuffleModeEnabled, mCallback.mShuffleModeEnabled);
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testPlaybackInfo() {
+        final int playbackType = MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL;
+        final int volumeControl = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
+        final int maxVolume = 10;
+        final int currentVolume = 3;
+
+        int audioStream = 77;
+        MediaControllerCompat.PlaybackInfo info = new MediaControllerCompat.PlaybackInfo(
+                playbackType, audioStream, volumeControl, maxVolume, currentVolume);
+
+        assertEquals(playbackType, info.getPlaybackType());
+        assertEquals(audioStream, info.getAudioStream());
+        assertEquals(volumeControl, info.getVolumeControl());
+        assertEquals(maxVolume, info.getMaxVolume());
+        assertEquals(currentVolume, info.getCurrentVolume());
+    }
+
+    private class MediaSessionCallback extends MediaSessionCompat.Callback {
+        private long mSeekPosition;
+        private long mQueueItemId;
+        private RatingCompat mRating;
+        private String mMediaId;
+        private String mQuery;
+        private Uri mUri;
+        private String mAction;
+        private String mCommand;
+        private Bundle mExtras;
+        private ResultReceiver mCommandCallback;
+        private int mRepeatMode;
+        private boolean mShuffleModeEnabled;
+
+        private boolean mOnPlayCalled;
+        private boolean mOnPauseCalled;
+        private boolean mOnStopCalled;
+        private boolean mOnFastForwardCalled;
+        private boolean mOnRewindCalled;
+        private boolean mOnSkipToPreviousCalled;
+        private boolean mOnSkipToNextCalled;
+        private boolean mOnSeekToCalled;
+        private boolean mOnSkipToQueueItemCalled;
+        private boolean mOnSetRatingCalled;
+        private boolean mOnPlayFromMediaIdCalled;
+        private boolean mOnPlayFromSearchCalled;
+        private boolean mOnPlayFromUriCalled;
+        private boolean mOnCustomActionCalled;
+        private boolean mOnCommandCalled;
+        private boolean mOnPrepareCalled;
+        private boolean mOnPrepareFromMediaIdCalled;
+        private boolean mOnPrepareFromSearchCalled;
+        private boolean mOnPrepareFromUriCalled;
+        private boolean mOnSetRepeatModeCalled;
+        private boolean mOnSetShuffleModeEnabledCalled;
+
+        public void reset() {
+            mSeekPosition = -1;
+            mQueueItemId = -1;
+            mRating = null;
+            mMediaId = null;
+            mQuery = null;
+            mUri = null;
+            mAction = null;
+            mExtras = null;
+            mCommand = null;
+            mCommandCallback = null;
+            mShuffleModeEnabled = false;
+            mRepeatMode = PlaybackStateCompat.REPEAT_MODE_NONE;
+
+            mOnPlayCalled = false;
+            mOnPauseCalled = false;
+            mOnStopCalled = false;
+            mOnFastForwardCalled = false;
+            mOnRewindCalled = false;
+            mOnSkipToPreviousCalled = false;
+            mOnSkipToNextCalled = false;
+            mOnSkipToQueueItemCalled = false;
+            mOnSeekToCalled = false;
+            mOnSetRatingCalled = false;
+            mOnPlayFromMediaIdCalled = false;
+            mOnPlayFromSearchCalled = false;
+            mOnPlayFromUriCalled = false;
+            mOnCustomActionCalled = false;
+            mOnCommandCalled = false;
+            mOnPrepareCalled = false;
+            mOnPrepareFromMediaIdCalled = false;
+            mOnPrepareFromSearchCalled = false;
+            mOnPrepareFromUriCalled = false;
+            mOnSetRepeatModeCalled = false;
+            mOnSetShuffleModeEnabledCalled = false;
+        }
+
+        @Override
+        public void onPlay() {
+            synchronized (mWaitLock) {
+                mOnPlayCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPause() {
+            synchronized (mWaitLock) {
+                mOnPauseCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onStop() {
+            synchronized (mWaitLock) {
+                mOnStopCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onFastForward() {
+            synchronized (mWaitLock) {
+                mOnFastForwardCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onRewind() {
+            synchronized (mWaitLock) {
+                mOnRewindCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSkipToPrevious() {
+            synchronized (mWaitLock) {
+                mOnSkipToPreviousCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSkipToNext() {
+            synchronized (mWaitLock) {
+                mOnSkipToNextCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSeekTo(long pos) {
+            synchronized (mWaitLock) {
+                mOnSeekToCalled = true;
+                mSeekPosition = pos;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSetRating(RatingCompat rating) {
+            synchronized (mWaitLock) {
+                mOnSetRatingCalled = true;
+                mRating = rating;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPlayFromMediaId(String mediaId, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPlayFromMediaIdCalled = true;
+                mMediaId = mediaId;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPlayFromSearch(String query, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPlayFromSearchCalled = true;
+                mQuery = query;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPlayFromUri(Uri uri, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPlayFromUriCalled = true;
+                mUri = uri;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onCustomAction(String action, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnCustomActionCalled = true;
+                mAction = action;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSkipToQueueItem(long id) {
+            synchronized (mWaitLock) {
+                mOnSkipToQueueItemCalled = true;
+                mQueueItemId = id;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onCommand(String command, Bundle extras, ResultReceiver cb) {
+            synchronized (mWaitLock) {
+                mOnCommandCalled = true;
+                mCommand = command;
+                mExtras = extras;
+                mCommandCallback = cb;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPrepare() {
+            synchronized (mWaitLock) {
+                mOnPrepareCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPrepareFromMediaId(String mediaId, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPrepareFromMediaIdCalled = true;
+                mMediaId = mediaId;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPrepareFromSearch(String query, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPrepareFromSearchCalled = true;
+                mQuery = query;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onPrepareFromUri(Uri uri, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPrepareFromUriCalled = true;
+                mUri = uri;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSetRepeatMode(int repeatMode) {
+            synchronized (mWaitLock) {
+                mOnSetRepeatModeCalled = true;
+                mRepeatMode = repeatMode;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSetShuffleModeEnabled(boolean enabled) {
+            synchronized (mWaitLock) {
+                mOnSetShuffleModeEnabledCalled = true;
+                mShuffleModeEnabled = enabled;
+                mWaitLock.notify();
+            }
+        }
+    }
+}
diff --git a/media-compat/tests/src/android/support/v4/media/session/MediaSessionCompatTest.java b/media-compat/tests/src/android/support/v4/media/session/MediaSessionCompatTest.java
index 72460f5..a5f11ed 100644
--- a/media-compat/tests/src/android/support/v4/media/session/MediaSessionCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/session/MediaSessionCompatTest.java
@@ -16,85 +16,701 @@
 
 package android.support.v4.media.session;
 
-import static junit.framework.Assert.fail;
+import static android.support.test.InstrumentationRegistry.getContext;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.rule.ActivityTestRule;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.media.MediaDescriptionCompat;
+import android.support.v4.media.MediaMetadataCompat;
+import android.support.v4.media.RatingCompat;
+import android.support.v4.media.VolumeProviderCompat;
+import android.view.KeyEvent;
 
+import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
+import java.util.ArrayList;
+import java.util.List;
 
+/**
+ * Test {@link MediaSessionCompat}.
+ */
 @RunWith(AndroidJUnit4.class)
 public class MediaSessionCompatTest {
-    @Rule
-    public ActivityTestRule<TestActivity> mActivityRule =
-            new ActivityTestRule<>(TestActivity.class);
-    Context mContext;
-    Map<String, LockedObject> results = new HashMap<>();
+    // The maximum time to wait for an operation.
+    private static final long TIME_OUT_MS = 3000L;
+    private static final int MAX_AUDIO_INFO_CHANGED_CALLBACK_COUNT = 10;
+    private static final String TEST_SESSION_TAG = "test-session-tag";
+    private static final String TEST_KEY = "test-key";
+    private static final String TEST_VALUE = "test-val";
+    private static final String TEST_SESSION_EVENT = "test-session-event";
+    private static final int TEST_CURRENT_VOLUME = 10;
+    private static final int TEST_MAX_VOLUME = 11;
+    private static final long TEST_QUEUE_ID = 12L;
+    private static final long TEST_ACTION = 55L;
+
+    private AudioManager mAudioManager;
+    private Handler mHandler = new Handler(Looper.getMainLooper());
+    private Object mWaitLock = new Object();
+    private MediaControllerCallback mCallback = new MediaControllerCallback();
+    private MediaSessionCompat mSession;
 
     @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getContext();
+    public void setUp() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+                mSession = new MediaSessionCompat(getContext(), TEST_SESSION_TAG);
+            }
+        });
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // It is OK to call release() twice.
+        mSession.release();
+    }
+
+    /**
+     * Tests that a session can be created and that all the fields are
+     * initialized correctly.
+     */
+    @Test
+    @SmallTest
+    public void testCreateSession() throws Exception {
+        assertNotNull(mSession.getSessionToken());
+        assertFalse("New session should not be active", mSession.isActive());
+
+        // Verify by getting the controller and checking all its fields
+        MediaControllerCompat controller = mSession.getController();
+        assertNotNull(controller);
+        verifyNewSession(controller, TEST_SESSION_TAG);
+    }
+
+    /**
+     * Tests MediaSessionCompat.Token created in the constructor of MediaSessionCompat.
+     */
+    @Test
+    @SmallTest
+    public void testSessionToken() throws Exception {
+        MediaSessionCompat.Token sessionToken = mSession.getSessionToken();
+
+        assertNotNull(sessionToken);
+        assertEquals(0, sessionToken.describeContents());
+
+        // Test writeToParcel
+        Parcel p = Parcel.obtain();
+        sessionToken.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        MediaSessionCompat.Token token = MediaSessionCompat.Token.CREATOR.createFromParcel(p);
+        assertEquals(token, sessionToken);
+        p.recycle();
+    }
+
+    /**
+     * Tests that the various configuration bits on a session get passed to the
+     * controller.
+     */
+    @Test
+    @SmallTest
+    public void testConfigureSession() throws Exception {
+        MediaControllerCompat controller = mSession.getController();
+        controller.registerCallback(mCallback, mHandler);
+
+        synchronized (mWaitLock) {
+            // test setExtras
+            mCallback.resetLocked();
+            final Bundle extras = new Bundle();
+            extras.putString(TEST_KEY, TEST_VALUE);
+            mSession.setExtras(extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnExtraChangedCalled);
+
+            Bundle extrasOut = mCallback.mExtras;
+            assertNotNull(extrasOut);
+            assertEquals(TEST_VALUE, extrasOut.get(TEST_KEY));
+
+            extrasOut = controller.getExtras();
+            assertNotNull(extrasOut);
+            assertEquals(TEST_VALUE, extrasOut.get(TEST_KEY));
+
+            // test setFlags
+            mSession.setFlags(5);
+            assertEquals(5, controller.getFlags());
+
+            // test setMetadata
+            mCallback.resetLocked();
+            MediaMetadataCompat metadata =
+                    new MediaMetadataCompat.Builder().putString(TEST_KEY, TEST_VALUE).build();
+            mSession.setMetadata(metadata);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnMetadataChangedCalled);
+
+            MediaMetadataCompat metadataOut = mCallback.mMediaMetadata;
+            assertNotNull(metadataOut);
+            assertEquals(TEST_VALUE, metadataOut.getString(TEST_KEY));
+
+            metadataOut = controller.getMetadata();
+            assertNotNull(metadataOut);
+            assertEquals(TEST_VALUE, metadataOut.getString(TEST_KEY));
+
+            // test setPlaybackState
+            mCallback.resetLocked();
+            PlaybackStateCompat state =
+                    new PlaybackStateCompat.Builder().setActions(TEST_ACTION).build();
+            mSession.setPlaybackState(state);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPlaybackStateChangedCalled);
+
+            PlaybackStateCompat stateOut = mCallback.mPlaybackState;
+            assertNotNull(stateOut);
+            assertEquals(TEST_ACTION, stateOut.getActions());
+
+            stateOut = controller.getPlaybackState();
+            assertNotNull(stateOut);
+            assertEquals(TEST_ACTION, stateOut.getActions());
+
+            // test setQueue and setQueueTitle
+            mCallback.resetLocked();
+            List<MediaSessionCompat.QueueItem> queue = new ArrayList<>();
+            MediaSessionCompat.QueueItem item = new MediaSessionCompat.QueueItem(
+                    new MediaDescriptionCompat.Builder()
+                            .setMediaId(TEST_VALUE)
+                            .setTitle("title")
+                            .build(),
+                    TEST_QUEUE_ID);
+            queue.add(item);
+            mSession.setQueue(queue);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnQueueChangedCalled);
+
+            mSession.setQueueTitle(TEST_VALUE);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnQueueTitleChangedCalled);
+
+            assertEquals(TEST_VALUE, mCallback.mTitle);
+            assertEquals(queue.size(), mCallback.mQueue.size());
+            assertEquals(TEST_QUEUE_ID, mCallback.mQueue.get(0).getQueueId());
+            assertEquals(TEST_VALUE, mCallback.mQueue.get(0).getDescription().getMediaId());
+
+            assertEquals(TEST_VALUE, controller.getQueueTitle());
+            assertEquals(queue.size(), controller.getQueue().size());
+            assertEquals(TEST_QUEUE_ID, controller.getQueue().get(0).getQueueId());
+            assertEquals(TEST_VALUE, controller.getQueue().get(0).getDescription().getMediaId());
+
+            mCallback.resetLocked();
+            mSession.setQueue(null);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnQueueChangedCalled);
+
+            mSession.setQueueTitle(null);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnQueueTitleChangedCalled);
+
+            assertNull(mCallback.mTitle);
+            assertNull(mCallback.mQueue);
+            assertNull(controller.getQueueTitle());
+            assertNull(controller.getQueue());
+
+            // test setSessionActivity
+            Intent intent = new Intent("cts.MEDIA_SESSION_ACTION");
+            PendingIntent pi = PendingIntent.getActivity(getContext(), 555, intent, 0);
+            mSession.setSessionActivity(pi);
+            assertEquals(pi, controller.getSessionActivity());
+
+            // test setRepeatMode
+            mCallback.resetLocked();
+            final int repeatMode = PlaybackStateCompat.REPEAT_MODE_ALL;
+            mSession.setRepeatMode(repeatMode);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnRepeatModeChangedCalled);
+            assertEquals(repeatMode, mCallback.mRepeatMode);
+            assertEquals(repeatMode, controller.getRepeatMode());
+
+            // test setShuffleModeEnabled
+            mCallback.resetLocked();
+            final boolean shuffleModeEnabled = true;
+            mSession.setShuffleModeEnabled(shuffleModeEnabled);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnShuffleModeChangedCalled);
+            assertEquals(shuffleModeEnabled, mCallback.mShuffleModeEnabled);
+            assertEquals(shuffleModeEnabled, controller.isShuffleModeEnabled());
+
+            // test setActivity
+            mSession.setActive(true);
+            assertTrue(mSession.isActive());
+
+            // test sendSessionEvent
+            mCallback.resetLocked();
+            mSession.sendSessionEvent(TEST_SESSION_EVENT, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+
+            assertTrue(mCallback.mOnSessionEventCalled);
+            assertEquals(TEST_SESSION_EVENT, mCallback.mEvent);
+            assertEquals(TEST_VALUE, mCallback.mExtras.getString(TEST_KEY));
+
+            // test release
+            mCallback.resetLocked();
+            mSession.release();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnSessionDestroyedCalled);
+        }
+    }
+
+    /**
+     * Test {@link MediaSessionCompat#setPlaybackToLocal} and
+     * {@link MediaSessionCompat#setPlaybackToRemote}.
+     */
+    @Test
+    @SmallTest
+    public void testPlaybackToLocalAndRemote() throws Exception {
+        MediaControllerCompat controller = mSession.getController();
+        controller.registerCallback(mCallback, mHandler);
+
+        synchronized (mWaitLock) {
+            // test setPlaybackToRemote, do this before testing setPlaybackToLocal
+            // to ensure it switches correctly.
+            mCallback.resetLocked();
+            try {
+                mSession.setPlaybackToRemote(null);
+                fail("Expected IAE for setPlaybackToRemote(null)");
+            } catch (IllegalArgumentException e) {
+                // expected
+            }
+            VolumeProviderCompat vp = new VolumeProviderCompat(
+                    VolumeProviderCompat.VOLUME_CONTROL_FIXED,
+                    TEST_MAX_VOLUME,
+                    TEST_CURRENT_VOLUME) {};
+            mSession.setPlaybackToRemote(vp);
+
+            MediaControllerCompat.PlaybackInfo info = null;
+            for (int i = 0; i < MAX_AUDIO_INFO_CHANGED_CALLBACK_COUNT; ++i) {
+                mCallback.mOnAudioInfoChangedCalled = false;
+                mWaitLock.wait(TIME_OUT_MS);
+                assertTrue(mCallback.mOnAudioInfoChangedCalled);
+                info = mCallback.mPlaybackInfo;
+                if (info != null && info.getCurrentVolume() == TEST_CURRENT_VOLUME
+                        && info.getMaxVolume() == TEST_MAX_VOLUME
+                        && info.getVolumeControl() == VolumeProviderCompat.VOLUME_CONTROL_FIXED
+                        && info.getPlaybackType()
+                        == MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
+                    break;
+                }
+            }
+            assertNotNull(info);
+            assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
+                    info.getPlaybackType());
+            assertEquals(TEST_MAX_VOLUME, info.getMaxVolume());
+            assertEquals(TEST_CURRENT_VOLUME, info.getCurrentVolume());
+            assertEquals(VolumeProviderCompat.VOLUME_CONTROL_FIXED,
+                    info.getVolumeControl());
+
+            info = controller.getPlaybackInfo();
+            assertNotNull(info);
+            assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
+                    info.getPlaybackType());
+            assertEquals(TEST_MAX_VOLUME, info.getMaxVolume());
+            assertEquals(TEST_CURRENT_VOLUME, info.getCurrentVolume());
+            assertEquals(VolumeProviderCompat.VOLUME_CONTROL_FIXED, info.getVolumeControl());
+
+            // test setPlaybackToLocal
+            mSession.setPlaybackToLocal(AudioManager.STREAM_RING);
+            info = controller.getPlaybackInfo();
+            assertNotNull(info);
+            assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
+                    info.getPlaybackType());
+        }
+    }
+
+    /**
+     * Test {@link MediaSessionCompat.Callback#onMediaButtonEvent}.
+     */
+    @Test
+    @SmallTest
+    public void testCallbackOnMediaButtonEvent() throws Exception {
+        MediaSessionCallback sessionCallback = new MediaSessionCallback();
+        mSession.setCallback(sessionCallback, new Handler(Looper.getMainLooper()));
+        mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
+        mSession.setActive(true);
+
+        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON).setComponent(
+                new ComponentName(getContext(), getContext().getClass()));
+        PendingIntent pi = PendingIntent.getBroadcast(getContext(), 0, mediaButtonIntent, 0);
+        mSession.setMediaButtonReceiver(pi);
+
+        long supportedActions = PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE
+                | PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_STOP
+                | PlaybackStateCompat.ACTION_SKIP_TO_NEXT
+                | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
+                | PlaybackStateCompat.ACTION_FAST_FORWARD | PlaybackStateCompat.ACTION_REWIND;
+
+        // Set state to STATE_PLAYING to get higher priority.
+        PlaybackStateCompat defaultState = new PlaybackStateCompat.Builder()
+                .setActions(supportedActions)
+                .setState(PlaybackStateCompat.STATE_PLAYING, 0L, 0.0f)
+                .build();
+        mSession.setPlaybackState(defaultState);
+
+        synchronized (mWaitLock) {
+            sessionCallback.reset();
+            sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_PLAY);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(sessionCallback.mOnPlayCalled);
+
+            sessionCallback.reset();
+            sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_PAUSE);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(sessionCallback.mOnPauseCalled);
+
+            sessionCallback.reset();
+            sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_NEXT);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(sessionCallback.mOnSkipToNextCalled);
+
+            sessionCallback.reset();
+            sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(sessionCallback.mOnSkipToPreviousCalled);
+
+            sessionCallback.reset();
+            sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_STOP);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(sessionCallback.mOnStopCalled);
+
+            sessionCallback.reset();
+            sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(sessionCallback.mOnFastForwardCalled);
+
+            sessionCallback.reset();
+            sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_REWIND);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(sessionCallback.mOnRewindCalled);
+
+            // Test PLAY_PAUSE button twice.
+            // First, send PLAY_PAUSE button event while in STATE_PAUSED.
+            sessionCallback.reset();
+            mSession.setPlaybackState(new PlaybackStateCompat.Builder().setActions(supportedActions)
+                    .setState(PlaybackStateCompat.STATE_PAUSED, 0L, 0.0f).build());
+            sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(sessionCallback.mOnPlayCalled);
+
+            // Next, send PLAY_PAUSE button event while in STATE_PLAYING.
+            sessionCallback.reset();
+            mSession.setPlaybackState(new PlaybackStateCompat.Builder().setActions(supportedActions)
+                    .setState(PlaybackStateCompat.STATE_PLAYING, 0L, 0.0f).build());
+            sendMediaKeyInputToController(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(sessionCallback.mOnPauseCalled);
+        }
     }
 
     @Test
+    @SmallTest
     public void testSetNullCallback() throws Throwable {
-        initWait("testSetNullCallback");
-        mActivityRule.runOnUiThread(new Runnable() {
+        getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 try {
-                    MediaSessionCompat session = new MediaSessionCompat(mContext, "TEST");
+                    MediaSessionCompat session = new MediaSessionCompat(getContext(), "TEST");
                     session.setCallback(null);
                 } catch (Exception e) {
                     fail("Fail with an exception: " + e);
-                } finally {
-                    setResultData("testSetNullCallback", true);
                 }
             }
         });
-        waitFor("testSetNullCallback");
     }
 
-    private void initWait(String key) throws InterruptedException {
-        results.put(key, new LockedObject());
+    /**
+     * Tests {@link MediaSessionCompat.QueueItem}.
+     */
+    @Test
+    @SmallTest
+    public void testQueueItem() {
+        MediaSessionCompat.QueueItem item = new MediaSessionCompat.QueueItem(
+                new MediaDescriptionCompat.Builder()
+                        .setMediaId("media-id")
+                        .setTitle("title")
+                        .build(),
+                TEST_QUEUE_ID);
+        assertEquals(TEST_QUEUE_ID, item.getQueueId());
+        assertEquals("media-id", item.getDescription().getMediaId());
+        assertEquals("title", item.getDescription().getTitle());
+        assertEquals(0, item.describeContents());
+
+        Parcel p = Parcel.obtain();
+        item.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        MediaSessionCompat.QueueItem other =
+                MediaSessionCompat.QueueItem.CREATOR.createFromParcel(p);
+        assertEquals(item.toString(), other.toString());
+        p.recycle();
     }
 
-    private Object[] waitFor(String key) throws InterruptedException {
-        return results.get(key).waitFor();
+    /**
+     * Verifies that a new session hasn't had any configuration bits set yet.
+     *
+     * @param controller The controller for the session
+     */
+    private void verifyNewSession(MediaControllerCompat controller, String tag) {
+        assertEquals("New session has unexpected configuration", 0L, controller.getFlags());
+        assertNull("New session has unexpected configuration", controller.getExtras());
+        assertNull("New session has unexpected configuration", controller.getMetadata());
+        assertEquals("New session has unexpected configuration",
+                getContext().getPackageName(), controller.getPackageName());
+        assertNull("New session has unexpected configuration", controller.getPlaybackState());
+        assertNull("New session has unexpected configuration", controller.getQueue());
+        assertNull("New session has unexpected configuration", controller.getQueueTitle());
+        assertEquals("New session has unexpected configuration", RatingCompat.RATING_NONE,
+                controller.getRatingType());
+        assertNull("New session has unexpected configuration", controller.getSessionActivity());
+
+        assertNotNull(controller.getSessionToken());
+        assertNotNull(controller.getTransportControls());
+
+        MediaControllerCompat.PlaybackInfo info = controller.getPlaybackInfo();
+        assertNotNull(info);
+        assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
+                info.getPlaybackType());
+        assertEquals(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC),
+                info.getCurrentVolume());
     }
 
-    private void setResultData(String key, Object... args) {
-        if (results.containsKey(key)) {
-            results.get(key).set(args);
+    private void sendMediaKeyInputToController(int keyCode) {
+        MediaControllerCompat controller = mSession.getController();
+        controller.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
+        controller.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
+    }
+
+    private class MediaControllerCallback extends MediaControllerCompat.Callback {
+        private volatile boolean mOnPlaybackStateChangedCalled;
+        private volatile boolean mOnMetadataChangedCalled;
+        private volatile boolean mOnQueueChangedCalled;
+        private volatile boolean mOnQueueTitleChangedCalled;
+        private volatile boolean mOnExtraChangedCalled;
+        private volatile boolean mOnAudioInfoChangedCalled;
+        private volatile boolean mOnSessionDestroyedCalled;
+        private volatile boolean mOnSessionEventCalled;
+        private volatile boolean mOnRepeatModeChangedCalled;
+        private volatile boolean mOnShuffleModeChangedCalled;
+
+        private volatile PlaybackStateCompat mPlaybackState;
+        private volatile MediaMetadataCompat mMediaMetadata;
+        private volatile List<MediaSessionCompat.QueueItem> mQueue;
+        private volatile CharSequence mTitle;
+        private volatile String mEvent;
+        private volatile Bundle mExtras;
+        private volatile MediaControllerCompat.PlaybackInfo mPlaybackInfo;
+        private volatile int mRepeatMode;
+        private volatile boolean mShuffleModeEnabled;
+
+        public void resetLocked() {
+            mOnPlaybackStateChangedCalled = false;
+            mOnMetadataChangedCalled = false;
+            mOnQueueChangedCalled = false;
+            mOnQueueTitleChangedCalled = false;
+            mOnExtraChangedCalled = false;
+            mOnAudioInfoChangedCalled = false;
+            mOnSessionDestroyedCalled = false;
+            mOnSessionEventCalled = false;
+            mOnRepeatModeChangedCalled = false;
+            mOnShuffleModeChangedCalled = false;
+
+            mPlaybackState = null;
+            mMediaMetadata = null;
+            mQueue = null;
+            mTitle = null;
+            mExtras = null;
+            mPlaybackInfo = null;
+            mRepeatMode = PlaybackStateCompat.REPEAT_MODE_NONE;
+            mShuffleModeEnabled = false;
+        }
+
+        @Override
+        public void onPlaybackStateChanged(PlaybackStateCompat state) {
+            synchronized (mWaitLock) {
+                mOnPlaybackStateChangedCalled = true;
+                mPlaybackState = state;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onMetadataChanged(MediaMetadataCompat metadata) {
+            synchronized (mWaitLock) {
+                mOnMetadataChangedCalled = true;
+                mMediaMetadata = metadata;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onQueueChanged(List<MediaSessionCompat.QueueItem> queue) {
+            synchronized (mWaitLock) {
+                mOnQueueChangedCalled = true;
+                mQueue = queue;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onQueueTitleChanged(CharSequence title) {
+            synchronized (mWaitLock) {
+                mOnQueueTitleChangedCalled = true;
+                mTitle = title;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onExtrasChanged(Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnExtraChangedCalled = true;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onAudioInfoChanged(MediaControllerCompat.PlaybackInfo info) {
+            synchronized (mWaitLock) {
+                mOnAudioInfoChangedCalled = true;
+                mPlaybackInfo = info;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSessionDestroyed() {
+            synchronized (mWaitLock) {
+                mOnSessionDestroyedCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSessionEvent(String event, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnSessionEventCalled = true;
+                mEvent = event;
+                mExtras = (Bundle) extras.clone();
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onRepeatModeChanged(int repeatMode) {
+            synchronized (mWaitLock) {
+                mOnRepeatModeChangedCalled = true;
+                mRepeatMode = repeatMode;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onShuffleModeChanged(boolean enabled) {
+            synchronized (mWaitLock) {
+                mOnShuffleModeChangedCalled = true;
+                mShuffleModeEnabled = enabled;
+                mWaitLock.notify();
+            }
         }
     }
 
-    private class LockedObject {
-        private Semaphore mLock = new Semaphore(1);
-        private volatile Object[] mArgs;
+    private class MediaSessionCallback extends MediaSessionCompat.Callback {
+        private boolean mOnPlayCalled;
+        private boolean mOnPauseCalled;
+        private boolean mOnStopCalled;
+        private boolean mOnFastForwardCalled;
+        private boolean mOnRewindCalled;
+        private boolean mOnSkipToPreviousCalled;
+        private boolean mOnSkipToNextCalled;
 
-        public LockedObject() {
-            mLock.drainPermits();
+        public void reset() {
+            mOnPlayCalled = false;
+            mOnPauseCalled = false;
+            mOnStopCalled = false;
+            mOnFastForwardCalled = false;
+            mOnRewindCalled = false;
+            mOnSkipToPreviousCalled = false;
+            mOnSkipToNextCalled = false;
         }
 
-        public void set(Object... args) {
-            mArgs = args;
-            mLock.release(1);
+        @Override
+        public void onPlay() {
+            synchronized (mWaitLock) {
+                mOnPlayCalled = true;
+                mWaitLock.notify();
+            }
         }
 
-        public Object[] waitFor() throws InterruptedException {
-            mLock.tryAcquire(1, 2, TimeUnit.SECONDS);
-            return mArgs;
+        @Override
+        public void onPause() {
+            synchronized (mWaitLock) {
+                mOnPauseCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onStop() {
+            synchronized (mWaitLock) {
+                mOnStopCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onFastForward() {
+            synchronized (mWaitLock) {
+                mOnFastForwardCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onRewind() {
+            synchronized (mWaitLock) {
+                mOnRewindCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSkipToPrevious() {
+            synchronized (mWaitLock) {
+                mOnSkipToPreviousCalled = true;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onSkipToNext() {
+            synchronized (mWaitLock) {
+                mOnSkipToNextCalled = true;
+                mWaitLock.notify();
+            }
         }
     }
 }
diff --git a/media-compat/tests/src/android/support/v4/media/session/PlaybackStateCompatTest.java b/media-compat/tests/src/android/support/v4/media/session/PlaybackStateCompatTest.java
new file mode 100644
index 0000000..410ae01
--- /dev/null
+++ b/media-compat/tests/src/android/support/v4/media/session/PlaybackStateCompatTest.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.media.session;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+/**
+ * Test {@link PlaybackStateCompat}.
+ */
+@RunWith(AndroidJUnit4.class)
+public class PlaybackStateCompatTest {
+
+    private static final long TEST_POSITION = 20000L;
+    private static final long TEST_BUFFERED_POSITION = 15000L;
+    private static final long TEST_UPDATE_TIME = 100000L;
+    private static final long TEST_ACTIONS = PlaybackStateCompat.ACTION_PLAY
+            | PlaybackStateCompat.ACTION_STOP | PlaybackStateCompat.ACTION_SEEK_TO;
+    private static final long TEST_QUEUE_ITEM_ID = 23L;
+    private static final float TEST_PLAYBACK_SPEED = 3.0f;
+    private static final float TEST_PLAYBACK_SPEED_ON_REWIND = -2.0f;
+    private static final float DELTA = 1e-7f;
+
+    private static final String TEST_ERROR_MSG = "test-error-msg";
+    private static final String TEST_CUSTOM_ACTION = "test-custom-action";
+    private static final String TEST_CUSTOM_ACTION_NAME = "test-custom-action-name";
+    private static final int TEST_ICON_RESOURCE_ID = android.R.drawable.ic_media_next;
+
+    private static final String EXTRAS_KEY = "test-key";
+    private static final String EXTRAS_VALUE = "test-value";
+
+    /**
+     * Test default values of {@link PlaybackStateCompat}.
+     */
+    @Test
+    @SmallTest
+    public void testBuilder() {
+        PlaybackStateCompat state = new PlaybackStateCompat.Builder().build();
+
+        assertEquals(new ArrayList<PlaybackStateCompat.CustomAction>(), state.getCustomActions());
+        assertEquals(0, state.getState());
+        assertEquals(0L, state.getPosition());
+        assertEquals(0L, state.getBufferedPosition());
+        assertEquals(0.0f, state.getPlaybackSpeed(), DELTA);
+        assertEquals(0L, state.getActions());
+        assertNull(state.getErrorMessage());
+        assertEquals(0L, state.getLastPositionUpdateTime());
+        assertEquals(MediaSessionCompat.QueueItem.UNKNOWN_ID, state.getActiveQueueItemId());
+        assertNull(state.getExtras());
+    }
+
+    /**
+     * Test following setter methods of {@link PlaybackStateCompat.Builder}:
+     * {@link PlaybackStateCompat.Builder#setState(int, long, float)}
+     * {@link PlaybackStateCompat.Builder#setActions(long)}
+     * {@link PlaybackStateCompat.Builder#setActiveQueueItemId(long)}
+     * {@link PlaybackStateCompat.Builder#setBufferedPosition(long)}
+     * {@link PlaybackStateCompat.Builder#setErrorMessage(CharSequence)}
+     * {@link PlaybackStateCompat.Builder#setExtras(Bundle)}
+     */
+    @Test
+    @SmallTest
+    public void testBuilder_setterMethods() {
+        Bundle extras = new Bundle();
+        extras.putString(EXTRAS_KEY, EXTRAS_VALUE);
+
+        PlaybackStateCompat state = new PlaybackStateCompat.Builder()
+                .setState(PlaybackStateCompat.STATE_PLAYING, TEST_POSITION, TEST_PLAYBACK_SPEED)
+                .setActions(TEST_ACTIONS)
+                .setActiveQueueItemId(TEST_QUEUE_ITEM_ID)
+                .setBufferedPosition(TEST_BUFFERED_POSITION)
+                .setErrorMessage(TEST_ERROR_MSG)
+                .setExtras(extras)
+                .build();
+        assertEquals(PlaybackStateCompat.STATE_PLAYING, state.getState());
+        assertEquals(TEST_POSITION, state.getPosition());
+        assertEquals(TEST_PLAYBACK_SPEED, state.getPlaybackSpeed(), DELTA);
+        assertEquals(TEST_ACTIONS, state.getActions());
+        assertEquals(TEST_QUEUE_ITEM_ID, state.getActiveQueueItemId());
+        assertEquals(TEST_BUFFERED_POSITION, state.getBufferedPosition());
+        assertEquals(TEST_ERROR_MSG, state.getErrorMessage().toString());
+        assertNotNull(state.getExtras());
+        assertEquals(EXTRAS_VALUE, state.getExtras().get(EXTRAS_KEY));
+    }
+
+    /**
+     * Test {@link PlaybackStateCompat.Builder#setState(int, long, float, long)}.
+     */
+    @Test
+    @SmallTest
+    public void testBuilder_setStateWithUpdateTime() {
+        PlaybackStateCompat state = new PlaybackStateCompat.Builder()
+                .setState(
+                        PlaybackStateCompat.STATE_REWINDING,
+                        TEST_POSITION,
+                        TEST_PLAYBACK_SPEED_ON_REWIND,
+                        TEST_UPDATE_TIME)
+                .build();
+        assertEquals(PlaybackStateCompat.STATE_REWINDING, state.getState());
+        assertEquals(TEST_POSITION, state.getPosition());
+        assertEquals(TEST_PLAYBACK_SPEED_ON_REWIND, state.getPlaybackSpeed(), DELTA);
+        assertEquals(TEST_UPDATE_TIME, state.getLastPositionUpdateTime());
+    }
+
+    /**
+     * Test {@link PlaybackStateCompat.Builder#addCustomAction(String, String, int)}.
+     */
+    @Test
+    @SmallTest
+    public void testBuilder_addCustomAction() {
+        ArrayList<PlaybackStateCompat.CustomAction> actions = new ArrayList<>();
+        PlaybackStateCompat.Builder builder = new PlaybackStateCompat.Builder();
+
+        for (int i = 0; i < 5; i++) {
+            actions.add(new PlaybackStateCompat.CustomAction.Builder(
+                    TEST_CUSTOM_ACTION + i, TEST_CUSTOM_ACTION_NAME + i, TEST_ICON_RESOURCE_ID + i)
+                    .build());
+            builder.addCustomAction(
+                    TEST_CUSTOM_ACTION + i, TEST_CUSTOM_ACTION_NAME + i, TEST_ICON_RESOURCE_ID + i);
+        }
+
+        PlaybackStateCompat state = builder.build();
+        assertEquals(actions.size(), state.getCustomActions().size());
+        for (int i = 0; i < actions.size(); i++) {
+            assertCustomActionEquals(actions.get(i), state.getCustomActions().get(i));
+        }
+    }
+
+    /**
+     * Test {@link PlaybackStateCompat.Builder#addCustomAction(PlaybackStateCompat.CustomAction)}.
+     */
+    @Test
+    @SmallTest
+    public void testBuilder_addCustomActionWithCustomActionObject() {
+        Bundle extras = new Bundle();
+        extras.putString(EXTRAS_KEY, EXTRAS_VALUE);
+
+        ArrayList<PlaybackStateCompat.CustomAction> actions = new ArrayList<>();
+        PlaybackStateCompat.Builder builder = new PlaybackStateCompat.Builder();
+
+        for (int i = 0; i < 5; i++) {
+            actions.add(new PlaybackStateCompat.CustomAction.Builder(
+                    TEST_CUSTOM_ACTION + i, TEST_CUSTOM_ACTION_NAME + i, TEST_ICON_RESOURCE_ID + i)
+                    .setExtras(extras)
+                    .build());
+            builder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
+                    TEST_CUSTOM_ACTION + i, TEST_CUSTOM_ACTION_NAME + i, TEST_ICON_RESOURCE_ID + i)
+                    .setExtras(extras)
+                    .build());
+        }
+
+        PlaybackStateCompat state = builder.build();
+        assertEquals(actions.size(), state.getCustomActions().size());
+        for (int i = 0; i < actions.size(); i++) {
+            assertCustomActionEquals(actions.get(i), state.getCustomActions().get(i));
+        }
+    }
+
+    /**
+     * Test {@link PlaybackStateCompat#writeToParcel(Parcel, int)}.
+     */
+    @Test
+    @SmallTest
+    public void testWriteToParcel() {
+        Bundle extras = new Bundle();
+        extras.putString(EXTRAS_KEY, EXTRAS_VALUE);
+
+        PlaybackStateCompat.Builder builder =
+                new PlaybackStateCompat.Builder()
+                        .setState(PlaybackStateCompat.STATE_CONNECTING, TEST_POSITION,
+                                TEST_PLAYBACK_SPEED, TEST_UPDATE_TIME)
+                        .setActions(TEST_ACTIONS)
+                        .setActiveQueueItemId(TEST_QUEUE_ITEM_ID)
+                        .setBufferedPosition(TEST_BUFFERED_POSITION)
+                        .setErrorMessage(TEST_ERROR_MSG)
+                        .setExtras(extras);
+
+        for (int i = 0; i < 5; i++) {
+            builder.addCustomAction(
+                    new PlaybackStateCompat.CustomAction.Builder(
+                            TEST_CUSTOM_ACTION + i,
+                            TEST_CUSTOM_ACTION_NAME + i,
+                            TEST_ICON_RESOURCE_ID + i)
+                            .setExtras(extras)
+                            .build());
+        }
+        PlaybackStateCompat state = builder.build();
+
+        Parcel parcel = Parcel.obtain();
+        state.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        PlaybackStateCompat stateOut = PlaybackStateCompat.CREATOR.createFromParcel(parcel);
+        assertEquals(PlaybackStateCompat.STATE_CONNECTING, stateOut.getState());
+        assertEquals(TEST_POSITION, stateOut.getPosition());
+        assertEquals(TEST_PLAYBACK_SPEED, stateOut.getPlaybackSpeed(), DELTA);
+        assertEquals(TEST_UPDATE_TIME, stateOut.getLastPositionUpdateTime());
+        assertEquals(TEST_BUFFERED_POSITION, stateOut.getBufferedPosition());
+        assertEquals(TEST_ACTIONS, stateOut.getActions());
+        assertEquals(TEST_QUEUE_ITEM_ID, stateOut.getActiveQueueItemId());
+        assertEquals(TEST_ERROR_MSG, stateOut.getErrorMessage());
+        assertNotNull(stateOut.getExtras());
+        assertEquals(EXTRAS_VALUE, stateOut.getExtras().get(EXTRAS_KEY));
+
+        assertEquals(state.getCustomActions().size(), stateOut.getCustomActions().size());
+        for (int i = 0; i < state.getCustomActions().size(); i++) {
+            assertCustomActionEquals(
+                    state.getCustomActions().get(i), stateOut.getCustomActions().get(i));
+        }
+        parcel.recycle();
+    }
+
+    /**
+     * Test {@link PlaybackStateCompat#describeContents()}.
+     */
+    @Test
+    @SmallTest
+    public void testDescribeContents() {
+        assertEquals(0, new PlaybackStateCompat.Builder().build().describeContents());
+    }
+
+    /**
+     * Test {@link PlaybackStateCompat.CustomAction}.
+     */
+    @Test
+    @SmallTest
+    public void testCustomAction() {
+        Bundle extras = new Bundle();
+        extras.putString(EXTRAS_KEY, EXTRAS_VALUE);
+
+        // Test Builder/Getters
+        PlaybackStateCompat.CustomAction customAction = new PlaybackStateCompat.CustomAction
+                .Builder(TEST_CUSTOM_ACTION, TEST_CUSTOM_ACTION_NAME, TEST_ICON_RESOURCE_ID)
+                .setExtras(extras)
+                .build();
+        assertEquals(TEST_CUSTOM_ACTION, customAction.getAction());
+        assertEquals(TEST_CUSTOM_ACTION_NAME, customAction.getName().toString());
+        assertEquals(TEST_ICON_RESOURCE_ID, customAction.getIcon());
+        assertEquals(EXTRAS_VALUE, customAction.getExtras().get(EXTRAS_KEY));
+
+        // Test describeContents
+        assertEquals(0, customAction.describeContents());
+
+        // Test writeToParcel
+        Parcel parcel = Parcel.obtain();
+        customAction.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        assertCustomActionEquals(
+                customAction, PlaybackStateCompat.CustomAction.CREATOR.createFromParcel(parcel));
+        parcel.recycle();
+    }
+
+    private void assertCustomActionEquals(PlaybackStateCompat.CustomAction action1,
+            PlaybackStateCompat.CustomAction action2) {
+        assertEquals(action1.getAction(), action2.getAction());
+        assertEquals(action1.getName(), action2.getName());
+        assertEquals(action1.getIcon(), action2.getIcon());
+
+        // To be the same, two extras should be both null or both not null.
+        assertEquals(action1.getExtras() != null, action2.getExtras() != null);
+        if (action1.getExtras() != null) {
+            assertEquals(action1.getExtras().get(EXTRAS_KEY), action2.getExtras().get(EXTRAS_KEY));
+        }
+    }
+}
diff --git a/percent/Android.mk b/percent/Android.mk
index aaeb65a..b569224 100644
--- a/percent/Android.mk
+++ b/percent/Android.mk
@@ -27,7 +27,6 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := android-support-v4
 LOCAL_JAR_EXCLUDE_FILES := none
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
diff --git a/percent/AndroidManifest-make.xml b/percent/AndroidManifest-make.xml
deleted file mode 100644
index e979013..0000000
--- a/percent/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.percent">
-    <uses-sdk android:minSdkVersion="9"/>
-    <application />
-</manifest>
diff --git a/percent/AndroidManifest.xml b/percent/AndroidManifest.xml
index 0d55165..fd770ab 100644
--- a/percent/AndroidManifest.xml
+++ b/percent/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.percent">
-    <uses-sdk android:minSdkVersion="9"/>
+    <uses-sdk android:minSdkVersion="14"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/percent/build.gradle b/percent/build.gradle
index b120075..1dc9490 100644
--- a/percent/build.gradle
+++ b/percent/build.gradle
@@ -1,95 +1,32 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'percent'
 
 dependencies {
     compile project(':support-compat')
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    testCompile 'junit:junit:4.12'
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = ['src']
         main.res.srcDir 'res'
         main.assets.srcDir 'assets'
         main.resources.srcDir 'src'
-
-        // this moves src/instrumentTest to tests so all folders follow:
-        // tests/java, tests/res, tests/assets, ...
-        // This is a *reset* so it replaces the default paths
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/java'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Percent Support Library'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 7 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Percent Support Library'
+    inceptionYear '2015'
+    description 'Android Percent Support Library'
 }
diff --git a/percent/src/android/support/percent/PercentFrameLayout.java b/percent/src/android/support/percent/PercentFrameLayout.java
index 679ffbe..9dce2bb 100644
--- a/percent/src/android/support/percent/PercentFrameLayout.java
+++ b/percent/src/android/support/percent/PercentFrameLayout.java
@@ -16,7 +16,6 @@
 
 package android.support.percent;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.support.annotation.RequiresApi;
@@ -147,7 +146,6 @@
         }
 
         @RequiresApi(19)
-        @TargetApi(19)
         public LayoutParams(LayoutParams source) {
             // The copy constructor used here is only supported on API 19+.
             this((FrameLayout.LayoutParams) source);
diff --git a/percent/src/android/support/percent/PercentLayoutHelper.java b/percent/src/android/support/percent/PercentLayoutHelper.java
index 3cb5f47..d681244 100644
--- a/percent/src/android/support/percent/PercentLayoutHelper.java
+++ b/percent/src/android/support/percent/PercentLayoutHelper.java
@@ -26,10 +26,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 
-import android.support.percent.R;
-
-import java.lang.Math;
-
 /**
  * Helper for layouts that want to support percentage based dimensions.
  *
@@ -320,15 +316,15 @@
     }
 
     private static boolean shouldHandleMeasuredWidthTooSmall(View view, PercentLayoutInfo info) {
-        int state = ViewCompat.getMeasuredWidthAndState(view) & ViewCompat.MEASURED_STATE_MASK;
-        return state == ViewCompat.MEASURED_STATE_TOO_SMALL && info.widthPercent >= 0 &&
-                info.mPreservedParams.width == ViewGroup.LayoutParams.WRAP_CONTENT;
+        int state = view.getMeasuredWidthAndState() & View.MEASURED_STATE_MASK;
+        return state == View.MEASURED_STATE_TOO_SMALL && info.widthPercent >= 0
+                && info.mPreservedParams.width == ViewGroup.LayoutParams.WRAP_CONTENT;
     }
 
     private static boolean shouldHandleMeasuredHeightTooSmall(View view, PercentLayoutInfo info) {
-        int state = ViewCompat.getMeasuredHeightAndState(view) & ViewCompat.MEASURED_STATE_MASK;
-        return state == ViewCompat.MEASURED_STATE_TOO_SMALL && info.heightPercent >= 0 &&
-                info.mPreservedParams.height == ViewGroup.LayoutParams.WRAP_CONTENT;
+        int state = view.getMeasuredHeightAndState() & View.MEASURED_STATE_MASK;
+        return state == View.MEASURED_STATE_TOO_SMALL && info.heightPercent >= 0
+                && info.mPreservedParams.height == ViewGroup.LayoutParams.WRAP_CONTENT;
     }
 
     /* package */ static class PercentMarginLayoutParams extends ViewGroup.MarginLayoutParams {
diff --git a/percent/tests/AndroidManifest.xml b/percent/tests/AndroidManifest.xml
index ba3aa19..7af63b3 100644
--- a/percent/tests/AndroidManifest.xml
+++ b/percent/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.percent.test">
     <uses-sdk
-        android:minSdkVersion="9"
+        android:minSdkVersion="14"
         android:targetSdkVersion="23"
         tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
               android.support.test.espresso, android.support.test.espresso.idling" />
diff --git a/recommendation/Android.mk b/recommendation/Android.mk
index 67721bb..0e0a9d7 100644
--- a/recommendation/Android.mk
+++ b/recommendation/Android.mk
@@ -27,7 +27,6 @@
 LOCAL_SDK_VERSION := 21
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-v4 \
     android-support-annotations
diff --git a/recommendation/AndroidManifest-make.xml b/recommendation/AndroidManifest-make.xml
deleted file mode 100644
index ef1223e..0000000
--- a/recommendation/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.recommendation">
-    <uses-sdk android:minSdkVersion="21"/>
-    <application />
-</manifest>
diff --git a/recommendation/build.gradle b/recommendation/build.gradle
index dadad58..9becae9 100644
--- a/recommendation/build.gradle
+++ b/recommendation/build.gradle
@@ -1,4 +1,4 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'recommendation'
 
 dependencies {
@@ -6,44 +6,21 @@
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
         minSdkVersion 21
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = ['src']
         main.res.srcDir 'res'
         main.assets.srcDir 'assets'
         main.resources.srcDir 'src'
-
-        // this moves src/instrumentTest to tests so all folders follow:
-        // tests/java, tests/res, tests/assets, ...
-        // This is a *reset* so it replaces the default paths
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
     }
 
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
+supportLibrary {
+    name 'Android Support Recommendation'
+    inceptionYear '2015'
+    description 'Android Support Recommendation'
 }
diff --git a/samples/Support13Demos/AndroidManifest.xml b/samples/Support13Demos/AndroidManifest.xml
index f345c63..cdc246f 100644
--- a/samples/Support13Demos/AndroidManifest.xml
+++ b/samples/Support13Demos/AndroidManifest.xml
@@ -24,7 +24,7 @@
 
     <uses-permission android:name="android.permission.READ_CONTACTS" />
 
-    <uses-sdk android:minSdkVersion="13" />
+    <uses-sdk android:minSdkVersion="14" />
 
     <!-- The smallest screen this app works on is a phone.  The app will
          scale its UI to larger screens but doesn't make good use of them
diff --git a/samples/Support13Demos/build.gradle b/samples/Support13Demos/build.gradle
index 1b58043..0436bf7 100644
--- a/samples/Support13Demos/build.gradle
+++ b/samples/Support13Demos/build.gradle
@@ -8,7 +8,7 @@
     compileSdkVersion project.ext.currentSdk
 
     defaultConfig {
-        minSdkVersion 13
+        minSdkVersion 14
     }
 
     sourceSets {
diff --git a/samples/Support4Demos/AndroidManifest.xml b/samples/Support4Demos/AndroidManifest.xml
index 67faa66..c48e790 100644
--- a/samples/Support4Demos/AndroidManifest.xml
+++ b/samples/Support4Demos/AndroidManifest.xml
@@ -432,6 +432,20 @@
             </intent-filter>
         </activity>
 
+        <!-- (OPTIONAL) use this meta data to indicate which icon should be used in media
+            notifications (for example, when the music changes and the user is
+            looking at another app) -->
+        <meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
+            android:resource="@drawable/ic_notification" />
+
+        <!--
+             (OPTIONAL) use this meta data to override the theme from which Android Auto will
+             look for colors. If you don't set this, Android Auto will look
+             for color attributes in your application theme.
+        -->
+        <meta-data android:name="com.google.android.gms.car.application.theme"
+            android:resource="@style/CarTheme" />
+
         <service android:name=".media.MediaBrowserServiceSupport"
             android:exported="true" android:process=":service">
             <intent-filter>
diff --git a/samples/Support4Demos/build.gradle b/samples/Support4Demos/build.gradle
index 959968a..ea1808a 100644
--- a/samples/Support4Demos/build.gradle
+++ b/samples/Support4Demos/build.gradle
@@ -8,7 +8,7 @@
     compileSdkVersion project.ext.currentSdk
 
     defaultConfig {
-        minSdkVersion 9
+        minSdkVersion 14
     }
 
     sourceSets {
@@ -19,7 +19,7 @@
     }
 
     lintOptions {
-        abortOnError false
+        abortOnError true
     }
 
     compileOptions {
diff --git a/samples/Support4Demos/res/values-v21/styles.xml b/samples/Support4Demos/res/values-v21/styles.xml
new file mode 100644
index 0000000..5e4f596
--- /dev/null
+++ b/samples/Support4Demos/res/values-v21/styles.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<resources>
+    <style name="AppTheme" parent="android:Theme.Material">
+        <item name="android:colorPrimary">#ffff5722</item>
+        <item name="android:colorPrimaryDark">#ffbf360c</item>
+        <item name="android:colorAccent">#ffff5722</item>
+    </style>
+
+    <style name="CarTheme" parent="AppTheme">
+        <!-- colorPrimaryDark is currently used in Android Auto for:
+             - App background
+             - Drawer right side ("more" custom actions) background
+             - Notification icon badge tinting
+             - Overview “now playing” icon tinting
+         -->
+        <item name="android:colorPrimaryDark">#ffbf360c</item>
+
+        <!-- colorAccent is used in Android Auto for:
+             - Spinner
+             - progress bar
+             - floating action button background (Play/Pause in media apps)
+         -->
+        <item name="android:colorAccent">#ffff5722</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/samples/Support4Demos/res/values/styles.xml b/samples/Support4Demos/res/values/styles.xml
index d94f9b0..bb090d2 100644
--- a/samples/Support4Demos/res/values/styles.xml
+++ b/samples/Support4Demos/res/values/styles.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -36,27 +36,4 @@
          in correctly laying out an activity as a dialog. -->
     <style name="ThemeDialogWhenLarge" parent="android:style/Theme">
     </style>
-
-    <style name="AppTheme" parent="android:Theme.Material">
-        <item name="android:colorPrimary">#ffff5722</item>
-        <item name="android:colorPrimaryDark">#ffbf360c</item>
-        <item name="android:colorAccent">#ffff5722</item>
-    </style>
-
-    <style name="CarTheme" parent="AppTheme">
-        <!-- colorPrimaryDark is currently used in Android Auto for:
-             - App background
-             - Drawer right side ("more" custom actions) background
-             - Notification icon badge tinting
-             - Overview “now playing” icon tinting
-         -->
-        <item name="android:colorPrimaryDark">#ffbf360c</item>
-
-        <!-- colorAccent is used in Android Auto for:
-             - Spinner
-             - progress bar
-             - floating action button background (Play/Pause in media apps)
-         -->
-        <item name="android:colorAccent">#ffff5722</item>
-    </style>
 </resources>
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/media/AlbumArtCache.java b/samples/Support4Demos/src/com/example/android/supportv4/media/AlbumArtCache.java
index 630b5d5..22a1e7b 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/media/AlbumArtCache.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/media/AlbumArtCache.java
@@ -18,8 +18,9 @@
 
 import android.graphics.Bitmap;
 import android.os.AsyncTask;
+import android.support.v4.graphics.BitmapCompat;
+import android.support.v4.util.LruCache;
 import android.util.Log;
-import android.util.LruCache;
 
 import com.example.android.supportv4.media.utils.BitmapHelper;
 
@@ -61,8 +62,8 @@
         mCache = new LruCache<String, Bitmap[]>(maxSize) {
             @Override
             protected int sizeOf(String key, Bitmap[] value) {
-                return value[BIG_BITMAP_INDEX].getByteCount()
-                    + value[ICON_BITMAP_INDEX].getByteCount();
+                return BitmapCompat.getAllocationByteCount(value[BIG_BITMAP_INDEX])
+                        + BitmapCompat.getAllocationByteCount(value[ICON_BITMAP_INDEX]);
             }
         };
     }
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/media/BrowseFragment.java b/samples/Support4Demos/src/com/example/android/supportv4/media/BrowseFragment.java
index d23ce05..4a1211f 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/media/BrowseFragment.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/media/BrowseFragment.java
@@ -15,11 +15,11 @@
  */
 package com.example.android.supportv4.media;
 
-import android.app.Fragment;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.support.v4.app.Fragment;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.media.MediaBrowserCompat;
 import android.support.v4.media.session.MediaControllerCompat;
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/media/MediaBrowserSupport.java b/samples/Support4Demos/src/com/example/android/supportv4/media/MediaBrowserSupport.java
index 6460318..55176d8 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/media/MediaBrowserSupport.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/media/MediaBrowserSupport.java
@@ -16,16 +16,18 @@
 
 package com.example.android.supportv4.media;
 
-import com.example.android.supportv4.R;
-import android.app.Activity;
 import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
 import android.support.v4.media.MediaBrowserCompat;
 import android.support.v4.media.session.MediaControllerCompat;
 
+import com.example.android.supportv4.R;
+
 /**
  * Main activity for the music player.
  */
-public class MediaBrowserSupport extends Activity implements BrowseFragment.FragmentDataHelper {
+public class MediaBrowserSupport extends FragmentActivity
+        implements BrowseFragment.FragmentDataHelper {
     private MediaControllerCompat mMediaController;
 
     @Override
@@ -33,7 +35,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_player);
         if (savedInstanceState == null) {
-            getFragmentManager().beginTransaction()
+            getSupportFragmentManager().beginTransaction()
                     .add(R.id.container, BrowseFragment.newInstance(null))
                     .commit();
         }
@@ -44,12 +46,12 @@
         if (item.isPlayable()) {
             mMediaController.getTransportControls().playFromMediaId(item.getMediaId(), null);
             QueueFragment queueFragment = QueueFragment.newInstance();
-            getFragmentManager().beginTransaction()
+            getSupportFragmentManager().beginTransaction()
                     .replace(R.id.container, queueFragment)
                     .addToBackStack(null)
                     .commit();
         } else if (item.isBrowsable()) {
-            getFragmentManager().beginTransaction()
+            getSupportFragmentManager().beginTransaction()
                     .replace(R.id.container, BrowseFragment.newInstance(item.getMediaId()))
                     .addToBackStack(null)
                     .commit();
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/media/QueueFragment.java b/samples/Support4Demos/src/com/example/android/supportv4/media/QueueFragment.java
index 6ec5477..33e6888 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/media/QueueFragment.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/media/QueueFragment.java
@@ -16,10 +16,10 @@
 
 package com.example.android.supportv4.media;
 
-import android.app.Fragment;
 import android.content.ComponentName;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.support.v4.app.Fragment;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.media.MediaBrowserCompat;
 import android.support.v4.media.session.MediaControllerCompat;
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java
index b408349..1621e6d 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java
@@ -144,7 +144,12 @@
         @Override
         public void onGlobalLayout() {
             mActionBar.onFirstLayout();
-            mSlidingLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                mSlidingLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+            } else {
+                //noinspection deprecation
+                mSlidingLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
+            }
         }
     }
 
diff --git a/samples/Support7Demos/build.gradle b/samples/Support7Demos/build.gradle
index d87479a..c49ec88 100644
--- a/samples/Support7Demos/build.gradle
+++ b/samples/Support7Demos/build.gradle
@@ -13,7 +13,7 @@
     compileSdkVersion project.ext.currentSdk
 
     defaultConfig {
-        minSdkVersion 9
+        minSdkVersion 14
     }
 
     sourceSets {
@@ -24,7 +24,7 @@
     }
 
     lintOptions {
-        abortOnError false
+        abortOnError true
     }
 
     compileOptions {
diff --git a/samples/Support7Demos/res/drawable/animation_vector_drawable_grouping_1.xml b/samples/Support7Demos/res/drawable/animation_vector_drawable_grouping_1.xml
index dbdf453..5359361 100644
--- a/samples/Support7Demos/res/drawable/animation_vector_drawable_grouping_1.xml
+++ b/samples/Support7Demos/res/drawable/animation_vector_drawable_grouping_1.xml
@@ -13,8 +13,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+
 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-                 android:drawable="@drawable/vector_drawable_grouping_1">
+                 xmlns:tools="http://schemas.android.com/tools"
+                 android:drawable="@drawable/vector_drawable_grouping_1"
+                 tools:ignore="NewApi">
 
     <target
             android:name="sun"
diff --git a/samples/Support7Demos/res/layout/overlay_display_window.xml b/samples/Support7Demos/res/layout/overlay_display_window.xml
index 36b4a0d..1f026fe 100644
--- a/samples/Support7Demos/res/layout/overlay_display_window.xml
+++ b/samples/Support7Demos/res/layout/overlay_display_window.xml
@@ -15,10 +15,12 @@
 -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:tools="http://schemas.android.com/tools"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:background="#000000">
-    <TextureView android:id="@+id/overlay_display_window_texture"
+    <TextureView tools:ignore="NewApi"
+               android:id="@+id/overlay_display_window_texture"
                android:layout_width="0px"
                android:layout_height="0px" />
     <TextView android:id="@+id/overlay_display_window_title"
diff --git a/samples/Support7Demos/res/menu/actions.xml b/samples/Support7Demos/res/menu/actions.xml
index e3b576e..f3b0b85 100644
--- a/samples/Support7Demos/res/menu/actions.xml
+++ b/samples/Support7Demos/res/menu/actions.xml
@@ -22,7 +22,9 @@
           app:actionViewClass="android.support.v7.widget.SearchView" />
     <item android:id="@+id/action_add"
           android:icon="@android:drawable/ic_menu_add"
-          android:title="@string/action_bar_add" />
+          android:title="@string/action_bar_add"
+          app:contentDescription="@string/action_bar_add_description"
+          app:tooltipText="@string/action_bar_add_tooltip" />
     <item android:id="@+id/action_edit"
           android:icon="@android:drawable/ic_menu_edit"
           android:title="@string/action_bar_edit"
diff --git a/samples/Support7Demos/res/menu/popup_menu.xml b/samples/Support7Demos/res/menu/popup_menu.xml
index f50efc5..09d3bfa 100644
--- a/samples/Support7Demos/res/menu/popup_menu.xml
+++ b/samples/Support7Demos/res/menu/popup_menu.xml
@@ -13,9 +13,12 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto">
     <item android:id="@+id/action_highlight"
-          android:title="@string/popup_menu_highlight" />
+          android:title="@string/popup_menu_highlight"
+          app:contentDescription="@string/popup_menu_highlight_description"
+          app:tooltipText="@string/popup_menu_highlight_tooltip" />
     <item android:id="@+id/action_edit"
           android:title="@string/popup_menu_edit" />
     <item android:id="@+id/action_delete"
diff --git a/samples/Support7Demos/res/values-v21/styles.xml b/samples/Support7Demos/res/values-v21/styles.xml
new file mode 100644
index 0000000..d5b1764
--- /dev/null
+++ b/samples/Support7Demos/res/values-v21/styles.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 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.
+-->
+
+<resources>
+    <style name="Theme.SampleDrawerLayout" parent="Theme.AppCompat.NoActionBar">
+        <!-- Tell SystemUI that our activity window will draw the background for the status bar. -->
+        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
+        <!-- Set the status bar to be translucent black. -->
+        <item name="android:statusBarColor">#30000000</item>
+        <item name="windowActionModeOverlay">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/samples/Support7Demos/res/values/strings.xml b/samples/Support7Demos/res/values/strings.xml
index 6794eae..fe325a1 100644
--- a/samples/Support7Demos/res/values/strings.xml
+++ b/samples/Support7Demos/res/values/strings.xml
@@ -71,7 +71,11 @@
 
     <string name="action_bar_search">Search</string>
     <string name="action_bar_add">Add</string>
+    <string name="action_bar_add_description">Add description</string>
+    <string name="action_bar_add_tooltip">Add tooltip</string>
     <string name="action_bar_edit">Edit</string>
+    <string name="action_bar_edit_description">Edit description</string>
+    <string name="action_bar_edit_tooltip">Edit tooltip</string>
     <string name="action_bar_share">Share</string>
     <string name="action_bar_sort">Sort</string>
     <string name="action_bar_sort_alpha">Alphabetically</string>
@@ -214,7 +218,11 @@
     <string name="popup_menu_summary">This activity illustrates the use of popup menus. The popup menu is shown by clicking the button above. The text area below logs various events.</string>
     <string name="popup_menu_button">Show popup!</string>
     <string name="popup_menu_highlight">Highlight</string>
+    <string name="popup_menu_highlight_description">Highlight description</string>
+    <string name="popup_menu_highlight_tooltip">Highlight tooltip</string>
     <string name="popup_menu_edit">Edit</string>
+    <string name="popup_menu_edit_description">Edit description</string>
+    <string name="popup_menu_edit_tooltip">Edit tooltip</string>
     <string name="popup_menu_delete">Delete</string>
     <string name="popup_menu_ignore">Ignore</string>
     <string name="popup_menu_share">Share</string>
diff --git a/samples/Support7Demos/res/values/styles.xml b/samples/Support7Demos/res/values/styles.xml
index a1ec841..3395c69 100644
--- a/samples/Support7Demos/res/values/styles.xml
+++ b/samples/Support7Demos/res/values/styles.xml
@@ -49,10 +49,6 @@
     </style>
 
     <style name="Theme.SampleDrawerLayout" parent="Theme.AppCompat.NoActionBar">
-        <!-- Tell SystemUI that our activity window will draw the background for the status bar. -->
-        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
-        <!-- Set the status bar to be translucent black. -->
-        <item name="android:statusBarColor">#30000000</item>
         <item name="windowActionModeOverlay">true</item>
         <item name="android:windowContentOverlay">@null</item>
     </style>
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarUsage.java b/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarUsage.java
index 8772601..90f89ee 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarUsage.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarUsage.java
@@ -53,6 +53,11 @@
         SearchView searchView = (SearchView) MenuItemCompat
                 .getActionView(menu.findItem(R.id.action_search));
         searchView.setOnQueryTextListener(mOnQueryTextListener);
+        final MenuItem editItem = menu.findItem(R.id.action_edit);
+        MenuItemCompat.setContentDescription(editItem,
+                getString(R.string.action_bar_edit_description));
+        MenuItemCompat.setTooltipText(editItem,
+                getString(R.string.action_bar_edit_tooltip));
         return true;
     }
 
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/graphics/ImageLoader.java b/samples/Support7Demos/src/com/example/android/supportv7/graphics/ImageLoader.java
index 30a0aa2..d20103f 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/graphics/ImageLoader.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/graphics/ImageLoader.java
@@ -20,7 +20,6 @@
 import android.os.AsyncTask;
 import android.provider.MediaStore;
 import android.support.v4.graphics.BitmapCompat;
-import android.support.v4.os.AsyncTaskCompat;
 import android.support.v4.util.LruCache;
 import android.widget.ImageView;
 
@@ -57,7 +56,7 @@
             return;
         }
 
-        AsyncTaskCompat.executeParallel(new AsyncTask<Void, Void, Bitmap>() {
+        new AsyncTask<Void, Void, Bitmap>() {
             @Override
             protected Bitmap doInBackground(Void... params) {
                 return MediaStore.Images.Thumbnails.getThumbnail(
@@ -80,7 +79,7 @@
                     }
                 }
             }
-        });
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
 
     /**
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/LocalPlayer.java b/samples/Support7Demos/src/com/example/android/supportv7/media/LocalPlayer.java
index b62f76e..2d0cb56 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/LocalPlayer.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/LocalPlayer.java
@@ -16,6 +16,7 @@
 
 package com.example.android.supportv7.media;
 
+import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.Presentation;
 import android.content.Context;
@@ -26,8 +27,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.SystemClock;
-import android.support.v7.media.MediaRouter.RouteInfo;
 import android.support.v7.media.MediaItemStatus;
+import android.support.v7.media.MediaRouter.RouteInfo;
 import android.util.Log;
 import android.view.Display;
 import android.view.Gravity;
@@ -373,6 +374,7 @@
         }
     }
 
+    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     private static final class ICSMediaPlayer {
         public static final void setSurface(MediaPlayer player, Surface surface) {
             player.setSurface(surface);
@@ -398,7 +400,6 @@
 
             // add surface holder callback
             SurfaceHolder holder = mSurfaceView.getHolder();
-            holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
             holder.addCallback(this);
         }
 
@@ -412,11 +413,8 @@
         public void release() {
             super.release();
 
-            // dismiss presentation display
-            if (mPresentation != null) {
-                Log.i(TAG, "Dismissing presentation because the activity is no longer visible.");
-                mPresentation.dismiss();
-                mPresentation = null;
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+                releasePresentation();
             }
 
             // remove surface holder callback
@@ -428,6 +426,7 @@
             mLayout.setVisibility(View.GONE);
         }
 
+        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
         @Override
         public void updatePresentation() {
             // Get the current route and its presentation display.
@@ -490,7 +489,10 @@
             int width = getVideoWidth();
             int height = getVideoHeight();
             if (width > 0 && height > 0) {
-                if (mPresentation == null) {
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
+                        && mPresentation != null) {
+                    mPresentation.updateSize(width, height);
+                } else {
                     int surfaceWidth = mLayout.getWidth();
                     int surfaceHeight = mLayout.getHeight();
 
@@ -510,8 +512,6 @@
                     }
                     Log.i(TAG, "video rect is " + lp.width + "x" + lp.height);
                     mSurfaceView.setLayoutParams(lp);
-                } else {
-                    mPresentation.updateSize(width, height);
                 }
             }
         }
@@ -540,7 +540,18 @@
             }
         };
 
+        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+        private void releasePresentation() {
+            // dismiss presentation display
+            if (mPresentation != null) {
+                Log.i(TAG, "Dismissing presentation because the activity is no longer visible.");
+                mPresentation.dismiss();
+                mPresentation = null;
+            }
+        }
+
         // Presentation
+        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
         private final class DemoPresentation extends Presentation {
             private SurfaceView mPresentationSurfaceView;
 
@@ -559,7 +570,6 @@
                 // Set up the surface view.
                 mPresentationSurfaceView = (SurfaceView)findViewById(R.id.surface_view);
                 SurfaceHolder holder = mPresentationSurfaceView.getHolder();
-                holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
                 holder.addCallback(SurfaceViewPlayer.this);
                 Log.i(TAG, "Presentation created");
             }
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/OverlayDisplayWindow.java b/samples/Support7Demos/src/com/example/android/supportv7/media/OverlayDisplayWindow.java
index 65a7ca2..6558f86 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/OverlayDisplayWindow.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/OverlayDisplayWindow.java
@@ -15,30 +15,32 @@
  */
 
 package com.example.android.supportv7.media;
-import com.example.android.supportv7.R;
 
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.SurfaceTexture;
 import android.hardware.display.DisplayManager;
 import android.os.Build;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Display;
-import android.util.DisplayMetrics;
 import android.view.GestureDetector;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
+import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.TextureView;
-import android.view.View;
-import android.view.Surface;
-import android.view.WindowManager;
 import android.view.TextureView.SurfaceTextureListener;
+import android.view.View;
+import android.view.WindowManager;
 import android.widget.TextView;
 
+import com.example.android.supportv7.R;
+
 /**
  * Manages an overlay display window, used for simulating remote playback.
  */
@@ -177,6 +179,7 @@
     /**
      * Implementation for API version 17+.
      */
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     private static final class JellybeanMr1Impl extends OverlayDisplayWindow {
         // When true, disables support for moving and resizing the overlay.
         // The window is made non-touchable, which makes it possible to
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/Player.java b/samples/Support7Demos/src/com/example/android/supportv7/media/Player.java
index 5e94413..380e945 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/Player.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/Player.java
@@ -16,8 +16,10 @@
 
 package com.example.android.supportv7.media;
 
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.os.Build;
 import android.support.v4.media.MediaMetadataCompat;
 import android.support.v4.media.session.MediaSessionCompat;
 import android.support.v4.media.session.PlaybackStateCompat;
@@ -72,7 +74,10 @@
     public void takeSnapshot() {}
     public Bitmap getSnapshot() { return null; }
 
-    // presentation display
+    /**
+     * presentation display
+     */
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     public void updatePresentation() {}
 
     public void setCallback(Callback callback) {
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
index bae5362..5d33a1f 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
@@ -24,6 +24,7 @@
 import android.media.AudioManager;
 import android.media.AudioManager.OnAudioFocusChangeListener;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
@@ -132,7 +133,9 @@
             Log.d(TAG, "onRouteSelected: route=" + route);
 
             mPlayer = Player.create(SampleMediaRouterActivity.this, route, mMediaSession);
-            mPlayer.updatePresentation();
+            if (isPresentationApiSupported()) {
+                mPlayer.updatePresentation();
+            }
             mSessionManager.setPlayer(mPlayer);
             mSessionManager.unsuspend();
 
@@ -150,7 +153,9 @@
                         0 : (SystemClock.elapsedRealtime() - item.getTimestamp()));
                 mSessionManager.suspend(pos);
             }
-            mPlayer.updatePresentation();
+            if (isPresentationApiSupported()) {
+                mPlayer.updatePresentation();
+            }
             mPlayer.release();
         }
 
@@ -163,7 +168,9 @@
         public void onRoutePresentationDisplayChanged(
                 MediaRouter router, RouteInfo route) {
             Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
-            mPlayer.updatePresentation();
+            if (isPresentationApiSupported()) {
+                mPlayer.updatePresentation();
+            }
         }
 
         @Override
@@ -180,6 +187,10 @@
         public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
             Log.d(TAG, "onRouteProviderChanged: provider=" + provider);
         }
+
+        private boolean isPresentationApiSupported() {
+            return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
+        }
     };
 
     private MediaSessionCompat mMediaSession;
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/view/CardViewActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/view/CardViewActivity.java
index 0722ebd..82d0790 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/view/CardViewActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/view/CardViewActivity.java
@@ -18,7 +18,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.support.v4.content.ContextCompat;
-import android.support.v4.view.ViewCompat;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.widget.CardView;
 import android.view.View;
@@ -78,7 +77,7 @@
         if (mMaxElevationSeekBar.getProgress() != mCardView.getMaxCardElevation()) {
             mCardView.setMaxCardElevation(mMaxElevationSeekBar.getProgress());
         }
-        ViewCompat.setAlpha(mCardView, mAlphaSeekBar.getProgress() / 255f);
+        mCardView.setAlpha(mAlphaSeekBar.getProgress() / 255f);
         ViewGroup.LayoutParams lp;
         if (mResizeCardView) {
             lp = setViewBounds(mCardView);
@@ -133,7 +132,7 @@
         mMaxElevationSeekBar.setOnSeekBarChangeListener(mOnSeekBarChangedListener);
 
         mAlphaSeekBar = (SeekBar) findViewById(R.id.alpha_seek_bar);
-        mAlphaSeekBar.setProgress((int) ViewCompat.getAlpha(mCardView) * 255);
+        mAlphaSeekBar.setProgress((int) (mCardView.getAlpha() * 255));
         mAlphaSeekBar.setOnSeekBarChangeListener(mOnSeekBarChangedListener);
 
         RadioGroup rb = (RadioGroup) findViewById(R.id.select_target_radio);
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
index 6714f6d..3226724 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/AnimatedRecyclerView.java
@@ -15,9 +15,8 @@
  */
 package com.example.android.supportv7.widget;
 
-import com.example.android.supportv7.R;
-
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.annotation.TargetApi;
 import android.app.Activity;
@@ -26,8 +25,6 @@
 import android.os.Bundle;
 import android.support.v4.util.ArrayMap;
 import android.support.v4.view.MenuItemCompat;
-import android.support.v4.view.ViewCompat;
-import android.support.v4.view.ViewPropertyAnimatorListener;
 import android.support.v7.widget.DefaultItemAnimator;
 import android.support.v7.widget.RecyclerView;
 import android.util.DisplayMetrics;
@@ -40,6 +37,8 @@
 import android.widget.CompoundButton;
 import android.widget.TextView;
 
+import com.example.android.supportv7.R;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -130,26 +129,26 @@
                 for (int i = mPendingSettleList.size() - 1; i >=0; i--) {
                     final MyViewHolder vh = mPendingSettleList.keyAt(i);
                     final long duration = mPendingSettleList.valueAt(i);
-                    ViewCompat.animate(vh.textView).translationX(0f).alpha(1f)
+                    vh.textView.animate().translationX(0f).alpha(1f)
                             .setDuration(duration).setListener(
-                            new ViewPropertyAnimatorListener() {
-                                @Override
-                                public void onAnimationStart(View view) {
-                                    dispatchAnimationStarted(vh);
-                                }
+                                    new AnimatorListenerAdapter() {
+                                        @Override
+                                        public void onAnimationStart(Animator animator) {
+                                            dispatchAnimationStarted(vh);
+                                        }
 
-                                @Override
-                                public void onAnimationEnd(View view) {
-                                    ViewCompat.setTranslationX(vh.textView, 0f);
-                                    ViewCompat.setAlpha(vh.textView, 1f);
-                                    dispatchAnimationFinished(vh);
-                                }
+                                        @Override
+                                        public void onAnimationEnd(Animator animator) {
+                                            vh.textView.setTranslationX(0f);
+                                            vh.textView.setAlpha(1f);
+                                            dispatchAnimationFinished(vh);
+                                        }
 
-                                @Override
-                                public void onAnimationCancel(View view) {
+                                        @Override
+                                        public void onAnimationCancel(Animator animator) {
 
-                                }
-                            }).start();
+                                        }
+                                    }).start();
                 }
                 mPendingSettleList.clear();
             }
@@ -230,7 +229,7 @@
                 if (pre.text.equals(post.text)) {
                     // same content. Just translate back to 0
                     final long duration = (long) (getChangeDuration()
-                            * (ViewCompat.getTranslationX(vh.textView) / vh.textView.getWidth()));
+                            * (vh.textView.getTranslationX() / vh.textView.getWidth()));
                     mPendingSettleList.put(vh, duration);
                     // we set it here because previous endAnimation would set it to other value.
                     vh.textView.setText(finalText);
@@ -274,7 +273,7 @@
         public ItemChangeAnimator(MyViewHolder viewHolder, CharSequence finalText, long duration) {
             mViewHolder = viewHolder;
             mMaxX = mViewHolder.itemView.getWidth();
-            mStartRatio = ViewCompat.getTranslationX(mViewHolder.textView) / mMaxX;
+            mStartRatio = mViewHolder.textView.getTranslationX() / mMaxX;
             mFinalText = finalText;
             mValueAnimator = ValueAnimator.ofFloat(0f, 1f);
             mValueAnimator.addUpdateListener(this);
@@ -286,11 +285,11 @@
         void setFraction(float fraction) {
             fraction = mStartRatio + (1f - mStartRatio) * fraction;
             if (fraction < .5f) {
-                ViewCompat.setTranslationX(mViewHolder.textView, fraction * mMaxX);
-                ViewCompat.setAlpha(mViewHolder.textView, 1f - fraction);
+                mViewHolder.textView.setTranslationX(fraction * mMaxX);
+                mViewHolder.textView.setAlpha(1f - fraction);
             } else {
-                ViewCompat.setTranslationX(mViewHolder.textView, (1f - fraction) * mMaxX);
-                ViewCompat.setAlpha(mViewHolder.textView, fraction);
+                mViewHolder.textView.setTranslationX((1f - fraction) * mMaxX);
+                mViewHolder.textView.setAlpha(fraction);
                 maybeSetFinalText();
             }
         }
@@ -307,7 +306,7 @@
         @Override
         public void onAnimationEnd(Animator animation) {
             maybeSetFinalText();
-            ViewCompat.setAlpha(mViewHolder.textView, 1f);
+            mViewHolder.textView.setAlpha(1f);
         }
 
         public void maybeSetFinalText() {
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/PopupMenuActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/PopupMenuActivity.java
index 2701c82..bb7cd86 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/PopupMenuActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/PopupMenuActivity.java
@@ -17,6 +17,7 @@
 package com.example.android.supportv7.widget;
 
 import android.os.Bundle;
+import android.support.v4.view.MenuItemCompat;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.widget.PopupMenu;
 import android.view.MenuInflater;
@@ -59,6 +60,11 @@
                 mPopupMenu = new PopupMenu(mContainer.getContext(), mButton);
                 final MenuInflater menuInflater = mPopupMenu.getMenuInflater();
                 menuInflater.inflate(R.menu.popup_menu, mPopupMenu.getMenu());
+                final MenuItem editItem = mPopupMenu.getMenu().findItem(R.id.action_edit);
+                MenuItemCompat.setContentDescription(editItem,
+                        getString(R.string.popup_menu_edit_description));
+                MenuItemCompat.setTooltipText(editItem,
+                        getString(R.string.popup_menu_edit_tooltip));
 
                 // Register a listener to be notified when a menu item in our popup menu has
                 // been clicked.
diff --git a/samples/SupportDesignDemos/AndroidManifest.xml b/samples/SupportDesignDemos/AndroidManifest.xml
index 29b042c..88c423a 100644
--- a/samples/SupportDesignDemos/AndroidManifest.xml
+++ b/samples/SupportDesignDemos/AndroidManifest.xml
@@ -22,7 +22,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.support.design">
 
-    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
 
     <application android:label="@string/activity_sample_code"
             android:supportsRtl="true"
diff --git a/samples/SupportDesignDemos/build.gradle b/samples/SupportDesignDemos/build.gradle
index b03e63e..5cfab4a 100644
--- a/samples/SupportDesignDemos/build.gradle
+++ b/samples/SupportDesignDemos/build.gradle
@@ -8,7 +8,7 @@
     compileSdkVersion project.ext.currentSdk
 
     defaultConfig {
-        minSdkVersion 9
+        minSdkVersion 14
     }
 
     sourceSets {
@@ -19,7 +19,7 @@
     }
 
     lintOptions {
-        abortOnError false
+        abortOnError true
     }
 
     compileOptions {
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/CustomSnackbarUsage.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/CustomSnackbarUsage.java
index 163cce2..595b485 100644
--- a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/CustomSnackbarUsage.java
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/CustomSnackbarUsage.java
@@ -19,7 +19,6 @@
 import android.os.Bundle;
 import android.support.design.widget.BaseTransientBottomBar;
 import android.support.design.widget.CoordinatorLayout;
-import android.support.v4.view.ViewCompat;
 import android.support.v7.app.AppCompatActivity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -51,15 +50,15 @@
                 new BaseTransientBottomBar.ContentViewCallback() {
                     @Override
                     public void animateContentIn(int delay, int duration) {
-                        ViewCompat.setAlpha(content, 0f);
-                        ViewCompat.animate(content).alpha(1f).setDuration(duration)
+                        content.setAlpha(0f);
+                        content.animate().alpha(1f).setDuration(duration)
                                 .setStartDelay(delay).start();
                     }
 
                     @Override
                     public void animateContentOut(int delay, int duration) {
-                        ViewCompat.setAlpha(content, 1f);
-                        ViewCompat.animate(content).alpha(0f).setDuration(duration)
+                        content.setAlpha(1f);
+                        content.animate().alpha(0f).setDuration(duration)
                                 .setStartDelay(delay).start();
                     }
                 };
diff --git a/samples/SupportLeanbackJank/Android.mk b/samples/SupportLeanbackJank/Android.mk
new file mode 100644
index 0000000..21e3f31
--- /dev/null
+++ b/samples/SupportLeanbackJank/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2014 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+# Build the samples.
+# We need to add some special AAPT flags to generate R classes
+# for resources that are included from the libraries.
+include $(CLEAR_VARS)
+LOCAL_USE_AAPT2 := true
+LOCAL_PACKAGE_NAME := SupportLeanbackJank
+LOCAL_MODULE_TAGS := samples tests
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 17
+LOCAL_DEX_PREOPT := false
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := glide
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+        android-support-compat \
+        android-support-core-ui \
+        android-support-media-compat \
+        android-support-fragment \
+        android-support-v7-recyclerview \
+        android-support-v17-leanback \
+        android-support-v17-preference-leanback \
+        android-support-v7-preference \
+        android-support-v14-preference
+
+include $(BUILD_PACKAGE)
diff --git a/samples/SupportLeanbackJank/AndroidManifest.xml b/samples/SupportLeanbackJank/AndroidManifest.xml
new file mode 100644
index 0000000..87be772
--- /dev/null
+++ b/samples/SupportLeanbackJank/AndroidManifest.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.leanbackjank">
+
+    <uses-sdk
+        android:minSdkVersion="21"
+        android:targetSdkVersion="24"/>
+
+    <uses-feature
+        android:name="android.hardware.touchscreen"
+        android:required="false"/>
+
+    <uses-feature
+        android:name="android.software.leanback"
+        android:required="true"/>
+
+    <application
+        android:banner="@drawable/app_banner"
+        android:label="@string/app_name"
+        android:logo="@drawable/app_banner"
+        android:theme="@style/JankApp">
+        <activity
+            android:name=".ui.MainActivity"
+            android:banner="@drawable/app_banner"
+            android:icon="@drawable/app_banner"
+            android:label="@string/app_name"
+            android:logo="@drawable/app_banner"
+            android:screenOrientation="landscape"
+            android:theme="@style/Theme.Leanback.Browse">
+            <intent-filter>
+                <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
+                <action android:name="android.intent.action.MAIN"/>
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".ui.VideoActivity"
+            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
+            android:launchMode="singleTask"
+            android:resizeableActivity="true"
+            android:supportsPictureInPicture="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+            </intent-filter>
+        </activity>
+
+    </application>
+</manifest>
diff --git a/samples/SupportLeanbackJank/README.txt b/samples/SupportLeanbackJank/README.txt
new file mode 100644
index 0000000..09de019
--- /dev/null
+++ b/samples/SupportLeanbackJank/README.txt
@@ -0,0 +1,6 @@
+Sample leanback browser app intended to represent current best practices, while providing a set of
+features and capabilities that are relevant to performance.
+
+This app's initial purpose is to aid in the testing of hardware performance for Android TV. It is
+used in tests that are used in a test suite designed to verify hardware performance. It is placed
+here because it might also prove useful for other testing scenarios.
\ No newline at end of file
diff --git a/samples/SupportLeanbackJank/build.gradle b/samples/SupportLeanbackJank/build.gradle
new file mode 100644
index 0000000..48960bf
--- /dev/null
+++ b/samples/SupportLeanbackJank/build.gradle
@@ -0,0 +1,36 @@
+apply plugin: 'com.android.application'
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    compile 'com.github.bumptech.glide:glide:3.7.0'
+    compile project(':support-leanback-v17')
+    compile project(':support-preference-leanback-v17')
+}
+
+android {
+    compileSdkVersion project.ext.currentSdk
+
+    defaultConfig {
+        minSdkVersion 17
+    }
+
+    sourceSets {
+        main.manifest.srcFile 'AndroidManifest.xml'
+        main.java.srcDirs = ['src']
+        main.aidl.srcDirs = ['src']
+        main.res.srcDirs = ['res']
+    }
+
+    lintOptions {
+        abortOnError false
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+}
+
diff --git a/samples/SupportLeanbackJank/res/drawable/android_header.png b/samples/SupportLeanbackJank/res/drawable/android_header.png
new file mode 100644
index 0000000..56206ec
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/drawable/android_header.png
Binary files differ
diff --git a/samples/SupportLeanbackJank/res/drawable/app_banner.png b/samples/SupportLeanbackJank/res/drawable/app_banner.png
new file mode 100644
index 0000000..4eeaa6f
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/drawable/app_banner.png
Binary files differ
diff --git a/samples/SupportLeanbackJank/res/drawable/default_background.xml b/samples/SupportLeanbackJank/res/drawable/default_background.xml
new file mode 100644
index 0000000..e367de8
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/drawable/default_background.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <gradient
+            android:startColor="@color/jank_yellow"
+            android:endColor="@color/jank_green"
+            android:angle="0" />
+</shape>
\ No newline at end of file
diff --git a/samples/SupportLeanbackJank/res/drawable/movie.png b/samples/SupportLeanbackJank/res/drawable/movie.png
new file mode 100644
index 0000000..cb5cb6d
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/drawable/movie.png
Binary files differ
diff --git a/samples/SupportLeanbackJank/res/layout/header_item.xml b/samples/SupportLeanbackJank/res/layout/header_item.xml
new file mode 100644
index 0000000..2e11b08
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/layout/header_item.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView
+        android:id="@+id/header_icon"
+        android:layout_width="32dp"
+        android:layout_height="32dp" />
+    <TextView
+        android:id="@+id/header_label"
+        android:textColor="#000000"
+        android:layout_marginTop="6dp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/SupportLeanbackJank/res/layout/main.xml b/samples/SupportLeanbackJank/res/layout/main.xml
new file mode 100644
index 0000000..d1fdee2
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/layout/main.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 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
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/main_frame"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <fragment
+        android:id="@+id/main_browse_fragment"
+        android:name="com.google.android.leanbackjank.ui.MainFragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+
+</FrameLayout>
diff --git a/samples/SupportLeanbackJank/res/raw/bbb_480p.mp4 b/samples/SupportLeanbackJank/res/raw/bbb_480p.mp4
new file mode 100644
index 0000000..9beaff3
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/raw/bbb_480p.mp4
Binary files differ
diff --git a/samples/SupportLeanbackJank/res/raw/bbb_sunflower_2160p_60fps.mp4 b/samples/SupportLeanbackJank/res/raw/bbb_sunflower_2160p_60fps.mp4
new file mode 100644
index 0000000..60f0bec
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/raw/bbb_sunflower_2160p_60fps.mp4
Binary files differ
diff --git a/samples/SupportLeanbackJank/res/raw/testvideo_1080p_60fps.mp4 b/samples/SupportLeanbackJank/res/raw/testvideo_1080p_60fps.mp4
new file mode 100644
index 0000000..9878a2a
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/raw/testvideo_1080p_60fps.mp4
Binary files differ
diff --git a/v17/preference-leanback/AndroidManifest-make.xml b/samples/SupportLeanbackJank/res/values/colors.xml
similarity index 66%
rename from v17/preference-leanback/AndroidManifest-make.xml
rename to samples/SupportLeanbackJank/res/values/colors.xml
index e2cfe35..e89b729 100644
--- a/v17/preference-leanback/AndroidManifest-make.xml
+++ b/samples/SupportLeanbackJank/res/values/colors.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
+  ~ Copyright (C) 2016 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.
@@ -15,10 +15,10 @@
   ~ limitations under the License
   -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.support.v17.preference"
-    android:versionCode="1"
-    android:versionName="1.0">
-    <uses-sdk android:minSdkVersion="17" />
-    <application />
-</manifest>
+<resources>
+    <color name="jank_yellow">#FABB05</color>
+    <color name="jank_green">#34A853</color>
+    <color name="jank_red">#EA4335</color>
+    <color name="jank_blue">#4285F4</color>
+    <color name="search_opaque">#ffaa3f</color>
+</resources>
\ No newline at end of file
diff --git a/v17/preference-leanback/AndroidManifest-make.xml b/samples/SupportLeanbackJank/res/values/dimens.xml
similarity index 66%
copy from v17/preference-leanback/AndroidManifest-make.xml
copy to samples/SupportLeanbackJank/res/values/dimens.xml
index e2cfe35..e2b1f9f 100644
--- a/v17/preference-leanback/AndroidManifest-make.xml
+++ b/samples/SupportLeanbackJank/res/values/dimens.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
+  ~ Copyright (C) 2016 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.
@@ -14,11 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.support.v17.preference"
-    android:versionCode="1"
-    android:versionName="1.0">
-    <uses-sdk android:minSdkVersion="17" />
-    <application />
-</manifest>
+<resources>
+    <dimen name="grid_item_width">100dp</dimen>
+    <dimen name="grid_item_height">100dp</dimen>
+    <dimen name="card_width">156dp</dimen>
+    <dimen name="card_height">88dp</dimen>
+</resources>
diff --git a/v17/preference-leanback/AndroidManifest-make.xml b/samples/SupportLeanbackJank/res/values/strings.xml
similarity index 66%
copy from v17/preference-leanback/AndroidManifest-make.xml
copy to samples/SupportLeanbackJank/res/values/strings.xml
index e2cfe35..37ceb80 100644
--- a/v17/preference-leanback/AndroidManifest-make.xml
+++ b/samples/SupportLeanbackJank/res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
+  ~ Copyright (C) 2016 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.
@@ -15,10 +15,7 @@
   ~ limitations under the License
   -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.support.v17.preference"
-    android:versionCode="1"
-    android:versionName="1.0">
-    <uses-sdk android:minSdkVersion="17" />
-    <application />
-</manifest>
+<resources>
+    <string name="app_name"><![CDATA[Leanback library jank test application]]></string>
+    <string name="browse_title"><![CDATA[Leanback library jank test application]]></string>
+</resources>
diff --git a/v17/preference-leanback/AndroidManifest-make.xml b/samples/SupportLeanbackJank/res/values/styles.xml
similarity index 62%
copy from v17/preference-leanback/AndroidManifest-make.xml
copy to samples/SupportLeanbackJank/res/values/styles.xml
index e2cfe35..ef7efe9 100644
--- a/v17/preference-leanback/AndroidManifest-make.xml
+++ b/samples/SupportLeanbackJank/res/values/styles.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
+  ~ Copyright (C) 2016 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.
@@ -15,10 +15,10 @@
   ~ limitations under the License
   -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.support.v17.preference"
-    android:versionCode="1"
-    android:versionName="1.0">
-    <uses-sdk android:minSdkVersion="17" />
-    <application />
-</manifest>
+<resources>
+    <style name="JankApp" parent="Theme.Leanback">
+        <item name="android:colorPrimary">@color/jank_yellow</item>
+        <item name="android:windowAllowReturnTransitionOverlap">true</item>
+        <item name="android:windowAllowEnterTransitionOverlap">true</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/IntentDefaults.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/IntentDefaults.java
new file mode 100644
index 0000000..722b7d6
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/IntentDefaults.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank;
+
+public final class IntentDefaults {
+
+    public static final int CATEGORY_COUNT = 20;
+    public static final int ENTRIES_PER_CATEGORY = 20;
+    public static final int CARD_WIDTH = 313;
+    public static final int CARD_HEIGHT = 176;
+    public static final int WHICH_VIDEO = IntentKeys.NO_VIDEO;
+    public static final boolean DISABLE_SHADOWS = false;
+    public static final boolean PLAY_VIDEO = false;
+    public static final boolean USE_SINGLE_BITMAP = false;
+
+    private IntentDefaults() {
+    }
+}
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/IntentKeys.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/IntentKeys.java
new file mode 100644
index 0000000..6d04cb0
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/IntentKeys.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank;
+
+public final class IntentKeys {
+
+    public static final String CATEGORY_COUNT = "CATEGORY_COUNT";
+    public static final String ENTRIES_PER_CATEGORY = "ENTRIES_PER_CATEGORY";
+    public static final String CARD_WIDTH = "CARD_WIDTH";
+    public static final String CARD_HEIGHT = "CARD_HEIGHT";
+    public static final String DISABLE_SHADOWS = "ENABLE_SHADOWS";
+    public static final String WHICH_VIDEO = "WHICH_VIDEO";
+    public static final String USE_SINGLE_BITMAP = "USE_SINGLE_BITMAP";
+
+    // Define values for WHICH_VIDEO.
+    public static final int NO_VIDEO = 0;
+    public static final int VIDEO_480P_60FPS = 1;
+    public static final int VIDEO_1080P_60FPS = 2;
+    public static final int VIDEO_2160P_60FPS = 3;
+
+    private IntentKeys() {
+    }
+}
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/data/VideoProvider.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/data/VideoProvider.java
new file mode 100644
index 0000000..a9e0dd5
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/data/VideoProvider.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank.data;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.graphics.Shader.TileMode;
+import android.net.Uri;
+import android.util.Log;
+
+import com.google.android.leanbackjank.model.VideoInfo;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Generates fake data for populating the video cards.
+ */
+public final class VideoProvider {
+
+    private static final String TAG = "JankVideoProvider";
+    private static final int STUDIO_COUNT = 13;
+
+    private static final List<Integer> COLORS = Arrays.asList(
+            Color.parseColor("#4285F4"),
+            Color.parseColor("#EA4335"),
+            Color.parseColor("#FABB05"),
+            Color.parseColor("#34A853")
+    );
+
+    private VideoProvider() {
+    }
+
+    public static HashMap<String, List<VideoInfo>> buildMedia(int categoryCount, int entriesPerCat,
+            int width, int height, Context context, boolean useSingleBitmap) {
+        HashMap<String, List<VideoInfo>> ret = new HashMap<>();
+
+        int count = 0;
+        String rootPath = String.format(Locale.US, "%s/%d_%d/", context.getFilesDir(), width,
+                height);
+        File rootDirectory = new File(rootPath);
+        rootDirectory.mkdirs();
+
+        for (int i = 0; i < categoryCount; i++) {
+            List<VideoInfo> list = new ArrayList<>();
+            String category = "Category " + Integer.toString(i);
+            ret.put(category, list);
+            for (int j = 0; j < entriesPerCat; j++) {
+                String description = String.format(Locale.US,
+                        "The gripping yet whimsical description of videoInfo %d in category %d", j,
+                        i);
+                String title = String.format(Locale.US, "Video %d-%d", i, j);
+                String studio = String.format(Locale.US, "Studio %d", count % STUDIO_COUNT);
+
+                VideoInfo videoInfo = new VideoInfo();
+                videoInfo.setId(Integer.toString(count));
+                videoInfo.setTitle(title);
+                videoInfo.setDescription(description);
+                videoInfo.setStudio(studio);
+                videoInfo.setCategory(category);
+
+                int videoNumber = useSingleBitmap ? 0 : count;
+                File file = new File(rootPath + videoNumber + ".jpg");
+                if (!file.exists()) {
+                    makeIcon(width, height, "Jank", file);
+                }
+                videoInfo.setImageUri(Uri.fromFile(file));
+
+                count++;
+
+                list.add(videoInfo);
+            }
+        }
+
+        return ret;
+    }
+
+    public static void makeIcon(int width, int height, String string, File file) {
+        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(bitmap);
+
+        Collections.shuffle(COLORS);
+
+        Paint paint = new Paint();
+        paint.setAntiAlias(true);
+        paint.setTextAlign(Paint.Align.CENTER);
+
+        // Draw background gradient.
+        Shader shader = new LinearGradient(0, 0, width - 1, height - 1, COLORS.get(0),
+                COLORS.get(1), TileMode.CLAMP);
+        paint.setShader(shader);
+        canvas.drawRect(0, 0, width - 1, height - 1, paint);
+
+        paint.setTextSize(height * 0.5f);
+        Rect rect = new Rect();
+        paint.getTextBounds(string, 0, string.length(), rect);
+
+        int hOffset = (height - rect.height()) / 2;
+        int wOffset = (width - rect.width()) / 2;
+        shader = new LinearGradient(wOffset, height - hOffset, width - wOffset, hOffset,
+                COLORS.get(2), COLORS.get(3), TileMode.CLAMP);
+        paint.setShader(shader);
+
+        canvas.drawText(string, width / 2, (height + rect.height()) / 2, paint);
+
+        try (FileOutputStream outputStream = new FileOutputStream(file)) {
+            bitmap.compress(CompressFormat.JPEG, 90, outputStream);
+        } catch (IOException e) {
+            Log.e(TAG, "Cannot write image to file: " + file, e);
+        }
+    }
+}
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/model/VideoInfo.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/model/VideoInfo.java
new file mode 100644
index 0000000..7e8cc8a
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/model/VideoInfo.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank.model;
+
+import android.net.Uri;
+
+/**
+ * VideoInfo class represents video entity with title, description, image thumbs and video url.
+ */
+public class VideoInfo {
+    private String mId;
+    private String mTitle;
+    private String mDescription;
+    private String mStudio;
+    private String mCategory;
+    private Uri mImageUri;
+
+    public VideoInfo() {
+    }
+
+    public String getId() {
+        return mId;
+    }
+
+    public void setId(String id) {
+        mId = id;
+    }
+
+    public String getTitle() {
+        return mTitle;
+    }
+
+    public void setTitle(String title) {
+        mTitle = title;
+    }
+
+    public String getDescription() {
+        return mDescription;
+    }
+
+    public void setDescription(String description) {
+        mDescription = description;
+    }
+
+    public String getStudio() {
+        return mStudio;
+    }
+
+    public void setStudio(String studio) {
+        mStudio = studio;
+    }
+
+    public String getCategory() {
+        return mCategory;
+    }
+
+    public void setCategory(String category) {
+        mCategory = category;
+    }
+
+    public Uri getImageUri() {
+        return mImageUri;
+    }
+
+    public void setImageUri(Uri imageUri) {
+        mImageUri = imageUri;
+    }
+}
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/CardPresenter.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/CardPresenter.java
new file mode 100644
index 0000000..564ff92
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/CardPresenter.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank.presenter;
+
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.ViewGroup;
+
+import com.bumptech.glide.Glide;
+import com.google.android.leanbackjank.R;
+import com.google.android.leanbackjank.model.VideoInfo;
+
+public class CardPresenter extends Presenter {
+    private int mSelectedBackgroundColor = -1;
+    private int mDefaultBackgroundColor = -1;
+    private int mCardWidth;
+    private int mCardHeight;
+
+    public CardPresenter(int width, int height) {
+        mCardWidth = width;
+        mCardHeight = height;
+    }
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent) {
+        mDefaultBackgroundColor = parent.getResources().getColor(R.color.jank_blue, null);
+        mSelectedBackgroundColor = parent.getResources().getColor(R.color.jank_red, null);
+
+        ImageCardView cardView = new ImageCardView(parent.getContext()) {
+            @Override
+            public void setSelected(boolean selected) {
+                updateCardBackgroundColor(this, selected);
+                super.setSelected(selected);
+            }
+        };
+
+        cardView.setFocusable(true);
+        cardView.setFocusableInTouchMode(true);
+        updateCardBackgroundColor(cardView, false);
+        return new ViewHolder(cardView);
+    }
+
+    private void updateCardBackgroundColor(ImageCardView view, boolean selected) {
+        int color = selected ? mSelectedBackgroundColor : mDefaultBackgroundColor;
+
+        // Both background colors should be set because the view's
+        // background is temporarily visible during animations.
+        view.setBackgroundColor(color);
+        view.findViewById(R.id.info_field).setBackgroundColor(color);
+    }
+
+    @Override
+    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
+        VideoInfo videoInfo = (VideoInfo) item;
+
+        ImageCardView cardView = (ImageCardView) viewHolder.view;
+        cardView.setTitleText(videoInfo.getTitle());
+        cardView.setContentText(videoInfo.getStudio());
+        cardView.setMainImageDimensions(mCardWidth, mCardHeight);
+
+        Glide.with(cardView.getContext())
+                .load(videoInfo.getImageUri())
+                .into(cardView.getMainImageView());
+    }
+
+    @Override
+    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
+        ImageCardView cardView = (ImageCardView) viewHolder.view;
+
+        // Remove references to images so that the garbage collector can free up memory.
+        cardView.setBadgeImage(null);
+        cardView.setMainImage(null);
+    }
+}
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/GridItemPresenter.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/GridItemPresenter.java
new file mode 100644
index 0000000..ff99a9b
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/GridItemPresenter.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank.presenter;
+
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.google.android.leanbackjank.R;
+
+public class GridItemPresenter extends Presenter {
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent) {
+        TextView view = new TextView(parent.getContext());
+
+        Resources res = parent.getResources();
+        int width = res.getDimensionPixelSize(R.dimen.grid_item_width);
+        int height = res.getDimensionPixelSize(R.dimen.grid_item_height);
+
+        view.setLayoutParams(new ViewGroup.LayoutParams(width, height));
+        view.setFocusable(true);
+        view.setFocusableInTouchMode(true);
+        view.setBackgroundColor(parent.getResources().getColor(R.color.jank_yellow, null));
+        view.setTextColor(Color.WHITE);
+        view.setGravity(Gravity.CENTER);
+        return new ViewHolder(view);
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder viewHolder, Object item) {
+        ((TextView) viewHolder.view).setText((String) item);
+    }
+
+    @Override
+    public void onUnbindViewHolder(ViewHolder viewHolder) {
+    }
+}
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/HeaderItemPresenter.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/HeaderItemPresenter.java
new file mode 100644
index 0000000..9740088
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/HeaderItemPresenter.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank.presenter;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.RowHeaderPresenter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.google.android.leanbackjank.R;
+
+public class HeaderItemPresenter extends RowHeaderPresenter {
+    private float mUnselectedAlpha;
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup viewGroup) {
+        mUnselectedAlpha = viewGroup.getResources()
+                .getFraction(R.fraction.lb_browse_header_unselect_alpha, 1, 1);
+        LayoutInflater inflater = (LayoutInflater) viewGroup.getContext()
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+        View view = inflater.inflate(R.layout.header_item, null);
+        view.setAlpha(mUnselectedAlpha); // Initialize icons to be at half-opacity.
+
+        return new ViewHolder(view);
+    }
+
+    @Override
+    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
+        HeaderItem headerItem = ((ListRow) item).getHeaderItem();
+        View rootView = viewHolder.view;
+        rootView.setFocusable(true);
+
+        ImageView iconView = (ImageView) rootView.findViewById(R.id.header_icon);
+        Drawable icon = rootView.getResources().getDrawable(R.drawable.android_header, null);
+        iconView.setImageDrawable(icon);
+
+        TextView label = (TextView) rootView.findViewById(R.id.header_label);
+        label.setText(headerItem.getName());
+    }
+
+    @Override
+    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
+        // no op
+    }
+
+    // TODO: This is a temporary fix. Remove me when leanback onCreateViewHolder no longer sets the
+    // mUnselectAlpha, and also assumes the xml inflation will return a RowHeaderView.
+    @Override
+    protected void onSelectLevelChanged(RowHeaderPresenter.ViewHolder holder) {
+        holder.view.setAlpha(
+                mUnselectedAlpha + holder.getSelectLevel() * (1.0f - mUnselectedAlpha));
+    }
+}
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainActivity.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainActivity.java
new file mode 100644
index 0000000..0097b31
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainActivity.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.google.android.leanbackjank.R;
+
+
+/**
+ * MainActivity class that loads MainFragment
+ */
+public class MainActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+    }
+
+    @Override
+    protected void onStop() {
+        Intent intent = new Intent(this, VideoActivity.class);
+        startActivity(intent);
+
+        super.onStop();
+    }
+}
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainFragment.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainFragment.java
new file mode 100644
index 0000000..5cbff96
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainFragment.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank.ui;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v17.leanback.app.BackgroundManager;
+import android.support.v17.leanback.app.BrowseFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.PresenterSelector;
+
+import com.google.android.leanbackjank.IntentDefaults;
+import com.google.android.leanbackjank.IntentKeys;
+import com.google.android.leanbackjank.R;
+import com.google.android.leanbackjank.data.VideoProvider;
+import com.google.android.leanbackjank.model.VideoInfo;
+import com.google.android.leanbackjank.presenter.CardPresenter;
+import com.google.android.leanbackjank.presenter.GridItemPresenter;
+import com.google.android.leanbackjank.presenter.HeaderItemPresenter;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Main class to show BrowseFragment with header and rows of videos
+ */
+public class MainFragment extends BrowseFragment {
+
+    private BackgroundManager mBackgroundManager;
+    private ArrayObjectAdapter mRowsAdapter;
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        // Define defaults.
+        int categoryCount = IntentDefaults.CATEGORY_COUNT;
+        int entriesPerCat = IntentDefaults.ENTRIES_PER_CATEGORY;
+        boolean disableShadows = IntentDefaults.DISABLE_SHADOWS;
+        int cardWidth = IntentDefaults.CARD_WIDTH;
+        int cardHeight = IntentDefaults.CARD_HEIGHT;
+        int whichVideo = IntentDefaults.WHICH_VIDEO;
+        boolean useSingleBitmap = IntentDefaults.USE_SINGLE_BITMAP;
+
+        Intent intent = getActivity().getIntent();
+        if (intent.getExtras() != null) {
+            categoryCount = intent.getIntExtra(IntentKeys.CATEGORY_COUNT, categoryCount);
+            entriesPerCat = intent.getIntExtra(IntentKeys.ENTRIES_PER_CATEGORY, entriesPerCat);
+            disableShadows = intent.getBooleanExtra(IntentKeys.DISABLE_SHADOWS, disableShadows);
+            cardWidth = intent.getIntExtra(IntentKeys.CARD_WIDTH, cardWidth);
+            cardHeight = intent.getIntExtra(IntentKeys.CARD_HEIGHT, cardHeight);
+            whichVideo = intent.getIntExtra(IntentKeys.WHICH_VIDEO, whichVideo);
+            useSingleBitmap = intent.getBooleanExtra(IntentKeys.USE_SINGLE_BITMAP, useSingleBitmap);
+        }
+
+        loadVideoData(categoryCount, entriesPerCat, disableShadows, useSingleBitmap, cardWidth,
+                cardHeight);
+        setBackground();
+        setupUIElements();
+
+        if (whichVideo != IntentKeys.NO_VIDEO) {
+            int resource = 0;
+            /* For info on how to generate videos see:
+             * https://docs.google.com/document/d/1HV8O-Nm4rc2DwVwiZmT4Wa9pf8XttWndg9saGncTRGw
+             */
+            if (whichVideo == IntentKeys.VIDEO_2160P_60FPS) {
+                resource = R.raw.bbb_sunflower_2160p_60fps;
+            } else if (whichVideo == IntentKeys.VIDEO_1080P_60FPS) {
+                resource = R.raw.testvideo_1080p_60fps;
+            } else if (whichVideo == IntentKeys.VIDEO_480P_60FPS) {
+                resource = R.raw.bbb_480p;
+            }
+            Uri uri = Uri.parse("android.resource://" + getContext().getPackageName() + "/"
+                    + resource);
+            Intent videoIntent = new Intent(Intent.ACTION_VIEW, uri, getContext(),
+                    VideoActivity.class);
+            startActivity(videoIntent);
+        }
+    }
+
+    private void setBackground() {
+        mBackgroundManager = BackgroundManager.getInstance(getActivity());
+        mBackgroundManager.attach(getActivity().getWindow());
+        mBackgroundManager.setDrawable(
+                getResources().getDrawable(R.drawable.default_background, null));
+    }
+
+    private void setupUIElements() {
+        setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.app_banner, null));
+        // Badge, when set, takes precedent over title
+        setTitle(getString(R.string.browse_title));
+        setHeadersState(HEADERS_ENABLED);
+        setHeadersTransitionOnBackEnabled(true);
+        // set headers background color
+        setBrandColor(getResources().getColor(R.color.jank_yellow));
+        // set search icon color
+        setSearchAffordanceColor(getResources().getColor(R.color.search_opaque));
+
+        setHeaderPresenterSelector(new PresenterSelector() {
+            @Override
+            public Presenter getPresenter(Object o) {
+                return new HeaderItemPresenter();
+            }
+        });
+    }
+
+    private void loadVideoData(int categoryCount, int entriesPerCat, boolean disableShadows,
+            boolean useSingleBitmap, int cardWidth, int cardHeight) {
+        ListRowPresenter listRowPresenter = new ListRowPresenter();
+        listRowPresenter.setShadowEnabled(!disableShadows);
+        mRowsAdapter = new ArrayObjectAdapter(listRowPresenter);
+        HashMap<String, List<VideoInfo>> data = VideoProvider.buildMedia(categoryCount,
+                entriesPerCat, cardWidth, cardHeight, getContext(), useSingleBitmap);
+        CardPresenter cardPresenter = new CardPresenter(cardWidth, cardHeight);
+
+        int i = 0;
+        for (Map.Entry<String, List<VideoInfo>> entry : data.entrySet()) {
+            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
+            for (VideoInfo videoInfo : entry.getValue()) {
+                listRowAdapter.add(videoInfo);
+            }
+            HeaderItem header = new HeaderItem(i++, entry.getKey());
+            mRowsAdapter.add(new ListRow(header, listRowAdapter));
+        }
+
+        ArrayObjectAdapter settingsListAdapter = new ArrayObjectAdapter(new GridItemPresenter());
+        for (int j = 0; j < entriesPerCat; j++) {
+            settingsListAdapter.add("Settings " + j);
+        }
+        HeaderItem settingsHeader = new HeaderItem(i++, "Settings");
+        mRowsAdapter.add(new ListRow(settingsHeader, settingsListAdapter));
+
+        setAdapter(mRowsAdapter);
+    }
+}
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/VideoActivity.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/VideoActivity.java
new file mode 100644
index 0000000..f026cc2
--- /dev/null
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/VideoActivity.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 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.google.android.leanbackjank.ui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnPreparedListener;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.VideoView;
+
+public class VideoActivity extends Activity {
+
+    private VideoView mVideoView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+        mVideoView = new VideoView(this);
+        mVideoView.setOnPreparedListener(new OnPreparedListener() {
+            @Override
+            public void onPrepared(MediaPlayer mp) {
+                mp.setLooping(true);
+            }
+        });
+        setContentView(mVideoView);
+
+        if (checkIntent(getIntent())) {
+            enterPictureInPictureMode();
+        }
+    }
+
+    private void playVideo(Uri uri) {
+        mVideoView.setVideoURI(uri);
+        mVideoView.start();
+    }
+
+    private boolean checkIntent(Intent intent) {
+        if (Intent.ACTION_VIEW.equals(intent.getAction())) {
+            Uri uri = intent.getData();
+            playVideo(uri);
+            return true;
+        } else {
+            finish();
+            return false;
+        }
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        checkIntent(intent);
+    }
+
+    @Override
+    protected void onStop() {
+        if (mVideoView != null) {
+            mVideoView.stopPlayback();
+        }
+        super.onStop();
+        finish();
+    }
+}
diff --git a/samples/SupportPercentDemos/AndroidManifest.xml b/samples/SupportPercentDemos/AndroidManifest.xml
index 71fea32..5c22277 100644
--- a/samples/SupportPercentDemos/AndroidManifest.xml
+++ b/samples/SupportPercentDemos/AndroidManifest.xml
@@ -22,7 +22,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.support.percent">
 
-    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
 
     <application android:label="@string/activity_sample_code"
             android:supportsRtl="true"
diff --git a/samples/SupportPercentDemos/build.gradle b/samples/SupportPercentDemos/build.gradle
index e3caf1d..1995a8d 100644
--- a/samples/SupportPercentDemos/build.gradle
+++ b/samples/SupportPercentDemos/build.gradle
@@ -8,7 +8,7 @@
     compileSdkVersion project.ext.currentSdk
 
     defaultConfig {
-        minSdkVersion 11
+        minSdkVersion 14
     }
 
     sourceSets {
@@ -19,7 +19,7 @@
     }
 
     lintOptions {
-        abortOnError false
+        abortOnError true
     }
 
     compileOptions {
diff --git a/samples/SupportPreferenceDemos/build.gradle b/samples/SupportPreferenceDemos/build.gradle
index e59a348..96307c6 100644
--- a/samples/SupportPreferenceDemos/build.gradle
+++ b/samples/SupportPreferenceDemos/build.gradle
@@ -24,7 +24,7 @@
     }
 
     lintOptions {
-        abortOnError false
+        abortOnError true
     }
 
     compileOptions {
diff --git a/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferences.java b/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferences.java
index 298d0e5..b90f637 100644
--- a/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferences.java
+++ b/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferences.java
@@ -34,8 +34,10 @@
         super.onCreate(savedInstanceState);
 
         // Display the fragment as the main content.
-        getFragmentManager().beginTransaction().replace(android.R.id.content,
-                new PrefsFragment()).commit();
+        if (savedInstanceState == null) {
+            getFragmentManager().beginTransaction().replace(android.R.id.content,
+                    new PrefsFragment()).commit();
+        }
     }
 
     @Override
diff --git a/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesCompat.java b/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesCompat.java
index c716bed..bc4a943 100644
--- a/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesCompat.java
+++ b/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesCompat.java
@@ -34,8 +34,10 @@
         super.onCreate(savedInstanceState);
 
         // Display the fragment as the main content.
-        getSupportFragmentManager().beginTransaction().replace(android.R.id.content,
-                new PrefsFragment()).commit();
+        if (savedInstanceState == null) {
+            getSupportFragmentManager().beginTransaction().replace(android.R.id.content,
+                    new PrefsFragment()).commit();
+        }
     }
 
     @Override
diff --git a/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesLeanback.java b/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesLeanback.java
index 35591dc..f7babfb 100644
--- a/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesLeanback.java
+++ b/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesLeanback.java
@@ -32,8 +32,10 @@
         super.onCreate(savedInstanceState);
 
         // Display the fragment as the main content.
-        getFragmentManager().beginTransaction().replace(android.R.id.content,
-                new SettingsFragment()).commit();
+        if (savedInstanceState == null) {
+            getFragmentManager().beginTransaction().replace(android.R.id.content,
+                    new SettingsFragment()).commit();
+        }
     }
 
 //BEGIN_INCLUDE(support_fragment_leanback)
diff --git a/samples/SupportTransitionDemos/build.gradle b/samples/SupportTransitionDemos/build.gradle
index 5ebdc1b..a80ebcb 100644
--- a/samples/SupportTransitionDemos/build.gradle
+++ b/samples/SupportTransitionDemos/build.gradle
@@ -20,7 +20,7 @@
     }
 
     lintOptions {
-        abortOnError false
+        abortOnError true
     }
 
     compileOptions {
diff --git a/samples/SupportTransitionDemos/res/layout/begin_delayed.xml b/samples/SupportTransitionDemos/res/layout/begin_delayed.xml
index 8aa1bba..ab7de11 100644
--- a/samples/SupportTransitionDemos/res/layout/begin_delayed.xml
+++ b/samples/SupportTransitionDemos/res/layout/begin_delayed.xml
@@ -30,19 +30,28 @@
             app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
             android:elevation="4dp"/>
 
-    <FrameLayout
-            android:id="@+id/root"
+    <LinearLayout
+        android:id="@+id/root"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:padding="16dp"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/message"
             android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:padding="16dp">
+            android:layout_height="wrap_content"
+            android:text="@string/hello_world"
+            android:textSize="18sp"
+            android:padding="8dp"/>
 
         <Button
-                android:id="@+id/button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/begin"/>
+            android:id="@+id/button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/begin"/>
 
-    </FrameLayout>
+    </LinearLayout>
 
 </LinearLayout>
diff --git a/samples/SupportTransitionDemos/res/values/strings.xml b/samples/SupportTransitionDemos/res/values/strings.xml
index 9e528cd..09319e6 100644
--- a/samples/SupportTransitionDemos/res/values/strings.xml
+++ b/samples/SupportTransitionDemos/res/values/strings.xml
@@ -21,4 +21,5 @@
     <string name="beginDelayed">Begin Delayed Transition</string>
     <string name="toggle">Toggle</string>
     <string name="begin">Begin</string>
+    <string name="hello_world">Hello, world!</string>
 </resources>
diff --git a/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/BeginDelayedUsage.java b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/BeginDelayedUsage.java
index 713e76d..9bce29d 100644
--- a/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/BeginDelayedUsage.java
+++ b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/BeginDelayedUsage.java
@@ -18,16 +18,16 @@
 
 import android.os.Bundle;
 import android.support.transition.TransitionManager;
-import android.support.v4.view.GravityCompat;
 import android.view.View;
-import android.widget.Button;
-import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
 import com.example.android.support.transition.R;
 
 public class BeginDelayedUsage extends TransitionUsageBase {
 
-    private FrameLayout mRoot;
-    private Button mButton;
+    private LinearLayout mRoot;
+    private TextView mMessage;
 
     @Override
     int getLayoutResId() {
@@ -37,9 +37,9 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        mRoot = (FrameLayout) findViewById(R.id.root);
-        mButton = (Button) findViewById(R.id.button);
-        mButton.setOnClickListener(new View.OnClickListener() {
+        mRoot = (LinearLayout) findViewById(R.id.root);
+        mMessage = (TextView) findViewById(R.id.message);
+        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
                 toggle();
@@ -49,13 +49,11 @@
 
     private void toggle() {
         TransitionManager.beginDelayedTransition(mRoot);
-        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mButton.getLayoutParams();
-        if ((params.gravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK) == GravityCompat.END) {
-            params.gravity = params.gravity ^ GravityCompat.END | GravityCompat.START;
+        if (mMessage.getVisibility() != View.VISIBLE) {
+            mMessage.setVisibility(View.VISIBLE);
         } else {
-            params.gravity = params.gravity ^ GravityCompat.START | GravityCompat.END;
+            mMessage.setVisibility(View.GONE);
         }
-        mButton.setLayoutParams(params);
     }
 
 }
diff --git a/samples/SupportVectorDrawable/animated/AndroidManifest.xml b/samples/SupportVectorDrawable/animated/AndroidManifest.xml
index 55d6bc6..09a5dbb 100644
--- a/samples/SupportVectorDrawable/animated/AndroidManifest.xml
+++ b/samples/SupportVectorDrawable/animated/AndroidManifest.xml
@@ -17,7 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.support.vectordrawable" >
 
-    <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23"/>
 
     <application android:icon="@drawable/app_sample_code" android:label="AnimatedVectorDrawableCompatTest" >
         <activity android:name="com.example.android.support.vectordrawable.app.AnimatedButtonBackground" />
@@ -28,4 +28,4 @@
         </intent-filter>
     </application>
 
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/settings.gradle b/settings.gradle
index e4e79a8..3228d9c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -85,6 +85,14 @@
 include ':support-exifinterface'
 project(':support-exifinterface').projectDir = new File(rootDir, 'exifinterface')
 
+include ':support-wearable'
+project(':support-wearable').projectDir = new File(rootDir, 'wearable')
+
+include ':support-tv-provider'
+project(':support-tv-provider').projectDir = new File(rootDir, 'tv-provider')
+
+include ':support-instantvideo'
+project(':support-instantvideo').projectDir = new File(rootDir, 'instantvideo')
 
 /////////////////////////////
 //
@@ -100,6 +108,9 @@
 include ':support-leanback-demos'
 project(':support-leanback-demos').projectDir = new File(samplesRoot, 'SupportLeanbackDemos')
 
+include ':support-leanback-jank'
+project(':support-leanback-jank').projectDir = new File(samplesRoot, 'SupportLeanbackJank')
+
 include ':support-percent-demos'
 project(':support-percent-demos').projectDir = new File(samplesRoot, 'SupportPercentDemos')
 
@@ -128,3 +139,6 @@
 
 include ':doclava'
 project(':doclava').projectDir = new File(externalRoot, 'doclava')
+
+include ':jdiff'
+project(':jdiff').projectDir = new File(externalRoot, 'jdiff')
diff --git a/transition/Android.mk b/transition/Android.mk
index aefedd7..b647dfc 100644
--- a/transition/Android.mk
+++ b/transition/Android.mk
@@ -28,13 +28,10 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := \
     $(call all-java-files-under,base) \
-    $(call all-java-files-under,ics) \
-    $(call all-java-files-under,kitkat) \
-    $(call all-java-files-under,api21) \
-    $(call all-java-files-under,api23) \
+    $(call all-java-files-under,api14) \
+    $(call all-java-files-under,api18) \
     $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-annotations \
     android-support-v4
diff --git a/transition/api14/android/support/transition/ViewGroupOverlayApi14.java b/transition/api14/android/support/transition/ViewGroupOverlayApi14.java
new file mode 100644
index 0000000..4c5579d
--- /dev/null
+++ b/transition/api14/android/support/transition/ViewGroupOverlayApi14.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+import android.view.View;
+import android.view.ViewGroup;
+
+@RequiresApi(14)
+class ViewGroupOverlayApi14 extends ViewOverlayApi14 implements ViewGroupOverlayImpl {
+
+    ViewGroupOverlayApi14(Context context, ViewGroup hostView, View requestingView) {
+        super(context, hostView, requestingView);
+    }
+
+    static ViewGroupOverlayApi14 createFrom(ViewGroup viewGroup) {
+        return (ViewGroupOverlayApi14) ViewOverlayApi14.createFrom(viewGroup);
+    }
+
+    @Override
+    public void add(@NonNull View view) {
+        mOverlayViewGroup.add(view);
+    }
+
+    @Override
+    public void remove(@NonNull View view) {
+        mOverlayViewGroup.remove(view);
+    }
+
+}
diff --git a/transition/api14/android/support/transition/ViewGroupUtilsApi14.java b/transition/api14/android/support/transition/ViewGroupUtilsApi14.java
new file mode 100644
index 0000000..e37a1cc
--- /dev/null
+++ b/transition/api14/android/support/transition/ViewGroupUtilsApi14.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import android.animation.LayoutTransition;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+import android.util.Log;
+import android.view.ViewGroup;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+@RequiresApi(14)
+class ViewGroupUtilsApi14 implements ViewGroupUtilsImpl {
+
+    private static final String TAG = "ViewGroupUtilsApi14";
+
+    private static final int LAYOUT_TRANSITION_CHANGING = 4;
+
+    private static LayoutTransition sEmptyLayoutTransition;
+
+    private static Field sLayoutSuppressedField;
+    private static boolean sLayoutSuppressedFieldFetched;
+
+    private static Method sCancelMethod;
+    private static boolean sCancelMethodFetched;
+
+    @Override
+    public ViewGroupOverlayImpl getOverlay(@NonNull ViewGroup group) {
+        return ViewGroupOverlayApi14.createFrom(group);
+    }
+
+    @Override
+    public void suppressLayout(@NonNull ViewGroup group, boolean suppress) {
+        // Prepare the dummy LayoutTransition
+        if (sEmptyLayoutTransition == null) {
+            sEmptyLayoutTransition = new LayoutTransition() {
+                @Override
+                public boolean isChangingLayout() {
+                    return true;
+                }
+            };
+            sEmptyLayoutTransition.setAnimator(LayoutTransition.APPEARING, null);
+            sEmptyLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, null);
+            sEmptyLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, null);
+            sEmptyLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, null);
+            sEmptyLayoutTransition.setAnimator(LAYOUT_TRANSITION_CHANGING, null);
+        }
+        if (suppress) {
+            // Save the current LayoutTransition
+            final LayoutTransition layoutTransition = group.getLayoutTransition();
+            if (layoutTransition != null) {
+                if (layoutTransition.isRunning()) {
+                    cancelLayoutTransition(layoutTransition);
+                }
+                if (layoutTransition != sEmptyLayoutTransition) {
+                    group.setTag(R.id.transition_layout_save, layoutTransition);
+                }
+            }
+            // Suppress the layout
+            group.setLayoutTransition(sEmptyLayoutTransition);
+        } else {
+            // Thaw the layout suppression
+            group.setLayoutTransition(null);
+            // Request layout if necessary
+            if (!sLayoutSuppressedFieldFetched) {
+                try {
+                    sLayoutSuppressedField = ViewGroup.class.getDeclaredField("mLayoutSuppressed");
+                    sLayoutSuppressedField.setAccessible(true);
+                } catch (NoSuchFieldException e) {
+                    Log.i(TAG, "Failed to access mLayoutSuppressed field by reflection");
+                }
+                sLayoutSuppressedFieldFetched = true;
+            }
+            boolean layoutSuppressed = false;
+            if (sLayoutSuppressedField != null) {
+                try {
+                    layoutSuppressed = sLayoutSuppressedField.getBoolean(group);
+                    if (layoutSuppressed) {
+                        sLayoutSuppressedField.setBoolean(group, false);
+                    }
+                } catch (IllegalAccessException e) {
+                    Log.i(TAG, "Failed to get mLayoutSuppressed field by reflection");
+                }
+            }
+            if (layoutSuppressed) {
+                group.requestLayout();
+            }
+            // Restore the saved LayoutTransition
+            final LayoutTransition layoutTransition =
+                    (LayoutTransition) group.getTag(R.id.transition_layout_save);
+            if (layoutTransition != null) {
+                group.setTag(R.id.transition_layout_save, null);
+                group.setLayoutTransition(layoutTransition);
+            }
+        }
+    }
+
+    private static void cancelLayoutTransition(LayoutTransition t) {
+        if (!sCancelMethodFetched) {
+            try {
+                sCancelMethod = LayoutTransition.class.getDeclaredMethod("cancel");
+                sCancelMethod.setAccessible(true);
+            } catch (NoSuchMethodException e) {
+                Log.i(TAG, "Failed to access cancel method by reflection");
+            }
+            sCancelMethodFetched = true;
+        }
+        if (sCancelMethod != null) {
+            try {
+                sCancelMethod.invoke(t);
+            } catch (IllegalAccessException e) {
+                Log.i(TAG, "Failed to access cancel method by reflection");
+            } catch (InvocationTargetException e) {
+                Log.i(TAG, "Failed to invoke cancel method by reflection");
+            }
+        }
+    }
+
+}
diff --git a/transition/ics/android/support/transition/ViewOverlay.java b/transition/api14/android/support/transition/ViewOverlayApi14.java
similarity index 88%
rename from transition/ics/android/support/transition/ViewOverlay.java
rename to transition/api14/android/support/transition/ViewOverlayApi14.java
index 8b36850..c45da98 100644
--- a/transition/ics/android/support/transition/ViewOverlay.java
+++ b/transition/api14/android/support/transition/ViewOverlayApi14.java
@@ -18,12 +18,11 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.R;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
@@ -37,8 +36,7 @@
 import java.util.ArrayList;
 
 @RequiresApi(14)
-@TargetApi(14)
-class ViewOverlay {
+class ViewOverlayApi14 implements ViewOverlayImpl {
 
     /**
      * The actual container for the drawables (and views, if it's a ViewGroupOverlay).
@@ -47,14 +45,14 @@
      */
     protected OverlayViewGroup mOverlayViewGroup;
 
-    ViewOverlay(Context context, ViewGroup hostView, View requestingView) {
+    ViewOverlayApi14(Context context, ViewGroup hostView, View requestingView) {
         mOverlayViewGroup = new OverlayViewGroup(context, hostView, requestingView, this);
     }
 
     static ViewGroup getContentView(View view) {
         View parent = view;
         while (parent != null) {
-            if (parent.getId() == R.id.content && parent instanceof ViewGroup) {
+            if (parent.getId() == android.R.id.content && parent instanceof ViewGroup) {
                 return (ViewGroup) parent;
             }
             if (parent.getParent() instanceof ViewGroup) {
@@ -64,7 +62,7 @@
         return null;
     }
 
-    public static ViewOverlay createFrom(View view) {
+    static ViewOverlayApi14 createFrom(View view) {
         ViewGroup contentView = getContentView(view);
         if (contentView != null) {
             final int numChildren = contentView.getChildCount();
@@ -74,7 +72,7 @@
                     return ((OverlayViewGroup) child).mViewOverlay;
                 }
             }
-            return new ViewGroupOverlay(contentView.getContext(), contentView, view);
+            return new ViewGroupOverlayApi14(contentView.getContext(), contentView, view);
         }
         return null;
     }
@@ -87,40 +85,26 @@
         return mOverlayViewGroup;
     }
 
-    /**
-     * Adds a Drawable to the overlay. The bounds of the drawable should be relative to
-     * the host view. Any drawable added to the overlay should be removed when it is no longer
-     * needed or no longer visible.
-     *
-     * @param drawable The Drawable to be added to the overlay. This drawable will be
-     *                 drawn when the view redraws its overlay.
-     * @see #remove(Drawable)
-     */
-    public void add(Drawable drawable) {
+    @Override
+    public void add(@NonNull Drawable drawable) {
         mOverlayViewGroup.add(drawable);
     }
 
-    /**
-     * Removes the specified Drawable from the overlay.
-     *
-     * @param drawable The Drawable to be removed from the overlay.
-     * @see #add(Drawable)
-     */
-    public void remove(Drawable drawable) {
-        mOverlayViewGroup.remove(drawable);
-    }
-
-    /**
-     * Removes all content from the overlay.
-     */
+    @Override
     public void clear() {
         mOverlayViewGroup.clear();
     }
 
+    @Override
+    public void remove(@NonNull Drawable drawable) {
+        mOverlayViewGroup.remove(drawable);
+    }
+
     boolean isEmpty() {
         return mOverlayViewGroup.isEmpty();
     }
 
+
     /**
      * OverlayViewGroup is a container that View and ViewGroup use to host
      * drawables and views added to their overlays  ({@link ViewOverlay} and
@@ -168,16 +152,16 @@
         /**
          * Reference to the hosting overlay object
          */
-        ViewOverlay mViewOverlay;
+        ViewOverlayApi14 mViewOverlay;
 
         OverlayViewGroup(Context context, ViewGroup hostView, View requestingView,
-                ViewOverlay viewOverlay) {
+                ViewOverlayApi14 viewOverlay) {
             super(context);
             mHostView = hostView;
             mRequestingView = requestingView;
             setRight(hostView.getWidth());
             setBottom(hostView.getHeight());
-            ((ViewGroup) hostView).addView(this);
+            hostView.addView(this);
             mViewOverlay = viewOverlay;
         }
 
@@ -190,7 +174,7 @@
         public void add(Drawable drawable) {
             if (mDrawables == null) {
 
-                mDrawables = new ArrayList<Drawable>();
+                mDrawables = new ArrayList<>();
             }
             if (!mDrawables.contains(drawable)) {
                 // Make each drawable unique in the overlay; can't add it more than once
@@ -216,8 +200,8 @@
         public void add(View child) {
             if (child.getParent() instanceof ViewGroup) {
                 ViewGroup parent = (ViewGroup) child.getParent();
-                if (parent != mHostView && parent.getParent() != null) {// &&
-//                        parent.isAttachedToWindow()) {
+                if (parent != mHostView && parent.getParent() != null
+                        && ViewCompat.isAttachedToWindow(parent)) {
                     // Moving to different container; figure out how to position child such that
                     // it is in the same location on the screen
                     int[] parentLocation = new int[2];
@@ -255,11 +239,8 @@
         }
 
         boolean isEmpty() {
-            if (getChildCount() == 0 &&
-                    (mDrawables == null || mDrawables.size() == 0)) {
-                return true;
-            }
-            return false;
+            return getChildCount() == 0
+                    && (mDrawables == null || mDrawables.size() == 0);
         }
 
         @Override
@@ -372,4 +353,5 @@
         }
     }
 
+
 }
diff --git a/transition/ics/android/support/transition/ChangeBoundsIcs.java b/transition/api14/android/support/transition/ViewUtilsApi14.java
similarity index 67%
rename from transition/ics/android/support/transition/ChangeBoundsIcs.java
rename to transition/api14/android/support/transition/ViewUtilsApi14.java
index 61b7ac1..6131114 100644
--- a/transition/ics/android/support/transition/ChangeBoundsIcs.java
+++ b/transition/api14/android/support/transition/ViewUtilsApi14.java
@@ -16,20 +16,21 @@
 
 package android.support.transition;
 
-import android.annotation.TargetApi;
+import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
+import android.view.View;
 
 @RequiresApi(14)
-@TargetApi(14)
-class ChangeBoundsIcs extends TransitionIcs implements ChangeBoundsInterface {
+class ViewUtilsApi14 implements ViewUtilsImpl {
 
-    public ChangeBoundsIcs(TransitionInterface transition) {
-        init(transition, new ChangeBoundsPort());
+    @Override
+    public ViewOverlayImpl getOverlay(@NonNull View view) {
+        return ViewOverlayApi14.createFrom(view);
     }
 
     @Override
-    public void setResizeClip(boolean resizeClip) {
-        ((ChangeBoundsPort) mTransition).setResizeClip(resizeClip);
+    public WindowIdImpl getWindowId(@NonNull View view) {
+        return new WindowIdApi14(view.getWindowToken());
     }
 
 }
diff --git a/transition/api23/android/support/transition/TransitionApi23.java b/transition/api14/android/support/transition/WindowIdApi14.java
similarity index 69%
copy from transition/api23/android/support/transition/TransitionApi23.java
copy to transition/api14/android/support/transition/WindowIdApi14.java
index 0df0ec5..52768c2 100644
--- a/transition/api23/android/support/transition/TransitionApi23.java
+++ b/transition/api14/android/support/transition/WindowIdApi14.java
@@ -16,17 +16,21 @@
 
 package android.support.transition;
 
-import android.annotation.TargetApi;
+import android.os.IBinder;
 import android.support.annotation.RequiresApi;
 
-@RequiresApi(23)
-@TargetApi(23)
-class TransitionApi23 extends TransitionKitKat {
+@RequiresApi(14)
+class WindowIdApi14 implements WindowIdImpl {
+
+    private final IBinder mToken;
+
+    WindowIdApi14(IBinder token) {
+        mToken = token;
+    }
 
     @Override
-    public TransitionImpl removeTarget(int targetId) {
-        mTransition.removeTarget(targetId);
-        return this;
+    public boolean equals(Object o) {
+        return o instanceof WindowIdApi14 && ((WindowIdApi14) o).mToken.equals(this.mToken);
     }
 
 }
diff --git a/transition/api18/android/support/transition/ViewGroupOverlayApi18.java b/transition/api18/android/support/transition/ViewGroupOverlayApi18.java
new file mode 100644
index 0000000..a32d8be
--- /dev/null
+++ b/transition/api18/android/support/transition/ViewGroupOverlayApi18.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroupOverlay;
+
+@RequiresApi(18)
+class ViewGroupOverlayApi18 implements ViewGroupOverlayImpl {
+
+    private final ViewGroupOverlay mViewGroupOverlay;
+
+    ViewGroupOverlayApi18(@NonNull ViewGroup group) {
+        mViewGroupOverlay = group.getOverlay();
+    }
+
+    @Override
+    public void add(@NonNull Drawable drawable) {
+        mViewGroupOverlay.add(drawable);
+    }
+
+    @Override
+    public void clear() {
+        mViewGroupOverlay.clear();
+    }
+
+    @Override
+    public void remove(@NonNull Drawable drawable) {
+        mViewGroupOverlay.remove(drawable);
+    }
+
+    @Override
+    public void add(@NonNull View view) {
+        mViewGroupOverlay.add(view);
+    }
+
+    @Override
+    public void remove(@NonNull View view) {
+        mViewGroupOverlay.remove(view);
+    }
+
+}
diff --git a/transition/api18/android/support/transition/ViewGroupUtilsApi18.java b/transition/api18/android/support/transition/ViewGroupUtilsApi18.java
new file mode 100644
index 0000000..7aad4e1
--- /dev/null
+++ b/transition/api18/android/support/transition/ViewGroupUtilsApi18.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+import android.util.Log;
+import android.view.ViewGroup;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+@RequiresApi(18)
+class ViewGroupUtilsApi18 extends ViewGroupUtilsApi14 {
+
+    private static final String TAG = "ViewUtilsApi18";
+
+    private static Method sSuppressLayoutMethod;
+    private static boolean sSuppressLayoutMethodFetched;
+
+    @Override
+    public ViewGroupOverlayImpl getOverlay(@NonNull ViewGroup group) {
+        return new ViewGroupOverlayApi18(group);
+    }
+
+    @Override
+    public void suppressLayout(@NonNull ViewGroup group, boolean suppress) {
+        fetchSuppressLayoutMethod();
+        if (sSuppressLayoutMethod != null) {
+            try {
+                sSuppressLayoutMethod.invoke(group, suppress);
+            } catch (IllegalAccessException e) {
+                Log.i(TAG, "Failed to invoke suppressLayout method", e);
+            } catch (InvocationTargetException e) {
+                Log.i(TAG, "Error invoking suppressLayout method", e);
+            }
+        }
+    }
+
+    private void fetchSuppressLayoutMethod() {
+        if (!sSuppressLayoutMethodFetched) {
+            try {
+                sSuppressLayoutMethod = ViewGroup.class.getDeclaredMethod("suppressLayout",
+                        boolean.class);
+                sSuppressLayoutMethod.setAccessible(true);
+            } catch (NoSuchMethodException e) {
+                Log.i(TAG, "Failed to retrieve suppressLayout method", e);
+            }
+            sSuppressLayoutMethodFetched = true;
+        }
+    }
+
+}
diff --git a/transition/api18/android/support/transition/ViewOverlayApi18.java b/transition/api18/android/support/transition/ViewOverlayApi18.java
new file mode 100644
index 0000000..c2bc4f0
--- /dev/null
+++ b/transition/api18/android/support/transition/ViewOverlayApi18.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+import android.view.View;
+import android.view.ViewOverlay;
+
+@RequiresApi(18)
+class ViewOverlayApi18 implements ViewOverlayImpl {
+
+    private final ViewOverlay mViewOverlay;
+
+    ViewOverlayApi18(@NonNull View view) {
+        mViewOverlay = view.getOverlay();
+    }
+
+    @Override
+    public void add(@NonNull Drawable drawable) {
+        mViewOverlay.add(drawable);
+    }
+
+    @Override
+    public void clear() {
+        mViewOverlay.clear();
+    }
+
+    @Override
+    public void remove(@NonNull Drawable drawable) {
+        mViewOverlay.remove(drawable);
+    }
+
+}
diff --git a/transition/api23/android/support/transition/TransitionApi23.java b/transition/api18/android/support/transition/ViewUtilsApi18.java
similarity index 67%
copy from transition/api23/android/support/transition/TransitionApi23.java
copy to transition/api18/android/support/transition/ViewUtilsApi18.java
index 0df0ec5..9cfa668 100644
--- a/transition/api23/android/support/transition/TransitionApi23.java
+++ b/transition/api18/android/support/transition/ViewUtilsApi18.java
@@ -16,17 +16,21 @@
 
 package android.support.transition;
 
-import android.annotation.TargetApi;
+import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
+import android.view.View;
 
-@RequiresApi(23)
-@TargetApi(23)
-class TransitionApi23 extends TransitionKitKat {
+@RequiresApi(18)
+class ViewUtilsApi18 extends ViewUtilsApi14 {
 
     @Override
-    public TransitionImpl removeTarget(int targetId) {
-        mTransition.removeTarget(targetId);
-        return this;
+    public ViewOverlayImpl getOverlay(@NonNull View view) {
+        return new ViewOverlayApi18(view);
+    }
+
+    @Override
+    public WindowIdImpl getWindowId(@NonNull View view) {
+        return new WindowIdApi18(view);
     }
 
 }
diff --git a/transition/kitkat/android/support/transition/ChangeBoundsKitKat.java b/transition/api18/android/support/transition/WindowIdApi18.java
similarity index 63%
rename from transition/kitkat/android/support/transition/ChangeBoundsKitKat.java
rename to transition/api18/android/support/transition/WindowIdApi18.java
index e8575d4..badae42 100644
--- a/transition/kitkat/android/support/transition/ChangeBoundsKitKat.java
+++ b/transition/api18/android/support/transition/WindowIdApi18.java
@@ -13,23 +13,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package android.support.transition;
 
-import android.annotation.TargetApi;
+import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
+import android.view.View;
+import android.view.WindowId;
 
-@RequiresApi(19)
-@TargetApi(19)
-class ChangeBoundsKitKat extends TransitionKitKat implements ChangeBoundsInterface {
+@RequiresApi(18)
+class WindowIdApi18 implements WindowIdImpl {
 
-    public ChangeBoundsKitKat(TransitionInterface transition) {
-        init(transition, new android.transition.ChangeBounds());
+    private final WindowId mWindowId;
+
+    WindowIdApi18(@NonNull View view) {
+        mWindowId = view.getWindowId();
     }
 
     @Override
-    public void setResizeClip(boolean resizeClip) {
-        ((android.transition.ChangeBounds) mTransition).setResizeClip(resizeClip);
+    public boolean equals(Object o) {
+        return o instanceof WindowIdApi18 && ((WindowIdApi18) o).mWindowId.equals(mWindowId);
     }
 
 }
diff --git a/transition/api21/android/support/transition/SceneApi21.java b/transition/api21/android/support/transition/SceneApi21.java
deleted file mode 100644
index 1e8f0ba..0000000
--- a/transition/api21/android/support/transition/SceneApi21.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.view.View;
-import android.view.ViewGroup;
-
-@RequiresApi(21)
-@TargetApi(21)
-class SceneApi21 extends SceneWrapper {
-
-    @Override
-    public void init(ViewGroup sceneRoot) {
-        mScene = new android.transition.Scene(sceneRoot);
-    }
-
-    @Override
-    public void init(ViewGroup sceneRoot, View layout) {
-        mScene = new android.transition.Scene(sceneRoot, layout);
-    }
-
-    @Override
-    public void enter() {
-        mScene.enter();
-    }
-
-}
diff --git a/transition/api21/android/support/transition/SceneStaticsApi21.java b/transition/api21/android/support/transition/SceneStaticsApi21.java
deleted file mode 100644
index 547ca70..0000000
--- a/transition/api21/android/support/transition/SceneStaticsApi21.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.support.annotation.RequiresApi;
-import android.view.ViewGroup;
-
-@RequiresApi(21)
-@TargetApi(21)
-class SceneStaticsApi21 extends SceneStaticsImpl {
-
-    @Override
-    public SceneImpl getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) {
-        SceneApi21 scene = new SceneApi21();
-        scene.mScene = android.transition.Scene.getSceneForLayout(sceneRoot, layoutId, context);
-        return scene;
-    }
-
-}
diff --git a/transition/base/android/support/transition/ChangeBoundsInterface.java b/transition/base/android/support/transition/ChangeBoundsInterface.java
deleted file mode 100644
index 3dc5a23..0000000
--- a/transition/base/android/support/transition/ChangeBoundsInterface.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-/**
- * Interface for platform specific ChangeBounds implementations.
- */
-interface ChangeBoundsInterface {
-
-    void setResizeClip(boolean resizeClip);
-
-}
diff --git a/transition/base/android/support/transition/SceneImpl.java b/transition/base/android/support/transition/SceneImpl.java
deleted file mode 100644
index 0ee9461..0000000
--- a/transition/base/android/support/transition/SceneImpl.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * Base class for platform specific Scene implementations.
- */
-abstract class SceneImpl {
-
-    public abstract void init(ViewGroup sceneRoot);
-
-    public abstract void init(ViewGroup sceneRoot, View layout);
-
-    public abstract ViewGroup getSceneRoot();
-
-    public abstract void exit();
-
-    public abstract void enter();
-
-    public abstract void setEnterAction(Runnable action);
-
-    public abstract void setExitAction(Runnable action);
-
-}
diff --git a/transition/base/android/support/transition/SceneStaticsImpl.java b/transition/base/android/support/transition/SceneStaticsImpl.java
deleted file mode 100644
index 2d8a138..0000000
--- a/transition/base/android/support/transition/SceneStaticsImpl.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.content.Context;
-import android.view.ViewGroup;
-
-abstract class SceneStaticsImpl {
-
-    public abstract SceneImpl getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context);
-
-}
diff --git a/transition/base/android/support/transition/TransitionImpl.java b/transition/base/android/support/transition/TransitionImpl.java
deleted file mode 100644
index ab482b8..0000000
--- a/transition/base/android/support/transition/TransitionImpl.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.animation.TimeInterpolator;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.util.List;
-
-/**
- * Base class for platform specific Transition implementations.
- */
-abstract class TransitionImpl {
-
-    public abstract void init(TransitionInterface external, Object internal);
-
-    public void init(TransitionInterface external) {
-        init(external, null);
-    }
-
-    public abstract TransitionImpl addListener(TransitionInterfaceListener listener);
-
-    public abstract TransitionImpl removeListener(TransitionInterfaceListener listener);
-
-    public abstract TransitionImpl addTarget(View target);
-
-    public abstract TransitionImpl addTarget(int targetId);
-
-    public abstract void captureEndValues(TransitionValues transitionValues);
-
-    public abstract void captureStartValues(TransitionValues transitionValues);
-
-    public abstract Animator createAnimator(ViewGroup sceneRoot,
-            TransitionValues startValues, TransitionValues endValues);
-
-    public abstract TransitionImpl excludeChildren(View target, boolean exclude);
-
-    public abstract TransitionImpl excludeChildren(int targetId, boolean exclude);
-
-    public abstract TransitionImpl excludeChildren(Class type, boolean exclude);
-
-    public abstract TransitionImpl excludeTarget(View target, boolean exclude);
-
-    public abstract TransitionImpl excludeTarget(int targetId, boolean exclude);
-
-    public abstract TransitionImpl excludeTarget(Class type, boolean exclude);
-
-    public abstract long getDuration();
-
-    public abstract TransitionImpl setDuration(long duration);
-
-    public abstract TimeInterpolator getInterpolator();
-
-    public abstract TransitionImpl setInterpolator(TimeInterpolator interpolator);
-
-    public abstract String getName();
-
-    public abstract long getStartDelay();
-
-    public abstract TransitionImpl setStartDelay(long startDelay);
-
-    public abstract List<Integer> getTargetIds();
-
-    public abstract List<View> getTargets();
-
-    public abstract String[] getTransitionProperties();
-
-    public abstract TransitionValues getTransitionValues(View view, boolean start);
-
-    public abstract TransitionImpl removeTarget(View target);
-
-    public abstract TransitionImpl removeTarget(int targetId);
-
-}
diff --git a/transition/base/android/support/transition/TransitionInterface.java b/transition/base/android/support/transition/TransitionInterface.java
deleted file mode 100644
index c498bd0..0000000
--- a/transition/base/android/support/transition/TransitionInterface.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.view.ViewGroup;
-
-/**
- * Used to reference android.support.transition.Transition in a backward compatible manner.
- */
-interface TransitionInterface {
-
-    void captureEndValues(TransitionValues transitionValues);
-
-    void captureStartValues(TransitionValues transitionValues);
-
-    Animator createAnimator(ViewGroup sceneRoot,
-            TransitionValues startValues, TransitionValues endValues);
-
-}
diff --git a/transition/base/android/support/transition/TransitionInterfaceListener.java b/transition/base/android/support/transition/TransitionInterfaceListener.java
deleted file mode 100644
index 9d27759..0000000
--- a/transition/base/android/support/transition/TransitionInterfaceListener.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-interface TransitionInterfaceListener<TransitionT extends TransitionInterface> {
-
-    void onTransitionStart(TransitionT transition);
-
-    void onTransitionEnd(TransitionT transition);
-
-    void onTransitionCancel(TransitionT transition);
-
-    void onTransitionPause(TransitionT transition);
-
-    void onTransitionResume(TransitionT transition);
-
-}
diff --git a/transition/base/android/support/transition/TransitionManagerImpl.java b/transition/base/android/support/transition/TransitionManagerImpl.java
deleted file mode 100644
index 861e875..0000000
--- a/transition/base/android/support/transition/TransitionManagerImpl.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-/**
- * Base class for platform specific TransitionManager implementations.
- */
-abstract class TransitionManagerImpl {
-
-    public abstract void setTransition(SceneImpl scene, TransitionImpl transition);
-
-    public abstract void setTransition(SceneImpl fromScene, SceneImpl toScene,
-            TransitionImpl transition);
-
-    public abstract void transitionTo(SceneImpl scene);
-
-}
diff --git a/transition/base/android/support/transition/TransitionManagerStaticsImpl.java b/transition/base/android/support/transition/TransitionManagerStaticsImpl.java
deleted file mode 100644
index 5171ba9..0000000
--- a/transition/base/android/support/transition/TransitionManagerStaticsImpl.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.view.ViewGroup;
-
-/**
- * Base class for platform specific TransitionManager implementations.
- */
-abstract class TransitionManagerStaticsImpl {
-
-    public abstract void go(SceneImpl scene);
-
-    public abstract void go(SceneImpl scene, TransitionImpl transition);
-
-    public abstract void beginDelayedTransition(final ViewGroup sceneRoot);
-
-    public abstract void beginDelayedTransition(final ViewGroup sceneRoot,
-            TransitionImpl transition);
-
-}
diff --git a/transition/base/android/support/transition/TransitionSetImpl.java b/transition/base/android/support/transition/TransitionSetImpl.java
deleted file mode 100644
index 5c5e8a6..0000000
--- a/transition/base/android/support/transition/TransitionSetImpl.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-interface TransitionSetImpl {
-
-    int getOrdering();
-
-    TransitionSetImpl setOrdering(int ordering);
-
-    TransitionSetImpl addTransition(TransitionImpl transition);
-
-    TransitionSetImpl removeTransition(TransitionImpl transition);
-
-}
diff --git a/transition/ics/android/support/transition/ViewGroupOverlay.java b/transition/base/android/support/transition/ViewGroupOverlayImpl.java
similarity index 73%
rename from transition/ics/android/support/transition/ViewGroupOverlay.java
rename to transition/base/android/support/transition/ViewGroupOverlayImpl.java
index da91466..82b1f6b 100644
--- a/transition/ics/android/support/transition/ViewGroupOverlay.java
+++ b/transition/base/android/support/transition/ViewGroupOverlayImpl.java
@@ -16,24 +16,12 @@
 
 package android.support.transition;
 
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
 import android.view.View;
-import android.view.ViewGroup;
 
 @RequiresApi(14)
-@TargetApi(14)
-class ViewGroupOverlay extends ViewOverlay {
-
-    ViewGroupOverlay(Context context, ViewGroup hostView, View requestingView) {
-        super(context, hostView, requestingView);
-    }
-
-    public static ViewGroupOverlay createFrom(ViewGroup viewGroup) {
-        return (ViewGroupOverlay) ViewOverlay.createFrom(viewGroup);
-    }
+interface ViewGroupOverlayImpl extends ViewOverlayImpl {
 
     /**
      * Adds a View to the overlay. The bounds of the added view should be
@@ -56,20 +44,17 @@
      * @param view The View to be added to the overlay. The added view will be
      *             drawn when the overlay is drawn.
      * @see #remove(View)
-     * @see android.view.ViewOverlay#add(Drawable)
+     * @see android.view.ViewOverlay#add(android.graphics.drawable.Drawable)
      */
-    public void add(View view) {
-        mOverlayViewGroup.add(view);
-    }
+    void add(@NonNull View view);
 
     /**
      * Removes the specified View from the overlay.
      *
      * @param view The View to be removed from the overlay.
      * @see #add(View)
-     * @see android.view.ViewOverlay#remove(Drawable)
+     * @see android.view.ViewOverlay#remove(android.graphics.drawable.Drawable)
      */
-    public void remove(View view) {
-        mOverlayViewGroup.remove(view);
-    }
+    void remove(@NonNull View view);
+
 }
diff --git a/transition/api23/android/support/transition/TransitionApi23.java b/transition/base/android/support/transition/ViewGroupUtilsImpl.java
similarity index 72%
copy from transition/api23/android/support/transition/TransitionApi23.java
copy to transition/base/android/support/transition/ViewGroupUtilsImpl.java
index 0df0ec5..8b8d8a2 100644
--- a/transition/api23/android/support/transition/TransitionApi23.java
+++ b/transition/base/android/support/transition/ViewGroupUtilsImpl.java
@@ -16,17 +16,15 @@
 
 package android.support.transition;
 
-import android.annotation.TargetApi;
+import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
+import android.view.ViewGroup;
 
-@RequiresApi(23)
-@TargetApi(23)
-class TransitionApi23 extends TransitionKitKat {
+@RequiresApi(14)
+interface ViewGroupUtilsImpl {
 
-    @Override
-    public TransitionImpl removeTarget(int targetId) {
-        mTransition.removeTarget(targetId);
-        return this;
-    }
+    ViewGroupOverlayImpl getOverlay(@NonNull ViewGroup group);
+
+    void suppressLayout(@NonNull ViewGroup group, boolean suppress);
 
 }
diff --git a/transition/base/android/support/transition/ViewOverlayImpl.java b/transition/base/android/support/transition/ViewOverlayImpl.java
new file mode 100644
index 0000000..b699970
--- /dev/null
+++ b/transition/base/android/support/transition/ViewOverlayImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+
+@RequiresApi(14)
+interface ViewOverlayImpl {
+
+    /**
+     * Adds a Drawable to the overlay. The bounds of the drawable should be relative to
+     * the host view. Any drawable added to the overlay should be removed when it is no longer
+     * needed or no longer visible.
+     *
+     * @param drawable The Drawable to be added to the overlay. This drawable will be
+     *                 drawn when the view redraws its overlay.
+     * @see #remove(Drawable)
+     */
+    void add(@NonNull Drawable drawable);
+
+    /**
+     * Removes all content from the overlay.
+     */
+    void clear();
+
+    /**
+     * Removes the specified Drawable from the overlay.
+     *
+     * @param drawable The Drawable to be removed from the overlay.
+     * @see #add(Drawable)
+     */
+    void remove(@NonNull Drawable drawable);
+
+}
diff --git a/transition/api23/android/support/transition/TransitionApi23.java b/transition/base/android/support/transition/ViewUtilsImpl.java
similarity index 72%
rename from transition/api23/android/support/transition/TransitionApi23.java
rename to transition/base/android/support/transition/ViewUtilsImpl.java
index 0df0ec5..188752d 100644
--- a/transition/api23/android/support/transition/TransitionApi23.java
+++ b/transition/base/android/support/transition/ViewUtilsImpl.java
@@ -16,17 +16,15 @@
 
 package android.support.transition;
 
-import android.annotation.TargetApi;
+import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
+import android.view.View;
 
-@RequiresApi(23)
-@TargetApi(23)
-class TransitionApi23 extends TransitionKitKat {
+@RequiresApi(14)
+interface ViewUtilsImpl {
 
-    @Override
-    public TransitionImpl removeTarget(int targetId) {
-        mTransition.removeTarget(targetId);
-        return this;
-    }
+    ViewOverlayImpl getOverlay(@NonNull View view);
+
+    WindowIdImpl getWindowId(@NonNull View view);
 
 }
diff --git a/transition/base/android/support/transition/VisibilityImpl.java b/transition/base/android/support/transition/VisibilityImpl.java
deleted file mode 100644
index 88c8c4b..0000000
--- a/transition/base/android/support/transition/VisibilityImpl.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.view.ViewGroup;
-
-/**
- * Interface for platform specific Visibility implementations on top of {@link TransitionImpl}.
- */
-interface VisibilityImpl {
-
-    boolean isVisible(TransitionValues values);
-
-    Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility);
-
-    Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility);
-
-}
diff --git a/transition/base/android/support/transition/VisibilityInterface.java b/transition/base/android/support/transition/VisibilityInterface.java
deleted file mode 100644
index 69fdf4e..0000000
--- a/transition/base/android/support/transition/VisibilityInterface.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.view.ViewGroup;
-
-/**
- * Used to reference android.support.transition.Visibility in a backward compatible manner.
- */
-interface VisibilityInterface extends TransitionInterface {
-
-    boolean isVisible(TransitionValues values);
-
-    Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility);
-
-    Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility);
-
-}
diff --git a/media-compat/tests/src/android/support/v4/media/session/TestActivity.java b/transition/base/android/support/transition/WindowIdImpl.java
similarity index 82%
rename from media-compat/tests/src/android/support/v4/media/session/TestActivity.java
rename to transition/base/android/support/transition/WindowIdImpl.java
index dd56467..2b5aa21 100644
--- a/media-compat/tests/src/android/support/v4/media/session/TestActivity.java
+++ b/transition/base/android/support/transition/WindowIdImpl.java
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package android.support.v4.media.session;
+package android.support.transition;
 
-import android.app.Activity;
+import android.support.annotation.RequiresApi;
 
-public class TestActivity extends Activity {
+@RequiresApi(14)
+interface WindowIdImpl {
 }
diff --git a/transition/build.gradle b/transition/build.gradle
index 2f47f83..036c010 100644
--- a/transition/build.gradle
+++ b/transition/build.gradle
@@ -1,4 +1,4 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 
 archivesBaseName = 'transition'
 
@@ -6,100 +6,38 @@
     compile project(':support-annotations')
     compile project(':support-v4')
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile 'org.mockito:mockito-core:1.9.5'
-    androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
-    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
-    testCompile 'junit:junit:4.12'
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
         minSdkVersion 14
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'base',
-                'ics',
-                'kitkat',
-                'api21',
-                'api23',
+                'api14',
+                'api18',
                 'src'
         ]
         main.res.srcDirs = [
                 'res',
                 'res-public'
         ]
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
+supportLibrary {
+    name 'Android Transition Support Library'
+    inceptionYear '2016'
+    description 'Android Transition Support Library'
 }
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Transition Support Library'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
-}
-
diff --git a/transition/ics/android/support/transition/AutoTransitionPort.java b/transition/ics/android/support/transition/AutoTransitionPort.java
deleted file mode 100644
index f3d4583..0000000
--- a/transition/ics/android/support/transition/AutoTransitionPort.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-/**
- * Utility class for creating a default transition that automatically fades,
- * moves, and resizes views during a scene change.
- *
- * <p>An AutoTransition can be described in a resource file by using the
- * tag <code>autoTransition</code>, along with the other standard
- * attributes of {@link android.R.styleable#Transition}.</p>
- */
-@RequiresApi(14)
-@TargetApi(14)
-class AutoTransitionPort extends TransitionSetPort {
-
-    /**
-     * Constructs an AutoTransition object, which is a TransitionSet which
-     * first fades out disappearing targets, then moves and resizes existing
-     * targets, and finally fades in appearing targets.
-     */
-    public AutoTransitionPort() {
-        setOrdering(ORDERING_SEQUENTIAL);
-        addTransition(new FadePort(FadePort.OUT)).
-                addTransition(new ChangeBoundsPort()).
-                addTransition(new FadePort(FadePort.IN));
-    }
-}
diff --git a/transition/ics/android/support/transition/ChangeBoundsPort.java b/transition/ics/android/support/transition/ChangeBoundsPort.java
deleted file mode 100644
index d9db2c7..0000000
--- a/transition/ics/android/support/transition/ChangeBoundsPort.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.annotation.TargetApi;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.support.annotation.RequiresApi;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.util.Map;
-
-/**
- * This transition captures the layout bounds of target views before and after
- * the scene change and animates those changes during the transition.
- *
- * <p>A ChangeBounds transition can be described in a resource file by using the
- * tag <code>changeBounds</code>, along with the other standard
- * attributes of {@link android.R.styleable#Transition}.</p>
- */
-@RequiresApi(14)
-@TargetApi(14)
-class ChangeBoundsPort extends TransitionPort {
-
-    private static final String PROPNAME_BOUNDS = "android:changeBounds:bounds";
-
-    private static final String PROPNAME_PARENT = "android:changeBounds:parent";
-
-    private static final String PROPNAME_WINDOW_X = "android:changeBounds:windowX";
-
-    private static final String PROPNAME_WINDOW_Y = "android:changeBounds:windowY";
-
-    private static final String[] sTransitionProperties = {
-            PROPNAME_BOUNDS,
-            PROPNAME_PARENT,
-            PROPNAME_WINDOW_X,
-            PROPNAME_WINDOW_Y
-    };
-
-    private static final String LOG_TAG = "ChangeBounds";
-
-    private static RectEvaluator sRectEvaluator = new RectEvaluator();
-
-    int[] tempLocation = new int[2];
-
-    boolean mResizeClip = false;
-
-    boolean mReparent = false;
-
-    @Override
-    public String[] getTransitionProperties() {
-        return sTransitionProperties;
-    }
-
-    public void setResizeClip(boolean resizeClip) {
-        mResizeClip = resizeClip;
-    }
-
-    /**
-     * Setting this flag tells ChangeBounds to track the before/after parent
-     * of every view using this transition. The flag is not enabled by
-     * default because it requires the parent instances to be the same
-     * in the two scenes or else all parents must use ids to allow
-     * the transition to determine which parents are the same.
-     *
-     * @param reparent true if the transition should track the parent
-     *                 container of target views and animate parent changes.
-     */
-    public void setReparent(boolean reparent) {
-        mReparent = reparent;
-    }
-
-    private void captureValues(TransitionValues values) {
-        View view = values.view;
-        values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(),
-                view.getRight(), view.getBottom()));
-        values.values.put(PROPNAME_PARENT, values.view.getParent());
-        values.view.getLocationInWindow(tempLocation);
-        values.values.put(PROPNAME_WINDOW_X, tempLocation[0]);
-        values.values.put(PROPNAME_WINDOW_Y, tempLocation[1]);
-    }
-
-    @Override
-    public void captureStartValues(TransitionValues transitionValues) {
-        captureValues(transitionValues);
-    }
-
-    @Override
-    public void captureEndValues(TransitionValues transitionValues) {
-        captureValues(transitionValues);
-    }
-
-    @Override
-    public Animator createAnimator(final ViewGroup sceneRoot, TransitionValues startValues,
-            TransitionValues endValues) {
-        if (startValues == null || endValues == null) {
-            return null;
-        }
-        Map<String, Object> startParentVals = startValues.values;
-        Map<String, Object> endParentVals = endValues.values;
-        ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
-        ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
-        if (startParent == null || endParent == null) {
-            return null;
-        }
-        final View view = endValues.view;
-        boolean parentsEqual = (startParent == endParent) ||
-                (startParent.getId() == endParent.getId());
-        // TODO: Might want reparenting to be separate/subclass transition, or at least
-        // triggered by a property on ChangeBounds. Otherwise, we're forcing the requirement that
-        // all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect
-        // of reparenting the views.
-        if (!mReparent || parentsEqual) {
-            Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
-            Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
-            int startLeft = startBounds.left;
-            int endLeft = endBounds.left;
-            int startTop = startBounds.top;
-            int endTop = endBounds.top;
-            int startRight = startBounds.right;
-            int endRight = endBounds.right;
-            int startBottom = startBounds.bottom;
-            int endBottom = endBounds.bottom;
-            int startWidth = startRight - startLeft;
-            int startHeight = startBottom - startTop;
-            int endWidth = endRight - endLeft;
-            int endHeight = endBottom - endTop;
-            int numChanges = 0;
-            if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) {
-                if (startLeft != endLeft) {
-                    ++numChanges;
-                }
-                if (startTop != endTop) {
-                    ++numChanges;
-                }
-                if (startRight != endRight) {
-                    ++numChanges;
-                }
-                if (startBottom != endBottom) {
-                    ++numChanges;
-                }
-            }
-            if (numChanges > 0) {
-                if (!mResizeClip) {
-                    PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges];
-                    int pvhIndex = 0;
-                    if (startLeft != endLeft) {
-                        view.setLeft(startLeft);
-                    }
-                    if (startTop != endTop) {
-                        view.setTop(startTop);
-                    }
-                    if (startRight != endRight) {
-                        view.setRight(startRight);
-                    }
-                    if (startBottom != endBottom) {
-                        view.setBottom(startBottom);
-                    }
-                    if (startLeft != endLeft) {
-                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("left", startLeft, endLeft);
-                    }
-                    if (startTop != endTop) {
-                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("top", startTop, endTop);
-                    }
-                    if (startRight != endRight) {
-                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("right",
-                                startRight, endRight);
-                    }
-                    if (startBottom != endBottom) {
-                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("bottom",
-                                startBottom, endBottom);
-                    }
-                    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh);
-                    if (view.getParent() instanceof ViewGroup) {
-                        final ViewGroup parent = (ViewGroup) view.getParent();
-//                        parent.suppressLayout(true);
-                        TransitionListener transitionListener = new TransitionListenerAdapter() {
-                            boolean mCanceled = false;
-
-                            @Override
-                            public void onTransitionCancel(TransitionPort transition) {
-//                                parent.suppressLayout(false);
-                                mCanceled = true;
-                            }
-
-                            @Override
-                            public void onTransitionEnd(TransitionPort transition) {
-                                if (!mCanceled) {
-//                                    parent.suppressLayout(false);
-                                }
-                            }
-
-                            @Override
-                            public void onTransitionPause(TransitionPort transition) {
-//                                parent.suppressLayout(false);
-                            }
-
-                            @Override
-                            public void onTransitionResume(TransitionPort transition) {
-//                                parent.suppressLayout(true);
-                            }
-                        };
-                        addListener(transitionListener);
-                    }
-                    return anim;
-                } else {
-                    if (startWidth != endWidth) {
-                        view.setRight(endLeft +
-                                Math.max(startWidth, endWidth));
-                    }
-                    if (startHeight != endHeight) {
-                        view.setBottom(endTop +
-                                Math.max(startHeight, endHeight));
-                    }
-                    // TODO: don't clobber TX/TY
-                    if (startLeft != endLeft) {
-                        view.setTranslationX(startLeft - endLeft);
-                    }
-                    if (startTop != endTop) {
-                        view.setTranslationY(startTop - endTop);
-                    }
-                    // Animate location with translationX/Y and size with clip bounds
-                    float transXDelta = endLeft - startLeft;
-                    float transYDelta = endTop - startTop;
-                    int widthDelta = endWidth - startWidth;
-                    int heightDelta = endHeight - startHeight;
-                    numChanges = 0;
-                    if (transXDelta != 0) {
-                        numChanges++;
-                    }
-                    if (transYDelta != 0) {
-                        numChanges++;
-                    }
-                    if (widthDelta != 0 || heightDelta != 0) {
-                        numChanges++;
-                    }
-                    PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges];
-                    int pvhIndex = 0;
-                    if (transXDelta != 0) {
-                        pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationX",
-                                view.getTranslationX(), 0);
-                    }
-                    if (transYDelta != 0) {
-                        pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationY",
-                                view.getTranslationY(), 0);
-                    }
-                    if (widthDelta != 0 || heightDelta != 0) {
-                        Rect tempStartBounds = new Rect(0, 0, startWidth, startHeight);
-                        Rect tempEndBounds = new Rect(0, 0, endWidth, endHeight);
-//                        pvh[pvhIndex++] = PropertyValuesHolder.ofObject("clipBounds",
-//                                sRectEvaluator, tempStartBounds, tempEndBounds);
-                    }
-                    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh);
-                    if (view.getParent() instanceof ViewGroup) {
-                        final ViewGroup parent = (ViewGroup) view.getParent();
-//                        parent.suppressLayout(true);
-                        TransitionListener transitionListener = new TransitionListenerAdapter() {
-                            boolean mCanceled = false;
-
-                            @Override
-                            public void onTransitionCancel(TransitionPort transition) {
-//                                parent.suppressLayout(false);
-                                mCanceled = true;
-                            }
-
-                            @Override
-                            public void onTransitionEnd(TransitionPort transition) {
-                                if (!mCanceled) {
-//                                    parent.suppressLayout(false);
-                                }
-                            }
-
-                            @Override
-                            public void onTransitionPause(TransitionPort transition) {
-//                                parent.suppressLayout(false);
-                            }
-
-                            @Override
-                            public void onTransitionResume(TransitionPort transition) {
-//                                parent.suppressLayout(true);
-                            }
-                        };
-                        addListener(transitionListener);
-                    }
-                    anim.addListener(new AnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationEnd(Animator animation) {
-//                            view.setClipBounds(null);
-                        }
-                    });
-                    return anim;
-                }
-            }
-        } else {
-            int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X);
-            int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y);
-            int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X);
-            int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y);
-            // TODO: also handle size changes: check bounds and animate size changes
-            if (startX != endX || startY != endY) {
-                sceneRoot.getLocationInWindow(tempLocation);
-                Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
-                        Bitmap.Config.ARGB_8888);
-                Canvas canvas = new Canvas(bitmap);
-                view.draw(canvas);
-                final BitmapDrawable drawable = new BitmapDrawable(bitmap);
-                view.setVisibility(View.INVISIBLE);
-                ViewOverlay.createFrom(sceneRoot).add(drawable);
-//                sceneRoot.getOverlay().add(drawable);
-                Rect startBounds1 = new Rect(startX - tempLocation[0], startY - tempLocation[1],
-                        startX - tempLocation[0] + view.getWidth(),
-                        startY - tempLocation[1] + view.getHeight());
-                Rect endBounds1 = new Rect(endX - tempLocation[0], endY - tempLocation[1],
-                        endX - tempLocation[0] + view.getWidth(),
-                        endY - tempLocation[1] + view.getHeight());
-                ObjectAnimator anim = ObjectAnimator.ofObject(drawable, "bounds",
-                        sRectEvaluator, startBounds1, endBounds1);
-                anim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        ViewOverlay.createFrom(sceneRoot).remove(drawable);
-//                        sceneRoot.getOverlay().remove(drawable);
-                        view.setVisibility(View.VISIBLE);
-                    }
-                });
-                return anim;
-            }
-        }
-        return null;
-    }
-}
diff --git a/transition/ics/android/support/transition/FadeIcs.java b/transition/ics/android/support/transition/FadeIcs.java
deleted file mode 100644
index ead8c00..0000000
--- a/transition/ics/android/support/transition/FadeIcs.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.view.ViewGroup;
-
-@RequiresApi(14)
-@TargetApi(14)
-class FadeIcs extends TransitionIcs implements VisibilityImpl {
-
-    public FadeIcs(TransitionInterface transition) {
-        init(transition, new FadePort());
-    }
-
-    public FadeIcs(TransitionInterface transition, int fadingMode) {
-        init(transition, new FadePort(fadingMode));
-    }
-
-    @Override
-    public boolean isVisible(TransitionValues values) {
-        return ((FadePort) mTransition).isVisible(values);
-    }
-
-    @Override
-    public Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility) {
-        return ((FadePort) mTransition).onAppear(sceneRoot, startValues, startVisibility,
-                endValues, endVisibility);
-    }
-
-    @Override
-    public Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues,
-            int startVisibility, TransitionValues endValues, int endVisibility) {
-        return ((FadePort) mTransition).onDisappear(sceneRoot, startValues, startVisibility,
-                startValues, startVisibility);
-    }
-
-}
diff --git a/transition/ics/android/support/transition/FadePort.java b/transition/ics/android/support/transition/FadePort.java
deleted file mode 100644
index 79673f5..0000000
--- a/transition/ics/android/support/transition/FadePort.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.support.v4.view.ViewCompat;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * This transition tracks changes to the visibility of target views in the
- * start and end scenes and fades views in or out when they become visible
- * or non-visible. Visibility is determined by both the
- * {@link View#setVisibility(int)} state of the view as well as whether it
- * is parented in the current view hierarchy.
- *
- * <p>The ability of this transition to fade out a particular view, and the
- * way that that fading operation takes place, is based on
- * the situation of the view in the view hierarchy. For example, if a view was
- * simply removed from its parent, then the view will be added into a {@link
- * android.view.ViewGroupOverlay} while fading. If a visible view is
- * changed to be {@link View#GONE} or {@link View#INVISIBLE}, then the
- * visibility will be changed to {@link View#VISIBLE} for the duration of
- * the animation. However, if a view is in a hierarchy which is also altering
- * its visibility, the situation can be more complicated. In general, if a
- * view that is no longer in the hierarchy in the end scene still has a
- * parent (so its parent hierarchy was removed, but it was not removed from
- * its parent), then it will be left alone to avoid side-effects from
- * improperly removing it from its parent. The only exception to this is if
- * the previous {@link android.transition.Scene} was
- * {@link ScenePort#getSceneForLayout(ViewGroup, int, android.content.Context)
- * created from a layout resource file}, then it is considered safe to un-parent
- * the starting scene view in order to fade it out.</p>
- *
- * <p>A Fade transition can be described in a resource file by using the
- * tag <code>fade</code>, along with the standard
- * attributes of {@link android.R.styleable#Fade} and
- * {@link android.R.styleable#Transition}.</p>
- */
-@RequiresApi(14)
-@TargetApi(14)
-class FadePort extends VisibilityPort {
-
-    /**
-     * Fading mode used in {@link #FadePort(int)} to make the transition
-     * operate on targets that are appearing. Maybe be combined with
-     * {@link #OUT} to fade both in and out.
-     */
-    public static final int IN = 0x1;
-
-    /**
-     * Fading mode used in {@link #FadePort(int)} to make the transition
-     * operate on targets that are disappearing. Maybe be combined with
-     * {@link #IN} to fade both in and out.
-     */
-    public static final int OUT = 0x2;
-
-    private static final String LOG_TAG = "Fade";
-
-    private static final String PROPNAME_SCREEN_X = "android:fade:screenX";
-
-    private static final String PROPNAME_SCREEN_Y = "android:fade:screenY";
-
-    private static boolean DBG = TransitionPort.DBG && false;
-
-    private int mFadingMode;
-
-    /**
-     * Constructs a Fade transition that will fade targets in and out.
-     */
-    public FadePort() {
-        this(IN | OUT);
-    }
-
-    /**
-     * Constructs a Fade transition that will fade targets in
-     * and/or out, according to the value of fadingMode.
-     *
-     * @param fadingMode The behavior of this transition, a combination of
-     *                   {@link #IN} and {@link #OUT}.
-     */
-    public FadePort(int fadingMode) {
-        mFadingMode = fadingMode;
-    }
-
-    /**
-     * Utility method to handle creating and running the Animator.
-     */
-    private Animator createAnimation(View view, float startAlpha, float endAlpha,
-            AnimatorListenerAdapter listener) {
-        if (startAlpha == endAlpha) {
-            // run listener if we're noop'ing the animation, to get the end-state results now
-            if (listener != null) {
-                listener.onAnimationEnd(null);
-            }
-            return null;
-        }
-        final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", startAlpha,
-                endAlpha);
-        if (DBG) {
-            Log.d(LOG_TAG, "Created animator " + anim);
-        }
-        if (listener != null) {
-            anim.addListener(listener);
-        }
-        return anim;
-    }
-
-    private void captureValues(TransitionValues transitionValues) {
-        int[] loc = new int[2];
-        transitionValues.view.getLocationOnScreen(loc);
-        transitionValues.values.put(PROPNAME_SCREEN_X, loc[0]);
-        transitionValues.values.put(PROPNAME_SCREEN_Y, loc[1]);
-    }
-
-    @Override
-    public void captureStartValues(TransitionValues transitionValues) {
-        super.captureStartValues(transitionValues);
-        captureValues(transitionValues);
-    }
-
-    @Override
-    public Animator onAppear(ViewGroup sceneRoot,
-            TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility) {
-        if ((mFadingMode & IN) != IN || endValues == null) {
-            return null;
-        }
-        final View endView = endValues.view;
-        if (DBG) {
-            View startView = (startValues != null) ? startValues.view : null;
-            Log.d(LOG_TAG, "Fade.onAppear: startView, startVis, endView, endVis = " +
-                    startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
-        }
-        endView.setAlpha(0);
-        TransitionListener transitionListener = new TransitionListenerAdapter() {
-            boolean mCanceled = false;
-
-            float mPausedAlpha;
-
-            @Override
-            public void onTransitionCancel(TransitionPort transition) {
-                endView.setAlpha(1);
-                mCanceled = true;
-            }
-
-            @Override
-            public void onTransitionEnd(TransitionPort transition) {
-                if (!mCanceled) {
-                    endView.setAlpha(1);
-                }
-            }
-
-            @Override
-            public void onTransitionPause(TransitionPort transition) {
-                mPausedAlpha = endView.getAlpha();
-                endView.setAlpha(1);
-            }
-
-            @Override
-            public void onTransitionResume(TransitionPort transition) {
-                endView.setAlpha(mPausedAlpha);
-            }
-        };
-        addListener(transitionListener);
-        return createAnimation(endView, 0, 1, null);
-    }
-
-    @Override
-    public Animator onDisappear(ViewGroup sceneRoot,
-            TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility) {
-        if ((mFadingMode & OUT) != OUT) {
-            return null;
-        }
-        View view = null;
-        View startView = (startValues != null) ? startValues.view : null;
-        View endView = (endValues != null) ? endValues.view : null;
-        if (DBG) {
-            Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
-                    startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
-        }
-        View overlayView = null;
-        View viewToKeep = null;
-        if (endView == null || endView.getParent() == null) {
-            if (endView != null) {
-                // endView was removed from its parent - add it to the overlay
-                view = overlayView = endView;
-            } else if (startView != null) {
-                // endView does not exist. Use startView only under certain
-                // conditions, because placing a view in an overlay necessitates
-                // it being removed from its current parent
-                if (startView.getParent() == null) {
-                    // no parent - safe to use
-                    view = overlayView = startView;
-                } else if (startView.getParent() instanceof View &&
-                        startView.getParent().getParent() == null) {
-                    View startParent = (View) startView.getParent();
-                    int id = startParent.getId();
-                    if (id != View.NO_ID && sceneRoot.findViewById(id) != null && mCanRemoveViews) {
-                        // no parent, but its parent is unparented  but the parent
-                        // hierarchy has been replaced by a new hierarchy with the same id
-                        // and it is safe to un-parent startView
-                        view = overlayView = startView;
-                    }
-                }
-            }
-        } else {
-            // visibility change
-            if (endVisibility == View.INVISIBLE) {
-                view = endView;
-                viewToKeep = view;
-            } else {
-                // Becoming GONE
-                if (startView == endView) {
-                    view = endView;
-                    viewToKeep = view;
-                } else {
-                    view = startView;
-                    overlayView = view;
-                }
-            }
-        }
-        final int finalVisibility = endVisibility;
-        // TODO: add automatic facility to Visibility superclass for keeping views around
-        if (overlayView != null) {
-            // TODO: Need to do this for general case of adding to overlay
-            int screenX = (Integer) startValues.values.get(PROPNAME_SCREEN_X);
-            int screenY = (Integer) startValues.values.get(PROPNAME_SCREEN_Y);
-            int[] loc = new int[2];
-            sceneRoot.getLocationOnScreen(loc);
-            ViewCompat.offsetLeftAndRight(overlayView, (screenX - loc[0]) - overlayView.getLeft());
-            ViewCompat.offsetTopAndBottom(overlayView, (screenY - loc[1]) - overlayView.getTop());
-            ViewGroupOverlay.createFrom(sceneRoot).add(overlayView);
-//            sceneRoot.getOverlay().add(overlayView);
-            // TODO: add automatic facility to Visibility superclass for keeping views around
-            final float startAlpha = 1;
-            float endAlpha = 0;
-            final View finalView = view;
-            final View finalOverlayView = overlayView;
-            final View finalViewToKeep = viewToKeep;
-            final ViewGroup finalSceneRoot = sceneRoot;
-            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    finalView.setAlpha(startAlpha);
-                    // TODO: restore view offset from overlay repositioning
-                    if (finalViewToKeep != null) {
-                        finalViewToKeep.setVisibility(finalVisibility);
-                    }
-                    if (finalOverlayView != null) {
-                        ViewGroupOverlay.createFrom(finalSceneRoot).remove(finalOverlayView);
-//                        finalSceneRoot.getOverlay().remove(finalOverlayView);
-                    }
-                }
-//
-//                @Override
-//                public void onAnimationPause(Animator animation) {
-//                    if (finalOverlayView != null) {
-//                        finalSceneRoot.getOverlay().remove(finalOverlayView);
-//                    }
-//                }
-//
-//                @Override
-//                public void onAnimationResume(Animator animation) {
-//                    if (finalOverlayView != null) {
-//                        finalSceneRoot.getOverlay().add(finalOverlayView);
-//                    }
-//                }
-            };
-            return createAnimation(view, startAlpha, endAlpha, endListener);
-        }
-        if (viewToKeep != null) {
-            // TODO: find a different way to do this, like just changing the view to be
-            // VISIBLE for the duration of the transition
-            viewToKeep.setVisibility((View.VISIBLE));
-            // TODO: add automatic facility to Visibility superclass for keeping views around
-            final float startAlpha = 1;
-            float endAlpha = 0;
-            final View finalView = view;
-            final View finalOverlayView = overlayView;
-            final View finalViewToKeep = viewToKeep;
-            final ViewGroup finalSceneRoot = sceneRoot;
-            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
-                boolean mCanceled = false;
-
-                float mPausedAlpha = -1;
-
-//                @Override
-//                public void onAnimationPause(Animator animation) {
-//                    if (finalViewToKeep != null && !mCanceled) {
-//                        finalViewToKeep.setVisibility(finalVisibility);
-//                    }
-//                    mPausedAlpha = finalView.getAlpha();
-//                    finalView.setAlpha(startAlpha);
-//                }
-//
-//                @Override
-//                public void onAnimationResume(Animator animation) {
-//                    if (finalViewToKeep != null && !mCanceled) {
-//                        finalViewToKeep.setVisibility(View.VISIBLE);
-//                    }
-//                    finalView.setAlpha(mPausedAlpha);
-//                }
-
-                @Override
-                public void onAnimationCancel(Animator animation) {
-                    mCanceled = true;
-                    if (mPausedAlpha >= 0) {
-                        finalView.setAlpha(mPausedAlpha);
-                    }
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    if (!mCanceled) {
-                        finalView.setAlpha(startAlpha);
-                    }
-                    // TODO: restore view offset from overlay repositioning
-                    if (finalViewToKeep != null && !mCanceled) {
-                        finalViewToKeep.setVisibility(finalVisibility);
-                    }
-                    if (finalOverlayView != null) {
-                        ViewGroupOverlay.createFrom(finalSceneRoot).add(finalOverlayView);
-//                        finalSceneRoot.getOverlay().remove(finalOverlayView);
-                    }
-                }
-            };
-            return createAnimation(view, startAlpha, endAlpha, endListener);
-        }
-        return null;
-    }
-
-}
\ No newline at end of file
diff --git a/transition/ics/android/support/transition/SceneIcs.java b/transition/ics/android/support/transition/SceneIcs.java
deleted file mode 100644
index 01e0508..0000000
--- a/transition/ics/android/support/transition/SceneIcs.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.view.View;
-import android.view.ViewGroup;
-
-@RequiresApi(14)
-@TargetApi(14)
-class SceneIcs extends SceneImpl {
-
-    /* package */ ScenePort mScene;
-
-    @Override
-    public void init(ViewGroup sceneRoot) {
-        mScene = new ScenePort(sceneRoot);
-    }
-
-    @Override
-    public void init(ViewGroup sceneRoot, View layout) {
-        mScene = new ScenePort(sceneRoot, layout);
-    }
-
-    @Override
-    public void enter() {
-        mScene.enter();
-    }
-
-    @Override
-    public void exit() {
-        mScene.exit();
-    }
-
-
-    @Override
-    public ViewGroup getSceneRoot() {
-        return mScene.getSceneRoot();
-    }
-
-    @Override
-    public void setEnterAction(Runnable action) {
-        mScene.setEnterAction(action);
-    }
-
-    @Override
-    public void setExitAction(Runnable action) {
-        mScene.setExitAction(action);
-    }
-
-}
diff --git a/transition/ics/android/support/transition/ScenePort.java b/transition/ics/android/support/transition/ScenePort.java
deleted file mode 100644
index 34b2d7b..0000000
--- a/transition/ics/android/support/transition/ScenePort.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.support.annotation.RequiresApi;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * A scene represents the collection of values that various properties in the
- * View hierarchy will have when the scene is applied. A Scene can be
- * configured to automatically run a Transition when it is applied, which will
- * animate the various property changes that take place during the
- * scene change.
- */
-@RequiresApi(14)
-@TargetApi(14)
-final class ScenePort {
-
-    Runnable mEnterAction, mExitAction;
-
-    private Context mContext;
-
-    private int mLayoutId = -1;
-
-    private ViewGroup mSceneRoot;
-
-    private View mLayout; // alternative to layoutId
-
-    /**
-     * Constructs a Scene with no information about how values will change
-     * when this scene is applied. This constructor might be used when
-     * a Scene is created with the intention of being dynamically configured,
-     * through setting {@link #setEnterAction(Runnable)} and possibly
-     * {@link #setExitAction(Runnable)}.
-     *
-     * @param sceneRoot The root of the hierarchy in which scene changes
-     *                  and transitions will take place.
-     */
-    public ScenePort(ViewGroup sceneRoot) {
-        mSceneRoot = sceneRoot;
-    }
-
-    /**
-     * Constructs a Scene which, when entered, will remove any
-     * children from the sceneRoot container and will inflate and add
-     * the hierarchy specified by the layoutId resource file.
-     *
-     * <p>This method is hidden because layoutId-based scenes should be
-     * created by the caching factory method {@link ScenePort#getCurrentScene(View)}.</p>
-     *
-     * @param sceneRoot The root of the hierarchy in which scene changes
-     *                  and transitions will take place.
-     * @param layoutId  The id of a resource file that defines the view
-     *                  hierarchy of this scene.
-     * @param context   The context used in the process of inflating
-     *                  the layout resource.
-     */
-    private ScenePort(ViewGroup sceneRoot, int layoutId, Context context) {
-        mContext = context;
-        mSceneRoot = sceneRoot;
-        mLayoutId = layoutId;
-    }
-
-    /**
-     * Constructs a Scene which, when entered, will remove any
-     * children from the sceneRoot container and add the layout
-     * object as a new child of that container.
-     *
-     * @param sceneRoot The root of the hierarchy in which scene changes
-     *                  and transitions will take place.
-     * @param layout    The view hierarchy of this scene, added as a child
-     *                  of sceneRoot when this scene is entered.
-     */
-    public ScenePort(ViewGroup sceneRoot, View layout) {
-        mSceneRoot = sceneRoot;
-        mLayout = layout;
-    }
-
-    /**
-     * Returns a Scene described by the resource file associated with the given
-     * <code>layoutId</code> parameter.
-     *
-     * @param sceneRoot The root of the hierarchy in which scene changes
-     *                  and transitions will take place.
-     * @param layoutId  The id of a standard layout resource file.
-     * @param context   The context used in the process of inflating
-     *                  the layout resource.
-     * @return The scene for the given root and layout id
-     */
-    public static ScenePort getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) {
-        // We don't cache ScenePort, but android.support.transition.Scene.
-        return new ScenePort(sceneRoot, layoutId, context);
-    }
-
-    /**
-     * Set the scene that the given view is in. The current scene is set only
-     * on the root view of a scene, not for every view in that hierarchy. This
-     * information is used by Scene to determine whether there is a previous
-     * scene which should be exited before the new scene is entered.
-     *
-     * @param view The view on which the current scene is being set
-     */
-    static void setCurrentScene(View view, ScenePort scene) {
-        view.setTag(R.id.transition_current_scene, scene);
-    }
-
-    /**
-     * Gets the current {@link ScenePort} set on the given view. A scene is set on a view
-     * only if that view is the scene root.
-     *
-     * @return The current Scene set on this view. A value of null indicates that
-     * no Scene is currently set.
-     */
-    static ScenePort getCurrentScene(View view) {
-        return (ScenePort) view.getTag(R.id.transition_current_scene);
-    }
-
-    /**
-     * Gets the root of the scene, which is the root of the view hierarchy
-     * affected by changes due to this scene, and which will be animated
-     * when this scene is entered.
-     *
-     * @return The root of the view hierarchy affected by this scene.
-     */
-    public ViewGroup getSceneRoot() {
-        return mSceneRoot;
-    }
-
-    /**
-     * Exits this scene, if it is the current scene
-     * on the scene's {@link #getSceneRoot() scene root}. The current scene is
-     * set when {@link #enter() entering} a scene.
-     * Exiting a scene runs the {@link #setExitAction(Runnable) exit action}
-     * if there is one.
-     */
-    public void exit() {
-        if (getCurrentScene(mSceneRoot) == this) {
-            if (mExitAction != null) {
-                mExitAction.run();
-            }
-        }
-    }
-
-    /**
-     * Enters this scene, which entails changing all values that
-     * are specified by this scene. These may be values associated
-     * with a layout view group or layout resource file which will
-     * now be added to the scene root, or it may be values changed by
-     * an {@link #setEnterAction(Runnable)} enter action}, or a
-     * combination of the these. No transition will be run when the
-     * scene is entered. To get transition behavior in scene changes,
-     * use one of the methods in {@link TransitionManagerPort} instead.
-     */
-    public void enter() {
-
-        // Apply layout change, if any
-        if (mLayoutId > 0 || mLayout != null) {
-            // empty out parent container before adding to it
-            getSceneRoot().removeAllViews();
-
-            if (mLayoutId > 0) {
-                LayoutInflater.from(mContext).inflate(mLayoutId, mSceneRoot);
-            } else {
-                mSceneRoot.addView(mLayout);
-            }
-        }
-
-        // Notify next scene that it is entering. Subclasses may override to configure scene.
-        if (mEnterAction != null) {
-            mEnterAction.run();
-        }
-
-        setCurrentScene(mSceneRoot, this);
-    }
-
-    /**
-     * Scenes that are not defined with layout resources or
-     * hierarchies, or which need to perform additional steps
-     * after those hierarchies are changed to, should set an enter
-     * action, and possibly an exit action as well. An enter action
-     * will cause Scene to call back into application code to do
-     * anything else the application needs after transitions have
-     * captured pre-change values and after any other scene changes
-     * have been applied, such as the layout (if any) being added to
-     * the view hierarchy. After this method is called, Transitions will
-     * be played.
-     *
-     * @param action The runnable whose {@link Runnable#run() run()} method will
-     *               be called when this scene is entered
-     * @see #setExitAction(Runnable)
-     * @see ScenePort#ScenePort(ViewGroup, int, Context)
-     * @see ScenePort#ScenePort(ViewGroup, ViewGroup)
-     */
-    public void setEnterAction(Runnable action) {
-        mEnterAction = action;
-    }
-
-    /**
-     * Scenes that are not defined with layout resources or
-     * hierarchies, or which need to perform additional steps
-     * after those hierarchies are changed to, should set an enter
-     * action, and possibly an exit action as well. An exit action
-     * will cause Scene to call back into application code to do
-     * anything the application needs to do after applicable transitions have
-     * captured pre-change values, but before any other scene changes
-     * have been applied, such as the new layout (if any) being added to
-     * the view hierarchy. After this method is called, the next scene
-     * will be entered, including a call to {@link #setEnterAction(Runnable)}
-     * if an enter action is set.
-     *
-     * @see #setEnterAction(Runnable)
-     * @see ScenePort#ScenePort(ViewGroup, int, Context)
-     * @see ScenePort#ScenePort(ViewGroup, ViewGroup)
-     */
-    public void setExitAction(Runnable action) {
-        mExitAction = action;
-    }
-
-
-    /**
-     * Returns whether this Scene was created by a layout resource file, determined
-     * by the layoutId passed into
-     * {@link #getSceneForLayout(ViewGroup, int, Context)}.
-     */
-    boolean isCreatedFromLayoutResource() {
-        return (mLayoutId > 0);
-    }
-}
\ No newline at end of file
diff --git a/transition/ics/android/support/transition/SceneStaticsIcs.java b/transition/ics/android/support/transition/SceneStaticsIcs.java
deleted file mode 100644
index bcc7451..0000000
--- a/transition/ics/android/support/transition/SceneStaticsIcs.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.support.annotation.RequiresApi;
-import android.view.ViewGroup;
-
-@RequiresApi(14)
-@TargetApi(14)
-class SceneStaticsIcs extends SceneStaticsImpl {
-
-    @Override
-    public SceneImpl getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) {
-        SceneIcs scene = new SceneIcs();
-        scene.mScene = ScenePort.getSceneForLayout(sceneRoot, layoutId, context);
-        return scene;
-    }
-
-}
diff --git a/transition/ics/android/support/transition/TransitionIcs.java b/transition/ics/android/support/transition/TransitionIcs.java
deleted file mode 100644
index 832b59e..0000000
--- a/transition/ics/android/support/transition/TransitionIcs.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.animation.TimeInterpolator;
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RequiresApi(14)
-@TargetApi(14)
-class TransitionIcs extends TransitionImpl {
-
-    /* package */ TransitionPort mTransition;
-
-    /* package */ TransitionInterface mExternalTransition;
-
-    private CompatListener mCompatListener;
-
-    @Override
-    public void init(TransitionInterface external, Object internal) {
-        mExternalTransition = external;
-        if (internal == null) {
-            mTransition = new TransitionWrapper(external);
-        } else {
-            mTransition = (TransitionPort) internal;
-        }
-    }
-
-    @Override
-    public TransitionImpl addListener(final TransitionInterfaceListener listener) {
-        if (mCompatListener == null) {
-            mCompatListener = new CompatListener();
-            mTransition.addListener(mCompatListener);
-        }
-        mCompatListener.addListener(listener);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl removeListener(TransitionInterfaceListener listener) {
-        if (mCompatListener == null) {
-            return this;
-        }
-        mCompatListener.removeListener(listener);
-        if (mCompatListener.isEmpty()) {
-            mTransition.removeListener(mCompatListener);
-            mCompatListener = null;
-        }
-        return this;
-    }
-
-    @Override
-    public TransitionImpl addTarget(View target) {
-        mTransition.addTarget(target);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl addTarget(int targetId) {
-        mTransition.addTarget(targetId);
-        return this;
-    }
-
-    @Override
-    public void captureEndValues(TransitionValues transitionValues) {
-        mTransition.captureEndValues(transitionValues);
-    }
-
-    @Override
-    public void captureStartValues(TransitionValues transitionValues) {
-        mTransition.captureStartValues(transitionValues);
-    }
-
-    @Override
-    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
-            TransitionValues endValues) {
-        return mTransition.createAnimator(sceneRoot, startValues, endValues);
-    }
-
-    @Override
-    public TransitionImpl excludeChildren(View target, boolean exclude) {
-        mTransition.excludeChildren(target, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeChildren(int targetId, boolean exclude) {
-        mTransition.excludeChildren(targetId, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeChildren(Class type, boolean exclude) {
-        mTransition.excludeChildren(type, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeTarget(View target, boolean exclude) {
-        mTransition.excludeTarget(target, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeTarget(int targetId, boolean exclude) {
-        mTransition.excludeTarget(targetId, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeTarget(Class type, boolean exclude) {
-        mTransition.excludeTarget(type, exclude);
-        return this;
-    }
-
-    @Override
-    public long getDuration() {
-        return mTransition.getDuration();
-    }
-
-    @Override
-    public TransitionImpl setDuration(long duration) {
-        mTransition.setDuration(duration);
-        return this;
-    }
-
-    @Override
-    public TimeInterpolator getInterpolator() {
-        return mTransition.getInterpolator();
-    }
-
-    @Override
-    public TransitionImpl setInterpolator(TimeInterpolator interpolator) {
-        mTransition.setInterpolator(interpolator);
-        return this;
-    }
-
-    @Override
-    public String getName() {
-        return mTransition.getName();
-    }
-
-    @Override
-    public long getStartDelay() {
-        return mTransition.getStartDelay();
-    }
-
-    @Override
-    public TransitionImpl setStartDelay(long startDelay) {
-        mTransition.setStartDelay(startDelay);
-        return this;
-    }
-
-    @Override
-    public List<Integer> getTargetIds() {
-        return mTransition.getTargetIds();
-    }
-
-    @Override
-    public List<View> getTargets() {
-        return mTransition.getTargets();
-    }
-
-    @Override
-    public String[] getTransitionProperties() {
-        return mTransition.getTransitionProperties();
-    }
-
-    @Override
-    public TransitionValues getTransitionValues(View view, boolean start) {
-        return mTransition.getTransitionValues(view, start);
-    }
-
-    @Override
-    public TransitionImpl removeTarget(View target) {
-        mTransition.removeTarget(target);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl removeTarget(int targetId) {
-        mTransition.removeTarget(targetId);
-        return this;
-    }
-
-    @Override
-    public String toString() {
-        return mTransition.toString();
-    }
-
-    private static class TransitionWrapper extends TransitionPort {
-
-        private TransitionInterface mTransition;
-
-        public TransitionWrapper(TransitionInterface transition) {
-            mTransition = transition;
-        }
-
-        @Override
-        public void captureStartValues(TransitionValues transitionValues) {
-            mTransition.captureStartValues(transitionValues);
-        }
-
-        @Override
-        public void captureEndValues(TransitionValues transitionValues) {
-            mTransition.captureEndValues(transitionValues);
-        }
-
-        @Override
-        public Animator createAnimator(ViewGroup sceneRoot,
-                TransitionValues startValues, TransitionValues endValues) {
-            return mTransition.createAnimator(sceneRoot, startValues, endValues);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private class CompatListener implements TransitionPort.TransitionListener {
-
-        private final ArrayList<TransitionInterfaceListener> mListeners = new ArrayList<>();
-
-        CompatListener() {
-        }
-
-        public void addListener(TransitionInterfaceListener listener) {
-            mListeners.add(listener);
-        }
-
-        public void removeListener(TransitionInterfaceListener listener) {
-            mListeners.remove(listener);
-        }
-
-        public boolean isEmpty() {
-            return mListeners.isEmpty();
-        }
-
-        @Override
-        public void onTransitionStart(TransitionPort transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionStart(mExternalTransition);
-            }
-        }
-
-        @Override
-        public void onTransitionEnd(TransitionPort transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionEnd(mExternalTransition);
-            }
-        }
-
-        @Override
-        public void onTransitionCancel(TransitionPort transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionCancel(mExternalTransition);
-            }
-        }
-
-        @Override
-        public void onTransitionPause(TransitionPort transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionPause(mExternalTransition);
-            }
-        }
-
-        @Override
-        public void onTransitionResume(TransitionPort transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionResume(mExternalTransition);
-            }
-        }
-    }
-
-}
diff --git a/transition/ics/android/support/transition/TransitionManagerIcs.java b/transition/ics/android/support/transition/TransitionManagerIcs.java
deleted file mode 100644
index d277ae7..0000000
--- a/transition/ics/android/support/transition/TransitionManagerIcs.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(14)
-@TargetApi(14)
-class TransitionManagerIcs extends TransitionManagerImpl {
-
-    private final TransitionManagerPort mTransitionManager = new TransitionManagerPort();
-
-    @Override
-    public void setTransition(SceneImpl scene, TransitionImpl transition) {
-        mTransitionManager.setTransition(((SceneIcs) scene).mScene,
-                transition == null ? null : ((TransitionIcs) transition).mTransition);
-    }
-
-    @Override
-    public void setTransition(SceneImpl fromScene, SceneImpl toScene, TransitionImpl transition) {
-        mTransitionManager.setTransition(((SceneIcs) fromScene).mScene, ((SceneIcs) toScene).mScene,
-                transition == null ? null : ((TransitionIcs) transition).mTransition);
-    }
-
-    @Override
-    public void transitionTo(SceneImpl scene) {
-        mTransitionManager.transitionTo(((SceneIcs) scene).mScene);
-    }
-
-}
diff --git a/transition/ics/android/support/transition/TransitionManagerPort.java b/transition/ics/android/support/transition/TransitionManagerPort.java
deleted file mode 100644
index 2ea7656..0000000
--- a/transition/ics/android/support/transition/TransitionManagerPort.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.support.annotation.RestrictTo;
-import android.support.v4.util.ArrayMap;
-import android.support.v4.view.ViewCompat;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-@RequiresApi(14)
-@TargetApi(14)
-class TransitionManagerPort {
-    // TODO: how to handle enter/exit?
-
-    private static final String[] EMPTY_STRINGS = new String[0];
-
-    private static String LOG_TAG = "TransitionManager";
-
-    private static TransitionPort sDefaultTransition = new AutoTransitionPort();
-
-    private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<TransitionPort>>>>
-            sRunningTransitions = new ThreadLocal<>();
-
-    static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<>();
-
-    ArrayMap<ScenePort, TransitionPort> mSceneTransitions = new ArrayMap<>();
-
-    ArrayMap<ScenePort, ArrayMap<ScenePort, TransitionPort>> mScenePairTransitions =
-            new ArrayMap<>();
-
-    ArrayMap<ScenePort, ArrayMap<String, TransitionPort>> mSceneNameTransitions = new ArrayMap<>();
-
-    ArrayMap<String, ArrayMap<ScenePort, TransitionPort>> mNameSceneTransitions = new ArrayMap<>();
-
-    /**
-     * Gets the current default transition. The initial value is an {@link
-     * AutoTransition} instance.
-     *
-     * @return The current default transition.
-     * @hide pending later changes
-     * @see #setDefaultTransition(TransitionPort)
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    public static TransitionPort getDefaultTransition() {
-        return sDefaultTransition;
-    }
-
-    /**
-     * Sets the transition to be used for any scene change for which no
-     * other transition is explicitly set. The initial value is
-     * an {@link AutoTransition} instance.
-     *
-     * @param transition The default transition to be used for scene changes.
-     * @hide pending later changes
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    public void setDefaultTransition(TransitionPort transition) {
-        sDefaultTransition = transition;
-    }
-
-    /**
-     * This is where all of the work of a transition/scene-change is
-     * orchestrated. This method captures the start values for the given
-     * transition, exits the current Scene, enters the new scene, captures
-     * the end values for the transition, and finally plays the
-     * resulting values-populated transition.
-     *
-     * @param scene      The scene being entered
-     * @param transition The transition to play for this scene change
-     */
-    private static void changeScene(ScenePort scene, TransitionPort transition) {
-
-        final ViewGroup sceneRoot = scene.getSceneRoot();
-
-        TransitionPort transitionClone = null;
-        if (transition != null) {
-            transitionClone = transition.clone();
-            transitionClone.setSceneRoot(sceneRoot);
-        }
-
-        ScenePort oldScene = ScenePort.getCurrentScene(sceneRoot);
-        if (oldScene != null && oldScene.isCreatedFromLayoutResource()) {
-            transitionClone.setCanRemoveViews(true);
-        }
-
-        sceneChangeSetup(sceneRoot, transitionClone);
-
-        scene.enter();
-
-        sceneChangeRunTransition(sceneRoot, transitionClone);
-    }
-
-    static ArrayMap<ViewGroup, ArrayList<TransitionPort>> getRunningTransitions() {
-        WeakReference<ArrayMap<ViewGroup, ArrayList<TransitionPort>>> runningTransitions =
-                sRunningTransitions.get();
-        if (runningTransitions == null || runningTransitions.get() == null) {
-            ArrayMap<ViewGroup, ArrayList<TransitionPort>> transitions = new ArrayMap<>();
-            runningTransitions = new WeakReference<>(transitions);
-            sRunningTransitions.set(runningTransitions);
-        }
-        return runningTransitions.get();
-    }
-
-    private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
-            final TransitionPort transition) {
-        if (transition != null && sceneRoot != null) {
-            MultiListener listener = new MultiListener(transition, sceneRoot);
-            sceneRoot.addOnAttachStateChangeListener(listener);
-            sceneRoot.getViewTreeObserver().addOnPreDrawListener(listener);
-        }
-    }
-
-    private static void sceneChangeSetup(ViewGroup sceneRoot, TransitionPort transition) {
-
-        // Capture current values
-        ArrayList<TransitionPort> runningTransitions = getRunningTransitions().get(sceneRoot);
-
-        if (runningTransitions != null && runningTransitions.size() > 0) {
-            for (TransitionPort runningTransition : runningTransitions) {
-                runningTransition.pause(sceneRoot);
-            }
-        }
-
-        if (transition != null) {
-            transition.captureValues(sceneRoot, true);
-        }
-
-        // Notify previous scene that it is being exited
-        ScenePort previousScene = ScenePort.getCurrentScene(sceneRoot);
-        if (previousScene != null) {
-            previousScene.exit();
-        }
-    }
-
-    public static void go(ScenePort scene) {
-        changeScene(scene, sDefaultTransition);
-    }
-
-    public static void go(ScenePort scene, TransitionPort transition) {
-        changeScene(scene, transition);
-    }
-
-    public static void beginDelayedTransition(final ViewGroup sceneRoot) {
-        beginDelayedTransition(sceneRoot, null);
-    }
-
-    public static void beginDelayedTransition(final ViewGroup sceneRoot,
-            TransitionPort transition) {
-        if (!sPendingTransitions.contains(sceneRoot) && ViewCompat.isLaidOut(sceneRoot)) {
-            if (TransitionPort.DBG) {
-                Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
-                        sceneRoot + ", " + transition);
-            }
-            sPendingTransitions.add(sceneRoot);
-            if (transition == null) {
-                transition = sDefaultTransition;
-            }
-            final TransitionPort transitionClone = transition.clone();
-            sceneChangeSetup(sceneRoot, transitionClone);
-            ScenePort.setCurrentScene(sceneRoot, null);
-            sceneChangeRunTransition(sceneRoot, transitionClone);
-        }
-    }
-
-    public void setTransition(ScenePort scene, TransitionPort transition) {
-        mSceneTransitions.put(scene, transition);
-    }
-
-    public void setTransition(ScenePort fromScene, ScenePort toScene, TransitionPort transition) {
-        ArrayMap<ScenePort, TransitionPort> sceneTransitionMap = mScenePairTransitions.get(toScene);
-        if (sceneTransitionMap == null) {
-            sceneTransitionMap = new ArrayMap<>();
-            mScenePairTransitions.put(toScene, sceneTransitionMap);
-        }
-        sceneTransitionMap.put(fromScene, transition);
-    }
-
-    /**
-     * Returns the Transition for the given scene being entered. The result
-     * depends not only on the given scene, but also the scene which the
-     * {@link ScenePort#getSceneRoot() sceneRoot} of the Scene is currently in.
-     *
-     * @param scene The scene being entered
-     * @return The Transition to be used for the given scene change. If no
-     * Transition was specified for this scene change, the default transition
-     * will be used instead.
-     */
-    private TransitionPort getTransition(ScenePort scene) {
-        TransitionPort transition;
-        ViewGroup sceneRoot = scene.getSceneRoot();
-        if (sceneRoot != null) {
-            // TODO: cached in Scene instead? long-term, cache in View itself
-            ScenePort currScene = ScenePort.getCurrentScene(sceneRoot);
-            if (currScene != null) {
-                ArrayMap<ScenePort, TransitionPort> sceneTransitionMap = mScenePairTransitions
-                        .get(scene);
-                if (sceneTransitionMap != null) {
-                    transition = sceneTransitionMap.get(currScene);
-                    if (transition != null) {
-                        return transition;
-                    }
-                }
-            }
-        }
-        transition = mSceneTransitions.get(scene);
-        return (transition != null) ? transition : sDefaultTransition;
-    }
-
-    /**
-     * Retrieve the transition from a named scene to a target defined scene if one has been
-     * associated with this TransitionManager.
-     *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
-     * @param fromName Named scene that this transition corresponds to
-     * @param toScene  Target scene that this transition will move to
-     * @return Transition corresponding to the given fromName and toScene or null
-     * if no association exists in this TransitionManager
-     * @see #setTransition(String, ScenePort, TransitionPort)
-     */
-    public TransitionPort getNamedTransition(String fromName, ScenePort toScene) {
-        ArrayMap<ScenePort, TransitionPort> m = mNameSceneTransitions.get(fromName);
-        if (m != null) {
-            return m.get(toScene);
-        }
-        return null;
-    }
-
-    ;
-
-    /**
-     * Retrieve the transition from a defined scene to a target named scene if one has been
-     * associated with this TransitionManager.
-     *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
-     * @param fromScene Scene that this transition starts from
-     * @param toName    Name of the target scene
-     * @return Transition corresponding to the given fromScene and toName or null
-     * if no association exists in this TransitionManager
-     */
-    public TransitionPort getNamedTransition(ScenePort fromScene, String toName) {
-        ArrayMap<String, TransitionPort> m = mSceneNameTransitions.get(fromScene);
-        if (m != null) {
-            return m.get(toName);
-        }
-        return null;
-    }
-
-    /**
-     * Retrieve the supported target named scenes when transitioning away from the given scene.
-     *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
-     * @param fromScene Scene to transition from
-     * @return An array of Strings naming each supported transition starting from
-     * <code>fromScene</code>. If no transitions to a named scene from the given
-     * scene are supported this function will return a String[] of length 0.
-     * @see #setTransition(ScenePort, String, TransitionPort)
-     */
-    public String[] getTargetSceneNames(ScenePort fromScene) {
-        final ArrayMap<String, TransitionPort> m = mSceneNameTransitions.get(fromScene);
-        if (m == null) {
-            return EMPTY_STRINGS;
-        }
-        final int count = m.size();
-        final String[] result = new String[count];
-        for (int i = 0; i < count; i++) {
-            result[i] = m.keyAt(i);
-        }
-        return result;
-    }
-
-    /**
-     * Set a transition from a specific scene to a named scene.
-     *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
-     * @param fromScene  Scene to transition from
-     * @param toName     Named scene to transition to
-     * @param transition Transition to use
-     * @see #getTargetSceneNames(ScenePort)
-     */
-    public void setTransition(ScenePort fromScene, String toName, TransitionPort transition) {
-        ArrayMap<String, TransitionPort> m = mSceneNameTransitions.get(fromScene);
-        if (m == null) {
-            m = new ArrayMap<>();
-            mSceneNameTransitions.put(fromScene, m);
-        }
-        m.put(toName, transition);
-    }
-
-    /**
-     * Set a transition from a named scene to a concrete scene.
-     *
-     * <p>A named scene is an indirect link for a transition. Fundamentally a named
-     * scene represents a potentially arbitrary intersection point of two otherwise independent
-     * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
-     * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
-     * In this way applications may define an API for more sophisticated transitions between
-     * caller and called activities very similar to the way that <code>Intent</code> extras
-     * define APIs for arguments and data propagation between activities.</p>
-     *
-     * @param fromName   Named scene to transition from
-     * @param toScene    Scene to transition to
-     * @param transition Transition to use
-     * @see #getNamedTransition(String, ScenePort)
-     */
-    public void setTransition(String fromName, ScenePort toScene, TransitionPort transition) {
-        ArrayMap<ScenePort, TransitionPort> m = mNameSceneTransitions.get(fromName);
-        if (m == null) {
-            m = new ArrayMap<>();
-            mNameSceneTransitions.put(fromName, m);
-        }
-        m.put(toScene, transition);
-    }
-
-    public void transitionTo(ScenePort scene) {
-        // Auto transition if there is no transition declared for the Scene, but there is
-        // a root or parent view
-        changeScene(scene, getTransition(scene));
-    }
-
-    /**
-     * This private utility class is used to listen for both OnPreDraw and
-     * OnAttachStateChange events. OnPreDraw events are the main ones we care
-     * about since that's what triggers the transition to take place.
-     * OnAttachStateChange events are also important in case the view is removed
-     * from the hierarchy before the OnPreDraw event takes place; it's used to
-     * clean up things since the OnPreDraw listener didn't get called in time.
-     */
-    private static class MultiListener implements ViewTreeObserver.OnPreDrawListener,
-            View.OnAttachStateChangeListener {
-
-        TransitionPort mTransition;
-
-        ViewGroup mSceneRoot;
-
-        MultiListener(TransitionPort transition, ViewGroup sceneRoot) {
-            mTransition = transition;
-            mSceneRoot = sceneRoot;
-        }
-
-        private void removeListeners() {
-            mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
-            mSceneRoot.removeOnAttachStateChangeListener(this);
-        }
-
-        @Override
-        public void onViewAttachedToWindow(View v) {
-        }
-
-        @Override
-        public void onViewDetachedFromWindow(View v) {
-            removeListeners();
-
-            sPendingTransitions.remove(mSceneRoot);
-            ArrayList<TransitionPort> runningTransitions = getRunningTransitions().get(mSceneRoot);
-            if (runningTransitions != null && runningTransitions.size() > 0) {
-                for (TransitionPort runningTransition : runningTransitions) {
-                    runningTransition.resume(mSceneRoot);
-                }
-            }
-            mTransition.clearValues(true);
-        }
-
-        @Override
-        public boolean onPreDraw() {
-            removeListeners();
-            sPendingTransitions.remove(mSceneRoot);
-            // Add to running list, handle end to remove it
-            final ArrayMap<ViewGroup, ArrayList<TransitionPort>> runningTransitions =
-                    getRunningTransitions();
-            ArrayList<TransitionPort> currentTransitions = runningTransitions.get(mSceneRoot);
-            ArrayList<TransitionPort> previousRunningTransitions = null;
-            if (currentTransitions == null) {
-                currentTransitions = new ArrayList<>();
-                runningTransitions.put(mSceneRoot, currentTransitions);
-            } else if (currentTransitions.size() > 0) {
-                previousRunningTransitions = new ArrayList<>(currentTransitions);
-            }
-            currentTransitions.add(mTransition);
-            mTransition.addListener(new TransitionPort.TransitionListenerAdapter() {
-                @Override
-                public void onTransitionEnd(TransitionPort transition) {
-                    ArrayList<TransitionPort> currentTransitions =
-                            runningTransitions.get(mSceneRoot);
-                    currentTransitions.remove(transition);
-                }
-            });
-            mTransition.captureValues(mSceneRoot, false);
-            if (previousRunningTransitions != null) {
-                for (TransitionPort runningTransition : previousRunningTransitions) {
-                    runningTransition.resume(mSceneRoot);
-                }
-            }
-            mTransition.playTransition(mSceneRoot);
-
-            return true;
-        }
-    }
-}
diff --git a/transition/ics/android/support/transition/TransitionManagerStaticsIcs.java b/transition/ics/android/support/transition/TransitionManagerStaticsIcs.java
deleted file mode 100644
index aab7083..0000000
--- a/transition/ics/android/support/transition/TransitionManagerStaticsIcs.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.view.ViewGroup;
-
-@RequiresApi(14)
-@TargetApi(14)
-class TransitionManagerStaticsIcs extends TransitionManagerStaticsImpl {
-
-    @Override
-    public void go(SceneImpl scene) {
-        TransitionManagerPort.go(((SceneIcs) scene).mScene);
-    }
-
-    @Override
-    public void go(SceneImpl scene, TransitionImpl transition) {
-        TransitionManagerPort.go(((SceneIcs) scene).mScene,
-                transition == null ? null : ((TransitionIcs) transition).mTransition);
-    }
-
-    @Override
-    public void beginDelayedTransition(ViewGroup sceneRoot) {
-        TransitionManagerPort.beginDelayedTransition(sceneRoot);
-    }
-
-    @Override
-    public void beginDelayedTransition(ViewGroup sceneRoot, TransitionImpl transition) {
-        TransitionManagerPort.beginDelayedTransition(sceneRoot,
-                transition == null ? null : ((TransitionIcs) transition).mTransition);
-    }
-
-}
diff --git a/transition/ics/android/support/transition/TransitionPort.java b/transition/ics/android/support/transition/TransitionPort.java
deleted file mode 100644
index 98b217d..0000000
--- a/transition/ics/android/support/transition/TransitionPort.java
+++ /dev/null
@@ -1,1295 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.TimeInterpolator;
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.support.annotation.RestrictTo;
-import android.support.v4.util.ArrayMap;
-import android.support.v4.util.LongSparseArray;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RequiresApi(14)
-@TargetApi(14)
-abstract class TransitionPort implements Cloneable {
-
-    static final boolean DBG = false;
-
-    private static final String LOG_TAG = "Transition";
-
-    // Per-animator information used for later canceling when future transitions overlap
-    private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators =
-            new ThreadLocal<>();
-
-    long mStartDelay = -1;
-
-    long mDuration = -1;
-
-    TimeInterpolator mInterpolator = null;
-
-    ArrayList<Integer> mTargetIds = new ArrayList<>();
-
-    ArrayList<View> mTargets = new ArrayList<>();
-
-    ArrayList<Integer> mTargetIdExcludes = null;
-
-    ArrayList<View> mTargetExcludes = null;
-
-    ArrayList<Class> mTargetTypeExcludes = null;
-
-    ArrayList<Integer> mTargetIdChildExcludes = null;
-
-    ArrayList<View> mTargetChildExcludes = null;
-
-    ArrayList<Class> mTargetTypeChildExcludes = null;
-
-    TransitionSetPort mParent = null;
-
-    // Scene Root is set at createAnimator() time in the cloned Transition
-    ViewGroup mSceneRoot = null;
-
-    // Whether removing views from their parent is possible. This is only for views
-    // in the start scene, which are no longer in the view hierarchy. This property
-    // is determined by whether the previous Scene was created from a layout
-    // resource, and thus the views from the exited scene are going away anyway
-    // and can be removed as necessary to achieve a particular effect, such as
-    // removing them from parents to add them to overlays.
-    boolean mCanRemoveViews = false;
-
-    // Number of per-target instances of this Transition currently running. This count is
-    // determined by calls to start() and end()
-    int mNumInstances = 0;
-
-    // Whether this transition is currently paused, due to a call to pause()
-    boolean mPaused = false;
-
-    // The set of listeners to be sent transition lifecycle events.
-    ArrayList<TransitionListener> mListeners = null;
-
-    // The set of animators collected from calls to createAnimator(),
-    // to be run in runAnimators()
-    ArrayList<Animator> mAnimators = new ArrayList<>();
-
-    private String mName = getClass().getName();
-
-    private android.support.transition.TransitionValuesMaps mStartValues
-            = new android.support.transition.TransitionValuesMaps();
-
-    private android.support.transition.TransitionValuesMaps mEndValues
-            = new android.support.transition.TransitionValuesMaps();
-
-    // Track all animators in use in case the transition gets canceled and needs to
-    // cancel running animators
-    ArrayList<Animator> mCurrentAnimators = new ArrayList<>();
-
-    // Whether this transition has ended. Used to avoid pause/resume on transitions
-    // that have completed
-    private boolean mEnded = false;
-
-    /**
-     * Constructs a Transition object with no target objects. A transition with
-     * no targets defaults to running on all target objects in the scene hierarchy
-     * (if the transition is not contained in a TransitionSet), or all target
-     * objects passed down from its parent (if it is in a TransitionSet).
-     */
-    public TransitionPort() {
-    }
-
-    private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
-        ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get();
-        if (runningAnimators == null) {
-            runningAnimators = new ArrayMap<>();
-            sRunningAnimators.set(runningAnimators);
-        }
-        return runningAnimators;
-    }
-
-    public long getDuration() {
-        return mDuration;
-    }
-
-    public TransitionPort setDuration(long duration) {
-        mDuration = duration;
-        return this;
-    }
-
-    public long getStartDelay() {
-        return mStartDelay;
-    }
-
-    public TransitionPort setStartDelay(long startDelay) {
-        mStartDelay = startDelay;
-        return this;
-    }
-
-    public TimeInterpolator getInterpolator() {
-        return mInterpolator;
-    }
-
-    public TransitionPort setInterpolator(TimeInterpolator interpolator) {
-        mInterpolator = interpolator;
-        return this;
-    }
-
-    public String[] getTransitionProperties() {
-        return null;
-    }
-
-
-    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
-            TransitionValues endValues) {
-        return null;
-    }
-
-    /**
-     * This method, essentially a wrapper around all calls to createAnimator for all
-     * possible target views, is called with the entire set of start/end
-     * values. The implementation in Transition iterates through these lists
-     * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}
-     * with each set of start/end values on this transition. The
-     * TransitionSet subclass overrides this method and delegates it to
-     * each of its children in succession.
-     *
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
-            TransitionValuesMaps endValues) {
-        if (DBG) {
-            Log.d(LOG_TAG, "createAnimators() for " + this);
-        }
-        ArrayMap<View, TransitionValues> endCopy =
-                new ArrayMap<>(endValues.viewValues);
-        SparseArray<TransitionValues> endIdCopy =
-                new SparseArray<>(endValues.idValues.size());
-        for (int i = 0; i < endValues.idValues.size(); ++i) {
-            int id = endValues.idValues.keyAt(i);
-            endIdCopy.put(id, endValues.idValues.valueAt(i));
-        }
-        LongSparseArray<TransitionValues> endItemIdCopy =
-                new LongSparseArray<>(endValues.itemIdValues.size());
-        for (int i = 0; i < endValues.itemIdValues.size(); ++i) {
-            long id = endValues.itemIdValues.keyAt(i);
-            endItemIdCopy.put(id, endValues.itemIdValues.valueAt(i));
-        }
-        // Walk through the start values, playing everything we find
-        // Remove from the end set as we go
-        ArrayList<TransitionValues> startValuesList = new ArrayList<>();
-        ArrayList<TransitionValues> endValuesList = new ArrayList<>();
-        for (View view : startValues.viewValues.keySet()) {
-            TransitionValues start;
-            TransitionValues end = null;
-            boolean isInListView = false;
-            if (view.getParent() instanceof ListView) {
-                isInListView = true;
-            }
-            if (!isInListView) {
-                int id = view.getId();
-                start = startValues.viewValues.get(view) != null ?
-                        startValues.viewValues.get(view) : startValues.idValues.get(id);
-                if (endValues.viewValues.get(view) != null) {
-                    end = endValues.viewValues.get(view);
-                    endCopy.remove(view);
-                } else if (id != View.NO_ID) {
-                    end = endValues.idValues.get(id);
-                    View removeView = null;
-                    for (View viewToRemove : endCopy.keySet()) {
-                        if (viewToRemove.getId() == id) {
-                            removeView = viewToRemove;
-                        }
-                    }
-                    if (removeView != null) {
-                        endCopy.remove(removeView);
-                    }
-                }
-                endIdCopy.remove(id);
-                if (isValidTarget(view, id)) {
-                    startValuesList.add(start);
-                    endValuesList.add(end);
-                }
-            } else {
-                ListView parent = (ListView) view.getParent();
-                if (parent.getAdapter().hasStableIds()) {
-                    int position = parent.getPositionForView(view);
-                    long itemId = parent.getItemIdAtPosition(position);
-                    start = startValues.itemIdValues.get(itemId);
-                    endItemIdCopy.remove(itemId);
-                    // TODO: deal with targetIDs for itemIDs for ListView items
-                    startValuesList.add(start);
-                    endValuesList.add(end);
-                }
-            }
-        }
-        int startItemIdCopySize = startValues.itemIdValues.size();
-        for (int i = 0; i < startItemIdCopySize; ++i) {
-            long id = startValues.itemIdValues.keyAt(i);
-            if (isValidTarget(null, id)) {
-                TransitionValues start = startValues.itemIdValues.get(id);
-                TransitionValues end = endValues.itemIdValues.get(id);
-                endItemIdCopy.remove(id);
-                startValuesList.add(start);
-                endValuesList.add(end);
-            }
-        }
-        // Now walk through the remains of the end set
-        for (View view : endCopy.keySet()) {
-            int id = view.getId();
-            if (isValidTarget(view, id)) {
-                TransitionValues start = startValues.viewValues.get(view) != null ?
-                        startValues.viewValues.get(view) : startValues.idValues.get(id);
-                TransitionValues end = endCopy.get(view);
-                endIdCopy.remove(id);
-                startValuesList.add(start);
-                endValuesList.add(end);
-            }
-        }
-        int endIdCopySize = endIdCopy.size();
-        for (int i = 0; i < endIdCopySize; ++i) {
-            int id = endIdCopy.keyAt(i);
-            if (isValidTarget(null, id)) {
-                TransitionValues start = startValues.idValues.get(id);
-                TransitionValues end = endIdCopy.get(id);
-                startValuesList.add(start);
-                endValuesList.add(end);
-            }
-        }
-        int endItemIdCopySize = endItemIdCopy.size();
-        for (int i = 0; i < endItemIdCopySize; ++i) {
-            long id = endItemIdCopy.keyAt(i);
-            // TODO: Deal with targetIDs and itemIDs
-            TransitionValues start = startValues.itemIdValues.get(id);
-            TransitionValues end = endItemIdCopy.get(id);
-            startValuesList.add(start);
-            endValuesList.add(end);
-        }
-        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-        for (int i = 0; i < startValuesList.size(); ++i) {
-            TransitionValues start = startValuesList.get(i);
-            TransitionValues end = endValuesList.get(i);
-            // Only bother trying to animate with values that differ between start/end
-            if (start != null || end != null) {
-                if (start == null || !start.equals(end)) {
-                    if (DBG) {
-                        View view = (end != null) ? end.view : start.view;
-                        Log.d(LOG_TAG, "  differing start/end values for view " +
-                                view);
-                        if (start == null || end == null) {
-                            Log.d(LOG_TAG, "    " + ((start == null) ?
-                                    "start null, end non-null" : "start non-null, end null"));
-                        } else {
-                            for (String key : start.values.keySet()) {
-                                Object startValue = start.values.get(key);
-                                Object endValue = end.values.get(key);
-                                if (startValue != endValue && !startValue.equals(endValue)) {
-                                    Log.d(LOG_TAG, "    " + key + ": start(" + startValue +
-                                            "), end(" + endValue + ")");
-                                }
-                            }
-                        }
-                    }
-                    // TODO: what to do about targetIds and itemIds?
-                    Animator animator = createAnimator(sceneRoot, start, end);
-                    if (animator != null) {
-                        // Save animation info for future cancellation purposes
-                        View view;
-                        TransitionValues infoValues = null;
-                        if (end != null) {
-                            view = end.view;
-                            String[] properties = getTransitionProperties();
-                            if (view != null && properties != null && properties.length > 0) {
-                                infoValues = new TransitionValues();
-                                infoValues.view = view;
-                                TransitionValues newValues = endValues.viewValues.get(view);
-                                if (newValues != null) {
-                                    for (int j = 0; j < properties.length; ++j) {
-                                        infoValues.values.put(properties[j],
-                                                newValues.values.get(properties[j]));
-                                    }
-                                }
-                                int numExistingAnims = runningAnimators.size();
-                                for (int j = 0; j < numExistingAnims; ++j) {
-                                    Animator anim = runningAnimators.keyAt(j);
-                                    AnimationInfo info = runningAnimators.get(anim);
-                                    if (info.values != null && info.view == view &&
-                                            ((info.name == null && getName() == null) ||
-                                                    info.name.equals(getName()))) {
-                                        if (info.values.equals(infoValues)) {
-                                            // Favor the old animator
-                                            animator = null;
-                                            break;
-                                        }
-                                    }
-                                }
-                            }
-                        } else {
-                            view = start.view;
-                        }
-                        if (animator != null) {
-                            AnimationInfo info = new AnimationInfo(view, getName(),
-                                    WindowIdPort.getWindowId(sceneRoot), infoValues);
-                            runningAnimators.put(animator, info);
-                            mAnimators.add(animator);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Internal utility method for checking whether a given view/id
-     * is valid for this transition, where "valid" means that either
-     * the Transition has no target/targetId list (the default, in which
-     * cause the transition should act on all views in the hiearchy), or
-     * the given view is in the target list or the view id is in the
-     * targetId list. If the target parameter is null, then the target list
-     * is not checked (this is in the case of ListView items, where the
-     * views are ignored and only the ids are used).
-     */
-    boolean isValidTarget(View target, long targetId) {
-        if (mTargetIdExcludes != null && mTargetIdExcludes.contains((int)targetId)) {
-            return false;
-        }
-        if (mTargetExcludes != null && mTargetExcludes.contains(target)) {
-            return false;
-        }
-        if (mTargetTypeExcludes != null && target != null) {
-            int numTypes = mTargetTypeExcludes.size();
-            for (int i = 0; i < numTypes; ++i) {
-                Class type = mTargetTypeExcludes.get(i);
-                if (type.isInstance(target)) {
-                    return false;
-                }
-            }
-        }
-        if (mTargetIds.size() == 0 && mTargets.size() == 0) {
-            return true;
-        }
-        if (mTargetIds.size() > 0) {
-            for (int i = 0; i < mTargetIds.size(); ++i) {
-                if (mTargetIds.get(i) == targetId) {
-                    return true;
-                }
-            }
-        }
-        if (target != null && mTargets.size() > 0) {
-            for (int i = 0; i < mTargets.size(); ++i) {
-                if (mTargets.get(i) == target) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * This is called internally once all animations have been set up by the
-     * transition hierarchy. \
-     *
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    protected void runAnimators() {
-        if (DBG) {
-            Log.d(LOG_TAG, "runAnimators() on " + this);
-        }
-        start();
-        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-        // Now start every Animator that was previously created for this transition
-        for (Animator anim : mAnimators) {
-            if (DBG) {
-                Log.d(LOG_TAG, "  anim: " + anim);
-            }
-            if (runningAnimators.containsKey(anim)) {
-                start();
-                runAnimator(anim, runningAnimators);
-            }
-        }
-        mAnimators.clear();
-        end();
-    }
-
-    private void runAnimator(Animator animator,
-            final ArrayMap<Animator, AnimationInfo> runningAnimators) {
-        if (animator != null) {
-            // TODO: could be a single listener instance for all of them since it uses the param
-            animator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    mCurrentAnimators.add(animation);
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    runningAnimators.remove(animation);
-                    mCurrentAnimators.remove(animation);
-                }
-            });
-            animate(animator);
-        }
-    }
-
-    public abstract void captureStartValues(TransitionValues transitionValues);
-
-    public abstract void captureEndValues(TransitionValues transitionValues);
-
-    public TransitionPort addTarget(int targetId) {
-        if (targetId > 0) {
-            mTargetIds.add(targetId);
-        }
-        return this;
-    }
-
-    public TransitionPort removeTarget(int targetId) {
-        if (targetId > 0) {
-            mTargetIds.remove((Integer) targetId);
-        }
-        return this;
-    }
-
-    public TransitionPort excludeTarget(int targetId, boolean exclude) {
-        mTargetIdExcludes = excludeId(mTargetIdExcludes, targetId, exclude);
-        return this;
-    }
-
-
-    public TransitionPort excludeChildren(int targetId, boolean exclude) {
-        mTargetIdChildExcludes = excludeId(mTargetIdChildExcludes, targetId, exclude);
-        return this;
-    }
-
-    /**
-     * Utility method to manage the boilerplate code that is the same whether we
-     * are excluding targets or their children.
-     */
-    private ArrayList<Integer> excludeId(ArrayList<Integer> list, int targetId, boolean exclude) {
-        if (targetId > 0) {
-            if (exclude) {
-                list = ArrayListManager.add(list, targetId);
-            } else {
-                list = ArrayListManager.remove(list, targetId);
-            }
-        }
-        return list;
-    }
-
-    public TransitionPort excludeTarget(View target, boolean exclude) {
-        mTargetExcludes = excludeView(mTargetExcludes, target, exclude);
-        return this;
-    }
-
-    public TransitionPort excludeChildren(View target, boolean exclude) {
-        mTargetChildExcludes = excludeView(mTargetChildExcludes, target, exclude);
-        return this;
-    }
-
-    /**
-     * Utility method to manage the boilerplate code that is the same whether we
-     * are excluding targets or their children.
-     */
-    private ArrayList<View> excludeView(ArrayList<View> list, View target, boolean exclude) {
-        if (target != null) {
-            if (exclude) {
-                list = ArrayListManager.add(list, target);
-            } else {
-                list = ArrayListManager.remove(list, target);
-            }
-        }
-        return list;
-    }
-
-    public TransitionPort excludeTarget(Class type, boolean exclude) {
-        mTargetTypeExcludes = excludeType(mTargetTypeExcludes, type, exclude);
-        return this;
-    }
-
-    public TransitionPort excludeChildren(Class type, boolean exclude) {
-        mTargetTypeChildExcludes = excludeType(mTargetTypeChildExcludes, type, exclude);
-        return this;
-    }
-
-    /**
-     * Utility method to manage the boilerplate code that is the same whether we
-     * are excluding targets or their children.
-     */
-    private ArrayList<Class> excludeType(ArrayList<Class> list, Class type, boolean exclude) {
-        if (type != null) {
-            if (exclude) {
-                list = ArrayListManager.add(list, type);
-            } else {
-                list = ArrayListManager.remove(list, type);
-            }
-        }
-        return list;
-    }
-
-    /**
-     * Sets the target view instances that this Transition is interested in
-     * animating. By default, there are no targets, and a Transition will
-     * listen for changes on every view in the hierarchy below the sceneRoot
-     * of the Scene being transitioned into. Setting targets constrains
-     * the Transition to only listen for, and act on, these views.
-     * All other views will be ignored.
-     *
-     * <p>The target list is like the {@link #addTarget(int) targetId}
-     * list except this list specifies the actual View instances, not the ids
-     * of the views. This is an important distinction when scene changes involve
-     * view hierarchies which have been inflated separately; different views may
-     * share the same id but not actually be the same instance. If the transition
-     * should treat those views as the same, then {@link #addTarget(int)} should be used
-     * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve
-     * changes all within the same view hierarchy, among views which do not
-     * necessarily have ids set on them, then the target list of views may be more
-     * convenient.</p>
-     *
-     * @param target A View on which the Transition will act, must be non-null.
-     * @return The Transition to which the target is added.
-     * Returning the same object makes it easier to chain calls during
-     * construction, such as
-     * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code>
-     * @see #addTarget(int)
-     */
-    public TransitionPort addTarget(View target) {
-        mTargets.add(target);
-        return this;
-    }
-
-    public TransitionPort removeTarget(View target) {
-        if (target != null) {
-            mTargets.remove(target);
-        }
-        return this;
-    }
-
-    public List<Integer> getTargetIds() {
-        return mTargetIds;
-    }
-
-    public List<View> getTargets() {
-        return mTargets;
-    }
-
-    /**
-     * Recursive method that captures values for the given view and the
-     * hierarchy underneath it.
-     *
-     * @param sceneRoot The root of the view hierarchy being captured
-     * @param start     true if this capture is happening before the scene change,
-     *                  false otherwise
-     */
-    void captureValues(ViewGroup sceneRoot, boolean start) {
-        clearValues(start);
-        if (mTargetIds.size() > 0 || mTargets.size() > 0) {
-            if (mTargetIds.size() > 0) {
-                for (int i = 0; i < mTargetIds.size(); ++i) {
-                    int id = mTargetIds.get(i);
-                    View view = sceneRoot.findViewById(id);
-                    if (view != null) {
-                        TransitionValues values = new TransitionValues();
-                        values.view = view;
-                        if (start) {
-                            captureStartValues(values);
-                        } else {
-                            captureEndValues(values);
-                        }
-                        if (start) {
-                            mStartValues.viewValues.put(view, values);
-                            if (id >= 0) {
-                                mStartValues.idValues.put(id, values);
-                            }
-                        } else {
-                            mEndValues.viewValues.put(view, values);
-                            if (id >= 0) {
-                                mEndValues.idValues.put(id, values);
-                            }
-                        }
-                    }
-                }
-            }
-            if (mTargets.size() > 0) {
-                for (int i = 0; i < mTargets.size(); ++i) {
-                    View view = mTargets.get(i);
-                    if (view != null) {
-                        TransitionValues values = new TransitionValues();
-                        values.view = view;
-                        if (start) {
-                            captureStartValues(values);
-                        } else {
-                            captureEndValues(values);
-                        }
-                        if (start) {
-                            mStartValues.viewValues.put(view, values);
-                        } else {
-                            mEndValues.viewValues.put(view, values);
-                        }
-                    }
-                }
-            }
-        } else {
-            captureHierarchy(sceneRoot, start);
-        }
-    }
-
-    /**
-     * Clear valuesMaps for specified start/end state
-     *
-     * @param start true if the start values should be cleared, false otherwise
-     */
-    void clearValues(boolean start) {
-        if (start) {
-            mStartValues.viewValues.clear();
-            mStartValues.idValues.clear();
-            mStartValues.itemIdValues.clear();
-        } else {
-            mEndValues.viewValues.clear();
-            mEndValues.idValues.clear();
-            mEndValues.itemIdValues.clear();
-        }
-    }
-
-    /**
-     * Recursive method which captures values for an entire view hierarchy,
-     * starting at some root view. Transitions without targetIDs will use this
-     * method to capture values for all possible views.
-     *
-     * @param view  The view for which to capture values. Children of this View
-     *              will also be captured, recursively down to the leaf nodes.
-     * @param start true if values are being captured in the start scene, false
-     *              otherwise.
-     */
-    private void captureHierarchy(View view, boolean start) {
-        if (view == null) {
-            return;
-        }
-        boolean isListViewItem = false;
-        if (view.getParent() instanceof ListView) {
-            isListViewItem = true;
-        }
-        if (isListViewItem && !((ListView) view.getParent()).getAdapter().hasStableIds()) {
-            // ignore listview children unless we can track them with stable IDs
-            return;
-        }
-        int id = View.NO_ID;
-        long itemId = View.NO_ID;
-        if (!isListViewItem) {
-            id = view.getId();
-        } else {
-            ListView listview = (ListView) view.getParent();
-            int position = listview.getPositionForView(view);
-            itemId = listview.getItemIdAtPosition(position);
-//            view.setHasTransientState(true);
-        }
-        if (mTargetIdExcludes != null && mTargetIdExcludes.contains(id)) {
-            return;
-        }
-        if (mTargetExcludes != null && mTargetExcludes.contains(view)) {
-            return;
-        }
-        if (mTargetTypeExcludes != null && view != null) {
-            int numTypes = mTargetTypeExcludes.size();
-            for (int i = 0; i < numTypes; ++i) {
-                if (mTargetTypeExcludes.get(i).isInstance(view)) {
-                    return;
-                }
-            }
-        }
-        TransitionValues values = new TransitionValues();
-        values.view = view;
-        if (start) {
-            captureStartValues(values);
-        } else {
-            captureEndValues(values);
-        }
-        if (start) {
-            if (!isListViewItem) {
-                mStartValues.viewValues.put(view, values);
-                if (id >= 0) {
-                    mStartValues.idValues.put((int) id, values);
-                }
-            } else {
-                mStartValues.itemIdValues.put(itemId, values);
-            }
-        } else {
-            if (!isListViewItem) {
-                mEndValues.viewValues.put(view, values);
-                if (id >= 0) {
-                    mEndValues.idValues.put((int) id, values);
-                }
-            } else {
-                mEndValues.itemIdValues.put(itemId, values);
-            }
-        }
-        if (view instanceof ViewGroup) {
-            // Don't traverse child hierarchy if there are any child-excludes on this view
-            if (mTargetIdChildExcludes != null && mTargetIdChildExcludes.contains(id)) {
-                return;
-            }
-            if (mTargetChildExcludes != null && mTargetChildExcludes.contains(view)) {
-                return;
-            }
-            if (mTargetTypeChildExcludes != null && view != null) {
-                int numTypes = mTargetTypeChildExcludes.size();
-                for (int i = 0; i < numTypes; ++i) {
-                    if (mTargetTypeChildExcludes.get(i).isInstance(view)) {
-                        return;
-                    }
-                }
-            }
-            ViewGroup parent = (ViewGroup) view;
-            for (int i = 0; i < parent.getChildCount(); ++i) {
-                captureHierarchy(parent.getChildAt(i), start);
-            }
-        }
-    }
-
-    public TransitionValues getTransitionValues(View view, boolean start) {
-        if (mParent != null) {
-            return mParent.getTransitionValues(view, start);
-        }
-        TransitionValuesMaps valuesMaps = start ? mStartValues : mEndValues;
-        TransitionValues values = valuesMaps.viewValues.get(view);
-        if (values == null) {
-            int id = view.getId();
-            if (id >= 0) {
-                values = valuesMaps.idValues.get(id);
-            }
-            if (values == null && view.getParent() instanceof ListView) {
-                ListView listview = (ListView) view.getParent();
-                int position = listview.getPositionForView(view);
-                long itemId = listview.getItemIdAtPosition(position);
-                values = valuesMaps.itemIdValues.get(itemId);
-            }
-            // TODO: Doesn't handle the case where a view was parented to a
-            // ListView (with an itemId), but no longer is
-        }
-        return values;
-    }
-
-    /**
-     * Pauses this transition, sending out calls to {@link
-     * TransitionListener#onTransitionPause(TransitionPort)} to all listeners
-     * and pausing all running animators started by this transition.
-     *
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    public void pause(View sceneRoot) {
-        if (!mEnded) {
-            ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-            int numOldAnims = runningAnimators.size();
-            WindowIdPort windowId = WindowIdPort.getWindowId(sceneRoot);
-            for (int i = numOldAnims - 1; i >= 0; i--) {
-                AnimationInfo info = runningAnimators.valueAt(i);
-                if (info.view != null && windowId.equals(info.windowId)) {
-                    Animator anim = runningAnimators.keyAt(i);
-                    anim.cancel(); // pause() is API Level 19
-                }
-            }
-            if (mListeners != null && mListeners.size() > 0) {
-                ArrayList<TransitionListener> tmpListeners =
-                        (ArrayList<TransitionListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onTransitionPause(this);
-                }
-            }
-            mPaused = true;
-        }
-    }
-
-    /**
-     * Resumes this transition, sending out calls to {@link
-     * TransitionListener#onTransitionPause(TransitionPort)} to all listeners
-     * and pausing all running animators started by this transition.
-     *
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    public void resume(View sceneRoot) {
-        if (mPaused) {
-            if (!mEnded) {
-                ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-                int numOldAnims = runningAnimators.size();
-                WindowIdPort windowId = WindowIdPort.getWindowId(sceneRoot);
-                for (int i = numOldAnims - 1; i >= 0; i--) {
-                    AnimationInfo info = runningAnimators.valueAt(i);
-                    if (info.view != null && windowId.equals(info.windowId)) {
-                        Animator anim = runningAnimators.keyAt(i);
-                        anim.end(); // resume() is API Level 19
-                    }
-                }
-                if (mListeners != null && mListeners.size() > 0) {
-                    ArrayList<TransitionListener> tmpListeners =
-                            (ArrayList<TransitionListener>) mListeners.clone();
-                    int numListeners = tmpListeners.size();
-                    for (int i = 0; i < numListeners; ++i) {
-                        tmpListeners.get(i).onTransitionResume(this);
-                    }
-                }
-            }
-            mPaused = false;
-        }
-    }
-
-    /**
-     * Called by TransitionManager to play the transition. This calls
-     * createAnimators() to set things up and create all of the animations and then
-     * runAnimations() to actually start the animations.
-     */
-    void playTransition(ViewGroup sceneRoot) {
-        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-        int numOldAnims = runningAnimators.size();
-        for (int i = numOldAnims - 1; i >= 0; i--) {
-            Animator anim = runningAnimators.keyAt(i);
-            if (anim != null) {
-                AnimationInfo oldInfo = runningAnimators.get(anim);
-                if (oldInfo != null && oldInfo.view != null &&
-                        oldInfo.view.getContext() == sceneRoot.getContext()) {
-                    boolean cancel = false;
-                    TransitionValues oldValues = oldInfo.values;
-                    View oldView = oldInfo.view;
-                    TransitionValues newValues = mEndValues.viewValues != null ?
-                            mEndValues.viewValues.get(oldView) : null;
-                    if (newValues == null) {
-                        newValues = mEndValues.idValues.get(oldView.getId());
-                    }
-                    if (oldValues != null) {
-                        // if oldValues null, then transition didn't care to stash values,
-                        // and won't get canceled
-                        if (newValues != null) {
-                            for (String key : oldValues.values.keySet()) {
-                                Object oldValue = oldValues.values.get(key);
-                                Object newValue = newValues.values.get(key);
-                                if (oldValue != null && newValue != null &&
-                                        !oldValue.equals(newValue)) {
-                                    cancel = true;
-                                    if (DBG) {
-                                        Log.d(LOG_TAG, "Transition.playTransition: " +
-                                                "oldValue != newValue for " + key +
-                                                ": old, new = " + oldValue + ", " + newValue);
-                                    }
-                                    break;
-                                }
-                            }
-                        }
-                    }
-                    if (cancel) {
-                        if (anim.isRunning() || anim.isStarted()) {
-                            if (DBG) {
-                                Log.d(LOG_TAG, "Canceling anim " + anim);
-                            }
-                            anim.cancel();
-                        } else {
-                            if (DBG) {
-                                Log.d(LOG_TAG, "removing anim from info list: " + anim);
-                            }
-                            runningAnimators.remove(anim);
-                        }
-                    }
-                }
-            }
-        }
-
-        createAnimators(sceneRoot, mStartValues, mEndValues);
-        runAnimators();
-    }
-
-    /**
-     * This is a utility method used by subclasses to handle standard parts of
-     * setting up and running an Animator: it sets the {@link #getDuration()
-     * duration} and the {@link #getStartDelay() startDelay}, starts the
-     * animation, and, when the animator ends, calls {@link #end()}.
-     *
-     * @param animator The Animator to be run during this transition.
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    protected void animate(Animator animator) {
-        // TODO: maybe pass auto-end as a boolean parameter?
-        if (animator == null) {
-            end();
-        } else {
-            if (getDuration() >= 0) {
-                animator.setDuration(getDuration());
-            }
-            if (getStartDelay() >= 0) {
-                animator.setStartDelay(getStartDelay());
-            }
-            if (getInterpolator() != null) {
-                animator.setInterpolator(getInterpolator());
-            }
-            animator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    end();
-                    animation.removeListener(this);
-                }
-            });
-            animator.start();
-        }
-    }
-
-    /**
-     * This method is called automatically by the transition and
-     * TransitionSet classes prior to a Transition subclass starting;
-     * subclasses should not need to call it directly.
-     *
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    protected void start() {
-        if (mNumInstances == 0) {
-            if (mListeners != null && mListeners.size() > 0) {
-                ArrayList<TransitionListener> tmpListeners =
-                        (ArrayList<TransitionListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onTransitionStart(this);
-                }
-            }
-            mEnded = false;
-        }
-        mNumInstances++;
-    }
-
-    /**
-     * This method is called automatically by the Transition and
-     * TransitionSet classes when a transition finishes, either because
-     * a transition did nothing (returned a null Animator from
-     * {@link TransitionPort#createAnimator(ViewGroup, TransitionValues,
-     * TransitionValues)}) or because the transition returned a valid
-     * Animator and end() was called in the onAnimationEnd()
-     * callback of the AnimatorListener.
-     *
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    protected void end() {
-        --mNumInstances;
-        if (mNumInstances == 0) {
-            if (mListeners != null && mListeners.size() > 0) {
-                ArrayList<TransitionListener> tmpListeners =
-                        (ArrayList<TransitionListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onTransitionEnd(this);
-                }
-            }
-            for (int i = 0; i < mStartValues.itemIdValues.size(); ++i) {
-                TransitionValues tv = mStartValues.itemIdValues.valueAt(i);
-                View v = tv.view;
-//                if (v.hasTransientState()) {
-//                    v.setHasTransientState(false);
-//                }
-            }
-            for (int i = 0; i < mEndValues.itemIdValues.size(); ++i) {
-                TransitionValues tv = mEndValues.itemIdValues.valueAt(i);
-                View v = tv.view;
-//                if (v.hasTransientState()) {
-//                    v.setHasTransientState(false);
-//                }
-            }
-            mEnded = true;
-        }
-    }
-
-    /**
-     * This method cancels a transition that is currently running.
-     *
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    protected void cancel() {
-        int numAnimators = mCurrentAnimators.size();
-        for (int i = numAnimators - 1; i >= 0; i--) {
-            Animator animator = mCurrentAnimators.get(i);
-            animator.cancel();
-        }
-        if (mListeners != null && mListeners.size() > 0) {
-            ArrayList<TransitionListener> tmpListeners =
-                    (ArrayList<TransitionListener>) mListeners.clone();
-            int numListeners = tmpListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                tmpListeners.get(i).onTransitionCancel(this);
-            }
-        }
-    }
-
-    /**
-     * 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.
-     * @return This transition object.
-     */
-    public TransitionPort addListener(TransitionListener listener) {
-        if (mListeners == null) {
-            mListeners = new ArrayList<>();
-        }
-        mListeners.add(listener);
-        return this;
-    }
-
-    public TransitionPort removeListener(TransitionListener listener) {
-        if (mListeners == null) {
-            return this;
-        }
-        mListeners.remove(listener);
-        if (mListeners.size() == 0) {
-            mListeners = null;
-        }
-        return this;
-    }
-
-    TransitionPort setSceneRoot(ViewGroup sceneRoot) {
-        mSceneRoot = sceneRoot;
-        return this;
-    }
-
-    void setCanRemoveViews(boolean canRemoveViews) {
-        mCanRemoveViews = canRemoveViews;
-    }
-
-    @Override
-    public String toString() {
-        return toString("");
-    }
-
-    @Override
-    public TransitionPort clone() {
-        TransitionPort clone = null;
-        try {
-            clone = (TransitionPort) super.clone();
-            clone.mAnimators = new ArrayList<Animator>();
-            clone.mStartValues = new TransitionValuesMaps();
-            clone.mEndValues = new TransitionValuesMaps();
-        } catch (CloneNotSupportedException e) {
-        }
-
-        return clone;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    String toString(String indent) {
-        String result = indent + getClass().getSimpleName() + "@" +
-                Integer.toHexString(hashCode()) + ": ";
-        if (mDuration != -1) {
-            result += "dur(" + mDuration + ") ";
-        }
-        if (mStartDelay != -1) {
-            result += "dly(" + mStartDelay + ") ";
-        }
-        if (mInterpolator != null) {
-            result += "interp(" + mInterpolator + ") ";
-        }
-        if (mTargetIds.size() > 0 || mTargets.size() > 0) {
-            result += "tgts(";
-            if (mTargetIds.size() > 0) {
-                for (int i = 0; i < mTargetIds.size(); ++i) {
-                    if (i > 0) {
-                        result += ", ";
-                    }
-                    result += mTargetIds.get(i);
-                }
-            }
-            if (mTargets.size() > 0) {
-                for (int i = 0; i < mTargets.size(); ++i) {
-                    if (i > 0) {
-                        result += ", ";
-                    }
-                    result += mTargets.get(i);
-                }
-            }
-            result += ")";
-        }
-        return result;
-    }
-
-    public interface TransitionListener {
-
-        /**
-         * Notification about the start of the transition.
-         *
-         * @param transition The started transition.
-         */
-        void onTransitionStart(TransitionPort transition);
-
-        /**
-         * Notification about the end of the transition. Canceled transitions
-         * will always notify listeners of both the cancellation and end
-         * events. That is, {@link #onTransitionEnd(TransitionPort)} is always called,
-         * regardless of whether the transition was canceled or played
-         * through to completion.
-         *
-         * @param transition The transition which reached its end.
-         */
-        void onTransitionEnd(TransitionPort transition);
-
-        /**
-         * Notification about the cancellation of the transition.
-         * Note that cancel may be called by a parent {@link TransitionSetPort} on
-         * a child transition which has not yet started. This allows the child
-         * transition to restore state on target objects which was set at
-         * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)
-         * createAnimator()} time.
-         *
-         * @param transition The transition which was canceled.
-         */
-        void onTransitionCancel(TransitionPort transition);
-
-        /**
-         * Notification when a transition is paused.
-         * Note that createAnimator() may be called by a parent {@link TransitionSetPort} on
-         * a child transition which has not yet started. This allows the child
-         * transition to restore state on target objects which was set at
-         * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)
-         * createAnimator()} time.
-         *
-         * @param transition The transition which was paused.
-         */
-        void onTransitionPause(TransitionPort transition);
-
-        /**
-         * Notification when a transition is resumed.
-         * Note that resume() may be called by a parent {@link TransitionSetPort} on
-         * a child transition which has not yet started. This allows the child
-         * transition to restore state which may have changed in an earlier call
-         * to {@link #onTransitionPause(TransitionPort)}.
-         *
-         * @param transition The transition which was resumed.
-         */
-        void onTransitionResume(TransitionPort transition);
-    }
-
-    /**
-     * Utility adapter class to avoid having to override all three methods
-     * whenever someone just wants to listen for a single event.
-     *
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    public static class TransitionListenerAdapter implements TransitionListener {
-
-        @Override
-        public void onTransitionStart(TransitionPort transition) {
-        }
-
-        @Override
-        public void onTransitionEnd(TransitionPort transition) {
-        }
-
-        @Override
-        public void onTransitionCancel(TransitionPort transition) {
-        }
-
-        @Override
-        public void onTransitionPause(TransitionPort transition) {
-        }
-
-        @Override
-        public void onTransitionResume(TransitionPort transition) {
-        }
-    }
-
-    /**
-     * Holds information about each animator used when a new transition starts
-     * while other transitions are still running to determine whether a running
-     * animation should be canceled or a new animation noop'd. The structure holds
-     * information about the state that an animation is going to, to be compared to
-     * end state of a new animation.
-     */
-    private static class AnimationInfo {
-
-        View view;
-
-        String name;
-
-        TransitionValues values;
-
-        WindowIdPort windowId;
-
-        AnimationInfo(View view, String name, WindowIdPort windowId, TransitionValues values) {
-            this.view = view;
-            this.name = name;
-            this.values = values;
-            this.windowId = windowId;
-        }
-    }
-
-    /**
-     * Utility class for managing typed ArrayLists efficiently. In particular, this
-     * can be useful for lists that we don't expect to be used often (eg, the exclude
-     * lists), so we'd like to keep them nulled out by default. This causes the code to
-     * become tedious, with constant null checks, code to allocate when necessary,
-     * and code to null out the reference when the list is empty. This class encapsulates
-     * all of that functionality into simple add()/remove() methods which perform the
-     * necessary checks, allocation/null-out as appropriate, and return the
-     * resulting list.
-     */
-    private static class ArrayListManager {
-
-        /**
-         * Add the specified item to the list, returning the resulting list.
-         * The returned list can either the be same list passed in or, if that
-         * list was null, the new list that was created.
-         *
-         * Note that the list holds unique items; if the item already exists in the
-         * list, the list is not modified.
-         */
-        static <T> ArrayList<T> add(ArrayList<T> list, T item) {
-            if (list == null) {
-                list = new ArrayList<T>();
-            }
-            if (!list.contains(item)) {
-                list.add(item);
-            }
-            return list;
-        }
-
-        /**
-         * Remove the specified item from the list, returning the resulting list.
-         * The returned list can either the be same list passed in or, if that
-         * list becomes empty as a result of the remove(), the new list was created.
-         */
-        static <T> ArrayList<T> remove(ArrayList<T> list, T item) {
-            if (list != null) {
-                list.remove(item);
-                if (list.isEmpty()) {
-                    list = null;
-                }
-            }
-            return list;
-        }
-    }
-
-}
diff --git a/transition/ics/android/support/transition/TransitionSetIcs.java b/transition/ics/android/support/transition/TransitionSetIcs.java
deleted file mode 100644
index b3fcd8f..0000000
--- a/transition/ics/android/support/transition/TransitionSetIcs.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(14)
-@TargetApi(14)
-class TransitionSetIcs extends TransitionIcs implements TransitionSetImpl {
-
-    private TransitionSetPort mTransitionSet;
-
-    public TransitionSetIcs(TransitionInterface transition) {
-        mTransitionSet = new TransitionSetPort();
-        init(transition, mTransitionSet);
-    }
-
-    @Override
-    public int getOrdering() {
-        return mTransitionSet.getOrdering();
-    }
-
-    @Override
-    public TransitionSetIcs setOrdering(int ordering) {
-        mTransitionSet.setOrdering(ordering);
-        return this;
-    }
-
-    @Override
-    public TransitionSetIcs addTransition(TransitionImpl transition) {
-        mTransitionSet.addTransition(((TransitionIcs) transition).mTransition);
-        return this;
-    }
-
-    @Override
-    public TransitionSetIcs removeTransition(TransitionImpl transition) {
-        mTransitionSet.removeTransition(((TransitionIcs) transition).mTransition);
-        return this;
-    }
-
-}
diff --git a/transition/ics/android/support/transition/TransitionSetPort.java b/transition/ics/android/support/transition/TransitionSetPort.java
deleted file mode 100644
index d88e046..0000000
--- a/transition/ics/android/support/transition/TransitionSetPort.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.animation.TimeInterpolator;
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.support.annotation.RestrictTo;
-import android.util.AndroidRuntimeException;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.util.ArrayList;
-
-@RequiresApi(14)
-@TargetApi(14)
-class TransitionSetPort extends TransitionPort {
-
-    /**
-     * A flag used to indicate that the child transitions of this set
-     * should all start at the same time.
-     */
-    public static final int ORDERING_TOGETHER = 0;
-
-    /**
-     * A flag used to indicate that the child transitions of this set should
-     * play in sequence; when one child transition ends, the next child
-     * transition begins. Note that a transition does not end until all
-     * instances of it (which are playing on all applicable targets of the
-     * transition) end.
-     */
-    public static final int ORDERING_SEQUENTIAL = 1;
-
-    ArrayList<TransitionPort> mTransitions = new ArrayList<TransitionPort>();
-
-    int mCurrentListeners;
-
-    boolean mStarted = false;
-
-    private boolean mPlayTogether = true;
-
-    public TransitionSetPort() {
-    }
-
-    public int getOrdering() {
-        return mPlayTogether ? ORDERING_TOGETHER : ORDERING_SEQUENTIAL;
-    }
-
-    public TransitionSetPort setOrdering(int ordering) {
-        switch (ordering) {
-            case ORDERING_SEQUENTIAL:
-                mPlayTogether = false;
-                break;
-            case ORDERING_TOGETHER:
-                mPlayTogether = true;
-                break;
-            default:
-                throw new AndroidRuntimeException("Invalid parameter for TransitionSet " +
-                        "ordering: " + ordering);
-        }
-        return this;
-    }
-
-    public TransitionSetPort addTransition(TransitionPort transition) {
-        if (transition != null) {
-            mTransitions.add(transition);
-            transition.mParent = this;
-            if (mDuration >= 0) {
-                transition.setDuration(mDuration);
-            }
-        }
-        return this;
-    }
-
-    /**
-     * Setting a non-negative duration on a TransitionSet causes all of the child
-     * transitions (current and future) to inherit this duration.
-     *
-     * @param duration The length of the animation, in milliseconds.
-     * @return This transitionSet object.
-     */
-    @Override
-    public TransitionSetPort setDuration(long duration) {
-        super.setDuration(duration);
-        if (mDuration >= 0) {
-            int numTransitions = mTransitions.size();
-            for (int i = 0; i < numTransitions; ++i) {
-                mTransitions.get(i).setDuration(duration);
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public TransitionSetPort setStartDelay(long startDelay) {
-        return (TransitionSetPort) super.setStartDelay(startDelay);
-    }
-
-    @Override
-    public TransitionSetPort setInterpolator(TimeInterpolator interpolator) {
-        return (TransitionSetPort) super.setInterpolator(interpolator);
-    }
-
-    @Override
-    public TransitionSetPort addTarget(View target) {
-        return (TransitionSetPort) super.addTarget(target);
-    }
-
-    @Override
-    public TransitionSetPort addTarget(int targetId) {
-        return (TransitionSetPort) super.addTarget(targetId);
-    }
-
-    @Override
-    public TransitionSetPort addListener(TransitionListener listener) {
-        return (TransitionSetPort) super.addListener(listener);
-    }
-
-    @Override
-    public TransitionSetPort removeTarget(int targetId) {
-        return (TransitionSetPort) super.removeTarget(targetId);
-    }
-
-    @Override
-    public TransitionSetPort removeTarget(View target) {
-        return (TransitionSetPort) super.removeTarget(target);
-    }
-
-    @Override
-    public TransitionSetPort removeListener(TransitionListener listener) {
-        return (TransitionSetPort) super.removeListener(listener);
-    }
-
-    public TransitionSetPort removeTransition(TransitionPort transition) {
-        mTransitions.remove(transition);
-        transition.mParent = null;
-        return this;
-    }
-
-    /**
-     * Sets up listeners for each of the child transitions. This is used to
-     * determine when this transition set is finished (all child transitions
-     * must finish first).
-     */
-    private void setupStartEndListeners() {
-        TransitionSetListener listener = new TransitionSetListener(this);
-        for (TransitionPort childTransition : mTransitions) {
-            childTransition.addListener(listener);
-        }
-        mCurrentListeners = mTransitions.size();
-    }
-
-    /**
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    @Override
-    protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
-            TransitionValuesMaps endValues) {
-        for (TransitionPort childTransition : mTransitions) {
-            childTransition.createAnimators(sceneRoot, startValues, endValues);
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @RestrictTo(LIBRARY_GROUP)
-    @Override
-    protected void runAnimators() {
-        if (mTransitions.isEmpty()) {
-            start();
-            end();
-            return;
-        }
-        setupStartEndListeners();
-        if (!mPlayTogether) {
-            // Setup sequence with listeners
-            // TODO: Need to add listeners in such a way that we can remove them later if canceled
-            for (int i = 1; i < mTransitions.size(); ++i) {
-                TransitionPort previousTransition = mTransitions.get(i - 1);
-                final TransitionPort nextTransition = mTransitions.get(i);
-                previousTransition.addListener(new TransitionListenerAdapter() {
-                    @Override
-                    public void onTransitionEnd(TransitionPort transition) {
-                        nextTransition.runAnimators();
-                        transition.removeListener(this);
-                    }
-                });
-            }
-            TransitionPort firstTransition = mTransitions.get(0);
-            if (firstTransition != null) {
-                firstTransition.runAnimators();
-            }
-        } else {
-            for (TransitionPort childTransition : mTransitions) {
-                childTransition.runAnimators();
-            }
-        }
-    }
-
-    @Override
-    public void captureStartValues(TransitionValues transitionValues) {
-        int targetId = transitionValues.view.getId();
-        if (isValidTarget(transitionValues.view, targetId)) {
-            for (TransitionPort childTransition : mTransitions) {
-                if (childTransition.isValidTarget(transitionValues.view, targetId)) {
-                    childTransition.captureStartValues(transitionValues);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void captureEndValues(TransitionValues transitionValues) {
-        int targetId = transitionValues.view.getId();
-        if (isValidTarget(transitionValues.view, targetId)) {
-            for (TransitionPort childTransition : mTransitions) {
-                if (childTransition.isValidTarget(transitionValues.view, targetId)) {
-                    childTransition.captureEndValues(transitionValues);
-                }
-            }
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(LIBRARY_GROUP)
-    @Override
-    public void pause(View sceneRoot) {
-        super.pause(sceneRoot);
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).pause(sceneRoot);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(LIBRARY_GROUP)
-    @Override
-    public void resume(View sceneRoot) {
-        super.resume(sceneRoot);
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).resume(sceneRoot);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(LIBRARY_GROUP)
-    @Override
-    protected void cancel() {
-        super.cancel();
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).cancel();
-        }
-    }
-
-    @Override
-    TransitionSetPort setSceneRoot(ViewGroup sceneRoot) {
-        super.setSceneRoot(sceneRoot);
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).setSceneRoot(sceneRoot);
-        }
-        return (TransitionSetPort) this;
-    }
-
-    @Override
-    void setCanRemoveViews(boolean canRemoveViews) {
-        super.setCanRemoveViews(canRemoveViews);
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).setCanRemoveViews(canRemoveViews);
-        }
-    }
-
-    @Override
-    String toString(String indent) {
-        String result = super.toString(indent);
-        for (int i = 0; i < mTransitions.size(); ++i) {
-            result += "\n" + mTransitions.get(i).toString(indent + "  ");
-        }
-        return result;
-    }
-
-    @Override
-    public TransitionSetPort clone() {
-        TransitionSetPort clone = (TransitionSetPort) super.clone();
-        clone.mTransitions = new ArrayList<TransitionPort>();
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            clone.addTransition((TransitionPort) mTransitions.get(i).clone());
-        }
-        return clone;
-    }
-
-    /**
-     * This listener is used to detect when all child transitions are done, at
-     * which point this transition set is also done.
-     */
-    static class TransitionSetListener extends TransitionListenerAdapter {
-
-        TransitionSetPort mTransitionSet;
-
-        TransitionSetListener(TransitionSetPort transitionSet) {
-            mTransitionSet = transitionSet;
-        }
-
-        @Override
-        public void onTransitionStart(TransitionPort transition) {
-            if (!mTransitionSet.mStarted) {
-                mTransitionSet.start();
-                mTransitionSet.mStarted = true;
-            }
-        }
-
-        @Override
-        public void onTransitionEnd(TransitionPort transition) {
-            --mTransitionSet.mCurrentListeners;
-            if (mTransitionSet.mCurrentListeners == 0) {
-                // All child trans
-                mTransitionSet.mStarted = false;
-                mTransitionSet.end();
-            }
-            transition.removeListener(this);
-        }
-    }
-
-}
diff --git a/transition/ics/android/support/transition/VisibilityIcs.java b/transition/ics/android/support/transition/VisibilityIcs.java
deleted file mode 100644
index f2290cf..0000000
--- a/transition/ics/android/support/transition/VisibilityIcs.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.view.ViewGroup;
-
-@RequiresApi(14)
-@TargetApi(14)
-class VisibilityIcs extends TransitionIcs implements VisibilityImpl {
-
-    @Override
-    public void init(TransitionInterface external, Object internal) {
-        mExternalTransition = external;
-        if (internal == null) {
-            mTransition = new VisibilityWrapper((VisibilityInterface) external);
-        } else {
-            mTransition = (VisibilityPort) internal;
-        }
-    }
-
-    @Override
-    public boolean isVisible(TransitionValues values) {
-        return ((VisibilityPort) mTransition).isVisible(values);
-    }
-
-    @Override
-    public Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility) {
-        return ((VisibilityPort) mTransition).onAppear(sceneRoot, startValues, startVisibility,
-                endValues, endVisibility);
-    }
-
-    @Override
-    public Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues,
-            int startVisibility, TransitionValues endValues, int endVisibility) {
-        return ((VisibilityPort) mTransition).onDisappear(sceneRoot, startValues, startVisibility,
-                endValues, endVisibility);
-    }
-
-    private static class VisibilityWrapper extends VisibilityPort {
-
-        private VisibilityInterface mVisibility;
-
-        VisibilityWrapper(VisibilityInterface visibility) {
-            mVisibility = visibility;
-        }
-
-        @Override
-        public void captureStartValues(TransitionValues transitionValues) {
-            mVisibility.captureStartValues(transitionValues);
-        }
-
-        @Override
-        public void captureEndValues(TransitionValues transitionValues) {
-            mVisibility.captureEndValues(transitionValues);
-        }
-
-        @Override
-        public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
-                TransitionValues endValues) {
-            return mVisibility.createAnimator(sceneRoot, startValues, endValues);
-        }
-
-        @Override
-        public boolean isVisible(TransitionValues values) {
-            return mVisibility.isVisible(values);
-        }
-
-        @Override
-        public Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues,
-                int startVisibility,
-                TransitionValues endValues, int endVisibility) {
-            return mVisibility.onAppear(sceneRoot, startValues, startVisibility,
-                    endValues, endVisibility);
-        }
-
-        @Override
-        public Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues,
-                int startVisibility, TransitionValues endValues, int endVisibility) {
-            return mVisibility.onDisappear(sceneRoot, startValues, startVisibility,
-                    endValues, endVisibility);
-        }
-
-    }
-
-}
diff --git a/transition/ics/android/support/transition/VisibilityPort.java b/transition/ics/android/support/transition/VisibilityPort.java
deleted file mode 100644
index e740b19..0000000
--- a/transition/ics/android/support/transition/VisibilityPort.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * This transition tracks changes to the visibility of target views in the
- * start and end scenes. Visibility is determined not just by the
- * {@link View#setVisibility(int)} state of views, but also whether
- * views exist in the current view hierarchy. The class is intended to be a
- * utility for subclasses such as {@link FadePort}, which use this visibility
- * information to determine the specific animations to run when visibility
- * changes occur. Subclasses should implement one or both of the methods
- * {@link #onAppear(ViewGroup, TransitionValues, int, TransitionValues, int)},
- * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)},
- */
-@RequiresApi(14)
-@TargetApi(14)
-abstract class VisibilityPort extends TransitionPort {
-
-    private static final String PROPNAME_VISIBILITY = "android:visibility:visibility";
-
-    private static final String PROPNAME_PARENT = "android:visibility:parent";
-
-    private static final String[] sTransitionProperties = {
-            PROPNAME_VISIBILITY,
-            PROPNAME_PARENT,
-    };
-
-    @Override
-    public String[] getTransitionProperties() {
-        return sTransitionProperties;
-    }
-
-    private void captureValues(TransitionValues transitionValues) {
-        int visibility = transitionValues.view.getVisibility();
-        transitionValues.values.put(PROPNAME_VISIBILITY, visibility);
-        transitionValues.values.put(PROPNAME_PARENT, transitionValues.view.getParent());
-    }
-
-    @Override
-    public void captureStartValues(TransitionValues transitionValues) {
-        captureValues(transitionValues);
-    }
-
-    @Override
-    public void captureEndValues(TransitionValues transitionValues) {
-        captureValues(transitionValues);
-    }
-
-    /**
-     * Returns whether the view is 'visible' according to the given values
-     * object. This is determined by testing the same properties in the values
-     * object that are used to determine whether the object is appearing or
-     * disappearing in the {@link
-     * TransitionPort#createAnimator(ViewGroup, TransitionValues, TransitionValues)}
-     * method. This method can be called by, for example, subclasses that want
-     * to know whether the object is visible in the same way that Visibility
-     * determines it for the actual animation.
-     *
-     * @param values The TransitionValues object that holds the information by
-     *               which visibility is determined.
-     * @return True if the view reference by <code>values</code> is visible,
-     * false otherwise.
-     */
-    public boolean isVisible(TransitionValues values) {
-        if (values == null) {
-            return false;
-        }
-        int visibility = (Integer) values.values.get(PROPNAME_VISIBILITY);
-        View parent = (View) values.values.get(PROPNAME_PARENT);
-
-        return visibility == View.VISIBLE && parent != null;
-    }
-
-    private VisibilityInfo getVisibilityChangeInfo(TransitionValues startValues,
-            TransitionValues endValues) {
-        final VisibilityInfo visInfo = new VisibilityInfo();
-        visInfo.visibilityChange = false;
-        visInfo.fadeIn = false;
-        if (startValues != null) {
-            visInfo.startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
-            visInfo.startParent = (ViewGroup) startValues.values.get(PROPNAME_PARENT);
-        } else {
-            visInfo.startVisibility = -1;
-            visInfo.startParent = null;
-        }
-        if (endValues != null) {
-            visInfo.endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
-            visInfo.endParent = (ViewGroup) endValues.values.get(PROPNAME_PARENT);
-        } else {
-            visInfo.endVisibility = -1;
-            visInfo.endParent = null;
-        }
-        if (startValues != null && endValues != null) {
-            if (visInfo.startVisibility == visInfo.endVisibility &&
-                    visInfo.startParent == visInfo.endParent) {
-                return visInfo;
-            } else {
-                if (visInfo.startVisibility != visInfo.endVisibility) {
-                    if (visInfo.startVisibility == View.VISIBLE) {
-                        visInfo.fadeIn = false;
-                        visInfo.visibilityChange = true;
-                    } else if (visInfo.endVisibility == View.VISIBLE) {
-                        visInfo.fadeIn = true;
-                        visInfo.visibilityChange = true;
-                    }
-                    // no visibilityChange if going between INVISIBLE and GONE
-                } else if (visInfo.startParent != visInfo.endParent) {
-                    if (visInfo.endParent == null) {
-                        visInfo.fadeIn = false;
-                        visInfo.visibilityChange = true;
-                    } else if (visInfo.startParent == null) {
-                        visInfo.fadeIn = true;
-                        visInfo.visibilityChange = true;
-                    }
-                }
-            }
-        }
-        if (startValues == null) {
-            visInfo.fadeIn = true;
-            visInfo.visibilityChange = true;
-        } else if (endValues == null) {
-            visInfo.fadeIn = false;
-            visInfo.visibilityChange = true;
-        }
-        return visInfo;
-    }
-
-    @Override
-    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
-            TransitionValues endValues) {
-        VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues);
-        if (visInfo.visibilityChange) {
-            // Only transition views that are either targets of this transition
-            // or whose parent hierarchies remain stable between scenes
-            boolean isTarget = false;
-            if (mTargets.size() > 0 || mTargetIds.size() > 0) {
-                View startView = startValues != null ? startValues.view : null;
-                View endView = endValues != null ? endValues.view : null;
-                int startId = startView != null ? startView.getId() : -1;
-                int endId = endView != null ? endView.getId() : -1;
-                isTarget = isValidTarget(startView, startId) || isValidTarget(endView, endId);
-            }
-            if (isTarget || ((visInfo.startParent != null || visInfo.endParent != null))) {
-                if (visInfo.fadeIn) {
-                    return onAppear(sceneRoot, startValues, visInfo.startVisibility,
-                            endValues, visInfo.endVisibility);
-                } else {
-                    return onDisappear(sceneRoot, startValues, visInfo.startVisibility,
-                            endValues, visInfo.endVisibility
-                    );
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * The default implementation of this method does nothing. Subclasses
-     * should override if they need to create an Animator when targets appear.
-     * The method should only be called by the Visibility class; it is
-     * not intended to be called from external classes.
-     *
-     * @param sceneRoot       The root of the transition hierarchy
-     * @param startValues     The target values in the start scene
-     * @param startVisibility The target visibility in the start scene
-     * @param endValues       The target values in the end scene
-     * @param endVisibility   The target visibility in the end scene
-     * @return An Animator to be started at the appropriate time in the
-     * overall transition for this scene change. A null value means no animation
-     * should be run.
-     */
-    public Animator onAppear(ViewGroup sceneRoot,
-            TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility) {
-        return null;
-    }
-
-    /**
-     * The default implementation of this method does nothing. Subclasses
-     * should override if they need to create an Animator when targets disappear.
-     * The method should only be called by the Visibility class; it is
-     * not intended to be called from external classes.
-     *
-     * @param sceneRoot       The root of the transition hierarchy
-     * @param startValues     The target values in the start scene
-     * @param startVisibility The target visibility in the start scene
-     * @param endValues       The target values in the end scene
-     * @param endVisibility   The target visibility in the end scene
-     * @return An Animator to be started at the appropriate time in the
-     * overall transition for this scene change. A null value means no animation
-     * should be run.
-     */
-    public Animator onDisappear(ViewGroup sceneRoot,
-            TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility) {
-        return null;
-    }
-
-    private static class VisibilityInfo {
-
-        boolean visibilityChange;
-
-        boolean fadeIn;
-
-        int startVisibility;
-
-        int endVisibility;
-
-        ViewGroup startParent;
-
-        ViewGroup endParent;
-
-        VisibilityInfo() {
-        }
-    }
-}
diff --git a/transition/ics/android/support/transition/WindowIdPort.java b/transition/ics/android/support/transition/WindowIdPort.java
deleted file mode 100644
index 148332e..0000000
--- a/transition/ics/android/support/transition/WindowIdPort.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.os.IBinder;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresApi;
-import android.view.View;
-
-
-/**
- * Backport of WindowId.
- *
- * <p>Since the use of WindowId in Transition API is limited to identifying windows, we can just
- * wrap a window token and use it as an identifier.</p>
- */
-@RequiresApi(14)
-@TargetApi(14)
-class WindowIdPort {
-
-    private final IBinder mToken;
-
-    private WindowIdPort(IBinder token) {
-        mToken = token;
-    }
-
-    static WindowIdPort getWindowId(@NonNull View view) {
-        return new WindowIdPort(view.getWindowToken());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return obj instanceof WindowIdPort && ((WindowIdPort) obj).mToken.equals(this.mToken);
-    }
-
-}
diff --git a/transition/kitkat/android/support/transition/FadeKitKat.java b/transition/kitkat/android/support/transition/FadeKitKat.java
deleted file mode 100644
index 26992af..0000000
--- a/transition/kitkat/android/support/transition/FadeKitKat.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.view.ViewGroup;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(19)
-@TargetApi(19)
-class FadeKitKat extends TransitionKitKat implements VisibilityImpl {
-
-    public FadeKitKat(TransitionInterface transition) {
-        init(transition, new android.transition.Fade());
-    }
-
-    public FadeKitKat(TransitionInterface transition, int fadingMode) {
-        init(transition, new android.transition.Fade(fadingMode));
-    }
-
-    @Override
-    public boolean isVisible(TransitionValues values) {
-        return ((android.transition.Fade) mTransition).isVisible(convertToPlatform(values));
-    }
-
-    @Override
-    public Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility) {
-        return ((android.transition.Fade) mTransition).onAppear(sceneRoot,
-                convertToPlatform(startValues), startVisibility,
-                convertToPlatform(endValues), endVisibility);
-    }
-
-    @Override
-    public Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues,
-            int startVisibility, TransitionValues endValues, int endVisibility) {
-        return ((android.transition.Fade) mTransition).onDisappear(sceneRoot,
-                convertToPlatform(startValues), startVisibility,
-                convertToPlatform(endValues), endVisibility);
-    }
-
-}
diff --git a/transition/kitkat/android/support/transition/SceneKitKat.java b/transition/kitkat/android/support/transition/SceneKitKat.java
deleted file mode 100644
index ae7ad10..0000000
--- a/transition/kitkat/android/support/transition/SceneKitKat.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(19)
-@TargetApi(19)
-class SceneKitKat extends SceneWrapper {
-
-    private static Field sEnterAction;
-    private static Method sSetCurrentScene;
-
-    private View mLayout; // alternative to layoutId
-
-    @Override
-    public void init(ViewGroup sceneRoot) {
-        mScene = new android.transition.Scene(sceneRoot);
-    }
-
-    @Override
-    public void init(ViewGroup sceneRoot, View layout) {
-        if (layout instanceof ViewGroup) {
-            mScene = new android.transition.Scene(sceneRoot, (ViewGroup) layout);
-        } else {
-            mScene = new android.transition.Scene(sceneRoot);
-            mLayout = layout;
-        }
-    }
-
-    @Override
-    public void enter() {
-        if (mLayout != null) {
-            // empty out parent container before adding to it
-            final ViewGroup root = getSceneRoot();
-            root.removeAllViews();
-            root.addView(mLayout);
-            invokeEnterAction();
-            updateCurrentScene(root);
-        } else {
-            mScene.enter();
-        }
-    }
-
-    private void invokeEnterAction() {
-        if (sEnterAction == null) {
-            try {
-                sEnterAction = android.transition.Scene.class.getDeclaredField("mEnterAction");
-                sEnterAction.setAccessible(true);
-            } catch (NoSuchFieldException e) {
-                throw new RuntimeException(e);
-            }
-        }
-        try {
-            final Runnable enterAction = (Runnable) sEnterAction.get(mScene);
-            if (enterAction != null) {
-                enterAction.run();
-            }
-        } catch (IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /** Sets this Scene as the current scene of the View. */
-    private void updateCurrentScene(View view) {
-        if (sSetCurrentScene == null) {
-            try {
-                sSetCurrentScene = android.transition.Scene.class.getDeclaredMethod(
-                        "setCurrentScene", View.class, android.transition.Scene.class);
-                sSetCurrentScene.setAccessible(true);
-            } catch (NoSuchMethodException e) {
-                throw new RuntimeException(e);
-            }
-        }
-        try {
-            sSetCurrentScene.invoke(null, view, mScene);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}
diff --git a/transition/kitkat/android/support/transition/SceneStaticsKitKat.java b/transition/kitkat/android/support/transition/SceneStaticsKitKat.java
deleted file mode 100644
index 94868d0..0000000
--- a/transition/kitkat/android/support/transition/SceneStaticsKitKat.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.content.Context;
-import android.view.ViewGroup;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(19)
-@TargetApi(19)
-class SceneStaticsKitKat extends SceneStaticsImpl {
-
-    @Override
-    public SceneImpl getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) {
-        SceneKitKat scene = new SceneKitKat();
-        scene.mScene = android.transition.Scene.getSceneForLayout(sceneRoot, layoutId, context);
-        return scene;
-    }
-
-}
diff --git a/transition/kitkat/android/support/transition/SceneWrapper.java b/transition/kitkat/android/support/transition/SceneWrapper.java
deleted file mode 100644
index cad5db9..0000000
--- a/transition/kitkat/android/support/transition/SceneWrapper.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.view.ViewGroup;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(19)
-@TargetApi(19)
-abstract class SceneWrapper extends SceneImpl {
-
-    /* package */ android.transition.Scene mScene;
-
-    @Override
-    public ViewGroup getSceneRoot() {
-        return mScene.getSceneRoot();
-    }
-
-    @Override
-    public void exit() {
-        mScene.exit();
-    }
-
-    @Override
-    public void setEnterAction(Runnable action) {
-        mScene.setEnterAction(action);
-    }
-
-    @Override
-    public void setExitAction(Runnable action) {
-        mScene.setExitAction(action);
-    }
-
-}
diff --git a/transition/kitkat/android/support/transition/TransitionKitKat.java b/transition/kitkat/android/support/transition/TransitionKitKat.java
deleted file mode 100644
index c608f66..0000000
--- a/transition/kitkat/android/support/transition/TransitionKitKat.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.animation.TimeInterpolator;
-import android.transition.Transition;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(19)
-@TargetApi(19)
-class TransitionKitKat extends TransitionImpl {
-
-    /* package */ android.transition.Transition mTransition;
-
-    /* package */ TransitionInterface mExternalTransition;
-
-    private CompatListener mCompatListener;
-
-    static void copyValues(android.transition.TransitionValues source,
-            android.support.transition.TransitionValues dest) {
-        if (source == null) {
-            return;
-        }
-        dest.view = source.view;
-        if (source.values.size() > 0) {
-            dest.values.putAll(source.values);
-        }
-    }
-
-    static void copyValues(android.support.transition.TransitionValues source,
-            android.transition.TransitionValues dest) {
-        if (source == null) {
-            return;
-        }
-        dest.view = source.view;
-        if (source.values.size() > 0) {
-            dest.values.putAll(source.values);
-        }
-    }
-
-    static void wrapCaptureStartValues(TransitionInterface transition,
-            android.transition.TransitionValues transitionValues) {
-        android.support.transition.TransitionValues externalValues =
-                new android.support.transition.TransitionValues();
-        copyValues(transitionValues, externalValues);
-        transition.captureStartValues(externalValues);
-        copyValues(externalValues, transitionValues);
-    }
-
-    static void wrapCaptureEndValues(TransitionInterface transition,
-            android.transition.TransitionValues transitionValues) {
-        android.support.transition.TransitionValues externalValues =
-                new android.support.transition.TransitionValues();
-        copyValues(transitionValues, externalValues);
-        transition.captureEndValues(externalValues);
-        copyValues(externalValues, transitionValues);
-    }
-
-    static TransitionValues convertToSupport(android.transition.TransitionValues values) {
-        if (values == null) {
-            return null;
-        }
-        TransitionValues supportValues = new TransitionValues();
-        copyValues(values, supportValues);
-        return supportValues;
-    }
-
-    static android.transition.TransitionValues convertToPlatform(TransitionValues values) {
-        if (values == null) {
-            return null;
-        }
-        android.transition.TransitionValues platformValues
-                = new android.transition.TransitionValues();
-        copyValues(values, platformValues);
-        return platformValues;
-    }
-
-    @Override
-    public void init(TransitionInterface external, Object internal) {
-        mExternalTransition = external;
-        if (internal == null) {
-            mTransition = new TransitionWrapper(external);
-        } else {
-            mTransition = (android.transition.Transition) internal;
-        }
-    }
-
-    @Override
-    public TransitionImpl addListener(TransitionInterfaceListener listener) {
-        if (mCompatListener == null) {
-            mCompatListener = new CompatListener();
-            mTransition.addListener(mCompatListener);
-        }
-        mCompatListener.addListener(listener);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl removeListener(TransitionInterfaceListener listener) {
-        if (mCompatListener == null) {
-            return this;
-        }
-        mCompatListener.removeListener(listener);
-        if (mCompatListener.isEmpty()) {
-            mTransition.removeListener(mCompatListener);
-            mCompatListener = null;
-        }
-        return this;
-    }
-
-    @Override
-    public TransitionImpl addTarget(View target) {
-        mTransition.addTarget(target);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl addTarget(int targetId) {
-        mTransition.addTarget(targetId);
-        return this;
-    }
-
-    @Override
-    public void captureEndValues(TransitionValues transitionValues) {
-        android.transition.TransitionValues internalValues =
-                new android.transition.TransitionValues();
-        copyValues(transitionValues, internalValues);
-        mTransition.captureEndValues(internalValues);
-        copyValues(internalValues, transitionValues);
-    }
-
-    @Override
-    public void captureStartValues(TransitionValues transitionValues) {
-        android.transition.TransitionValues internalValues =
-                new android.transition.TransitionValues();
-        copyValues(transitionValues, internalValues);
-        mTransition.captureStartValues(internalValues);
-        copyValues(internalValues, transitionValues);
-    }
-
-    @Override
-    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
-            TransitionValues endValues) {
-        android.transition.TransitionValues internalStartValues;
-        android.transition.TransitionValues internalEndValues;
-        if (startValues != null) {
-            internalStartValues = new android.transition.TransitionValues();
-            copyValues(startValues, internalStartValues);
-        } else {
-            internalStartValues = null;
-        }
-        if (endValues != null) {
-            internalEndValues = new android.transition.TransitionValues();
-            copyValues(endValues, internalEndValues);
-        } else {
-            internalEndValues = null;
-        }
-        return mTransition.createAnimator(sceneRoot, internalStartValues, internalEndValues);
-    }
-
-    @Override
-    public TransitionImpl excludeChildren(View target, boolean exclude) {
-        mTransition.excludeChildren(target, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeChildren(int targetId, boolean exclude) {
-        mTransition.excludeChildren(targetId, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeChildren(Class type, boolean exclude) {
-        mTransition.excludeChildren(type, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeTarget(View target, boolean exclude) {
-        mTransition.excludeTarget(target, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeTarget(int targetId, boolean exclude) {
-        mTransition.excludeTarget(targetId, exclude);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl excludeTarget(Class type, boolean exclude) {
-        mTransition.excludeTarget(type, exclude);
-        return this;
-    }
-
-    @Override
-    public long getDuration() {
-        return mTransition.getDuration();
-    }
-
-    @Override
-    public TransitionImpl setDuration(long duration) {
-        mTransition.setDuration(duration);
-        return this;
-    }
-
-    @Override
-    public TimeInterpolator getInterpolator() {
-        return mTransition.getInterpolator();
-    }
-
-    @Override
-    public TransitionImpl setInterpolator(TimeInterpolator interpolator) {
-        mTransition.setInterpolator(interpolator);
-        return this;
-    }
-
-    @Override
-    public String getName() {
-        return mTransition.getName();
-    }
-
-    @Override
-    public long getStartDelay() {
-        return mTransition.getStartDelay();
-    }
-
-    @Override
-    public TransitionImpl setStartDelay(long startDelay) {
-        mTransition.setStartDelay(startDelay);
-        return this;
-    }
-
-    @Override
-    public List<Integer> getTargetIds() {
-        return mTransition.getTargetIds();
-    }
-
-    @Override
-    public List<View> getTargets() {
-        return mTransition.getTargets();
-    }
-
-    @Override
-    public String[] getTransitionProperties() {
-        return mTransition.getTransitionProperties();
-    }
-
-    @Override
-    public TransitionValues getTransitionValues(View view, boolean start) {
-        TransitionValues values = new TransitionValues();
-        copyValues(mTransition.getTransitionValues(view, start), values);
-        return values;
-    }
-
-    @Override
-    public TransitionImpl removeTarget(View target) {
-        mTransition.removeTarget(target);
-        return this;
-    }
-
-    @Override
-    public TransitionImpl removeTarget(int targetId) {
-        if (targetId > 0) {
-            // Workaround for the issue that the platform version calls remove(int)
-            // when it should call remove(Integer)
-            getTargetIds().remove((Integer) targetId);
-        }
-        return this;
-    }
-
-    @Override
-    public String toString() {
-        return mTransition.toString();
-    }
-
-    private static class TransitionWrapper extends android.transition.Transition {
-
-        private TransitionInterface mTransition;
-
-        public TransitionWrapper(TransitionInterface transition) {
-            mTransition = transition;
-        }
-
-        @Override
-        public void captureStartValues(android.transition.TransitionValues transitionValues) {
-            wrapCaptureStartValues(mTransition, transitionValues);
-        }
-
-        @Override
-        public void captureEndValues(android.transition.TransitionValues transitionValues) {
-            wrapCaptureEndValues(mTransition, transitionValues);
-        }
-
-        @Override
-        public Animator createAnimator(ViewGroup sceneRoot,
-                android.transition.TransitionValues startValues,
-                android.transition.TransitionValues endValues) {
-            return mTransition.createAnimator(sceneRoot, convertToSupport(startValues),
-                    convertToSupport(endValues));
-        }
-
-    }
-
-    @SuppressWarnings("unchecked")
-    private class CompatListener implements android.transition.Transition.TransitionListener {
-
-        private final ArrayList<TransitionInterfaceListener> mListeners = new ArrayList<>();
-
-        CompatListener() {
-        }
-
-        void addListener(TransitionInterfaceListener listener) {
-            mListeners.add(listener);
-        }
-
-        void removeListener(TransitionInterfaceListener listener) {
-            mListeners.remove(listener);
-        }
-
-        boolean isEmpty() {
-            return mListeners.isEmpty();
-        }
-
-        @Override
-        public void onTransitionStart(Transition transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionStart(mExternalTransition);
-            }
-        }
-
-        @Override
-        public void onTransitionEnd(Transition transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionEnd(mExternalTransition);
-            }
-        }
-
-        @Override
-        public void onTransitionCancel(Transition transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionCancel(mExternalTransition);
-            }
-        }
-
-        @Override
-        public void onTransitionPause(Transition transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionPause(mExternalTransition);
-            }
-        }
-
-        @Override
-        public void onTransitionResume(Transition transition) {
-            for (TransitionInterfaceListener listener : mListeners) {
-                listener.onTransitionResume(mExternalTransition);
-            }
-        }
-
-    }
-
-}
diff --git a/transition/kitkat/android/support/transition/TransitionManagerKitKat.java b/transition/kitkat/android/support/transition/TransitionManagerKitKat.java
deleted file mode 100644
index 3326600..0000000
--- a/transition/kitkat/android/support/transition/TransitionManagerKitKat.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.transition.TransitionManager;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(19)
-@TargetApi(19)
-class TransitionManagerKitKat extends TransitionManagerImpl {
-
-    private final android.transition.TransitionManager mTransitionManager = new TransitionManager();
-
-    @Override
-    public void setTransition(SceneImpl scene, TransitionImpl transition) {
-        mTransitionManager.setTransition(((SceneWrapper) scene).mScene,
-                transition == null ? null : ((TransitionKitKat) transition).mTransition);
-    }
-
-    @Override
-    public void setTransition(SceneImpl fromScene, SceneImpl toScene, TransitionImpl transition) {
-        mTransitionManager.setTransition(((SceneWrapper) fromScene).mScene,
-                ((SceneWrapper) toScene).mScene,
-                transition == null ? null : ((TransitionKitKat) transition).mTransition);
-    }
-
-    @Override
-    public void transitionTo(SceneImpl scene) {
-        mTransitionManager.transitionTo(((SceneWrapper) scene).mScene);
-    }
-
-}
diff --git a/transition/kitkat/android/support/transition/TransitionManagerStaticsKitKat.java b/transition/kitkat/android/support/transition/TransitionManagerStaticsKitKat.java
deleted file mode 100644
index e7c927b..0000000
--- a/transition/kitkat/android/support/transition/TransitionManagerStaticsKitKat.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.view.ViewGroup;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(19)
-@TargetApi(19)
-class TransitionManagerStaticsKitKat extends TransitionManagerStaticsImpl {
-
-    @Override
-    public void go(SceneImpl scene) {
-        android.transition.TransitionManager.go(((SceneWrapper) scene).mScene);
-    }
-
-    @Override
-    public void go(SceneImpl scene, TransitionImpl transition) {
-        android.transition.TransitionManager.go(((SceneWrapper) scene).mScene,
-                transition == null ? null : ((TransitionKitKat) transition).mTransition);
-    }
-
-    @Override
-    public void beginDelayedTransition(ViewGroup sceneRoot) {
-        android.transition.TransitionManager.beginDelayedTransition(sceneRoot);
-    }
-
-    @Override
-    public void beginDelayedTransition(ViewGroup sceneRoot, TransitionImpl transition) {
-        android.transition.TransitionManager.beginDelayedTransition(sceneRoot,
-                transition == null ? null : ((TransitionKitKat) transition).mTransition);
-    }
-
-}
diff --git a/transition/kitkat/android/support/transition/TransitionSetKitKat.java b/transition/kitkat/android/support/transition/TransitionSetKitKat.java
deleted file mode 100644
index f880d71..0000000
--- a/transition/kitkat/android/support/transition/TransitionSetKitKat.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(19)
-@TargetApi(19)
-class TransitionSetKitKat extends TransitionKitKat implements TransitionSetImpl {
-
-    private android.transition.TransitionSet mTransitionSet;
-
-    public TransitionSetKitKat(TransitionInterface transition) {
-        mTransitionSet = new android.transition.TransitionSet();
-        init(transition, mTransitionSet);
-    }
-
-    @Override
-    public int getOrdering() {
-        return mTransitionSet.getOrdering();
-    }
-
-    @Override
-    public TransitionSetKitKat setOrdering(int ordering) {
-        mTransitionSet.setOrdering(ordering);
-        return this;
-    }
-
-    @Override
-    public TransitionSetKitKat addTransition(TransitionImpl transition) {
-        mTransitionSet.addTransition(((TransitionKitKat) transition).mTransition);
-        return this;
-    }
-
-    @Override
-    public TransitionSetKitKat removeTransition(TransitionImpl transition) {
-        mTransitionSet.removeTransition(((TransitionKitKat) transition).mTransition);
-        return this;
-    }
-
-}
diff --git a/transition/kitkat/android/support/transition/VisibilityKitKat.java b/transition/kitkat/android/support/transition/VisibilityKitKat.java
deleted file mode 100644
index ca603ae..0000000
--- a/transition/kitkat/android/support/transition/VisibilityKitKat.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.transition;
-
-import android.animation.Animator;
-import android.view.ViewGroup;
-
-import android.annotation.TargetApi;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(19)
-@TargetApi(19)
-class VisibilityKitKat extends TransitionKitKat implements VisibilityImpl {
-
-    @Override
-    public void init(TransitionInterface external, Object internal) {
-        mExternalTransition = external;
-        if (internal == null) {
-            mTransition = new VisibilityWrapper((VisibilityInterface) external);
-        } else {
-            mTransition = (android.transition.Visibility) internal;
-        }
-    }
-
-    @Override
-    public boolean isVisible(TransitionValues values) {
-        return ((android.transition.Visibility) mTransition).isVisible(convertToPlatform(values));
-    }
-
-    @Override
-    public Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
-            TransitionValues endValues, int endVisibility) {
-        return ((android.transition.Visibility) mTransition).onAppear(sceneRoot,
-                convertToPlatform(startValues), startVisibility,
-                convertToPlatform(endValues), endVisibility);
-    }
-
-    @Override
-    public Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues,
-            int startVisibility, TransitionValues endValues, int endVisibility) {
-        return ((android.transition.Visibility) mTransition).onDisappear(sceneRoot,
-                convertToPlatform(startValues), startVisibility,
-                convertToPlatform(endValues), endVisibility);
-    }
-
-    private static class VisibilityWrapper extends android.transition.Visibility {
-
-        private final VisibilityInterface mVisibility;
-
-        VisibilityWrapper(VisibilityInterface visibility) {
-            mVisibility = visibility;
-        }
-
-        @Override
-        public void captureStartValues(android.transition.TransitionValues transitionValues) {
-            wrapCaptureStartValues(mVisibility, transitionValues);
-        }
-
-        @Override
-        public void captureEndValues(android.transition.TransitionValues transitionValues) {
-            wrapCaptureEndValues(mVisibility, transitionValues);
-        }
-
-        @Override
-        public Animator createAnimator(ViewGroup sceneRoot,
-                android.transition.TransitionValues startValues,
-                android.transition.TransitionValues endValues) {
-            return mVisibility.createAnimator(sceneRoot, convertToSupport(startValues),
-                    convertToSupport(endValues));
-        }
-
-        @Override
-        public boolean isVisible(android.transition.TransitionValues values) {
-            if (values == null) {
-                return false;
-            }
-            TransitionValues externalValues = new TransitionValues();
-            copyValues(values, externalValues);
-            return mVisibility.isVisible(externalValues);
-        }
-
-        @Override
-        public Animator onAppear(ViewGroup sceneRoot,
-                android.transition.TransitionValues startValues, int startVisibility,
-                android.transition.TransitionValues endValues, int endVisibility) {
-            return mVisibility.onAppear(sceneRoot, convertToSupport(startValues), startVisibility,
-                    convertToSupport(endValues), endVisibility);
-        }
-
-        @Override
-        public Animator onDisappear(ViewGroup sceneRoot,
-                android.transition.TransitionValues startValues, int startVisibility,
-                android.transition.TransitionValues endValues, int endVisibility) {
-            return mVisibility.onDisappear(sceneRoot, convertToSupport(startValues),
-                    startVisibility,
-                    convertToSupport(endValues), endVisibility);
-        }
-
-    }
-
-}
diff --git a/transition/res/values/ids.xml b/transition/res/values/ids.xml
index 9a6846b..071cf2a 100644
--- a/transition/res/values/ids.xml
+++ b/transition/res/values/ids.xml
@@ -17,4 +17,5 @@
 <resources>
     <item name="transition_scene_layoutid_cache" type="id"/>
     <item name="transition_current_scene" type="id"/>
+    <item name="transition_layout_save" type="id"/>
 </resources>
diff --git a/transition/src/android/support/transition/ChangeBounds.java b/transition/src/android/support/transition/ChangeBounds.java
index f29f056..ae119a4 100644
--- a/transition/src/android/support/transition/ChangeBounds.java
+++ b/transition/src/android/support/transition/ChangeBounds.java
@@ -17,11 +17,20 @@
 package android.support.transition;
 
 import android.animation.Animator;
-import android.os.Build;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.view.View;
 import android.view.ViewGroup;
 
+import java.util.Map;
+
 /**
  * This transition captures the layout bounds of target views before and after
  * the scene change and animates those changes during the transition.
@@ -30,30 +39,27 @@
  */
 public class ChangeBounds extends Transition {
 
-    public ChangeBounds() {
-        super(true);
-        if (Build.VERSION.SDK_INT < 19) {
-            mImpl = new ChangeBoundsIcs(this);
-        } else {
-            mImpl = new ChangeBoundsKitKat(this);
-        }
-    }
+    private static final String PROPNAME_BOUNDS = "android:changeBounds:bounds";
+    private static final String PROPNAME_PARENT = "android:changeBounds:parent";
+    private static final String PROPNAME_WINDOW_X = "android:changeBounds:windowX";
+    private static final String PROPNAME_WINDOW_Y = "android:changeBounds:windowY";
+    private static final String[] sTransitionProperties = {
+            PROPNAME_BOUNDS,
+            PROPNAME_PARENT,
+            PROPNAME_WINDOW_X,
+            PROPNAME_WINDOW_Y
+    };
 
-    @Override
-    public void captureEndValues(@NonNull TransitionValues transitionValues) {
-        mImpl.captureEndValues(transitionValues);
-    }
+    int[] mTempLocation = new int[2];
+    boolean mResizeClip = false;
+    boolean mReparent = false;
 
-    @Override
-    public void captureStartValues(@NonNull TransitionValues transitionValues) {
-        mImpl.captureStartValues(transitionValues);
-    }
+    private static RectEvaluator sRectEvaluator = new RectEvaluator();
 
-    @Override
     @Nullable
-    public Animator createAnimator(@NonNull ViewGroup sceneRoot,
-            @NonNull TransitionValues startValues, @NonNull TransitionValues endValues) {
-        return mImpl.createAnimator(sceneRoot, startValues, endValues);
+    @Override
+    public String[] getTransitionProperties() {
+        return sTransitionProperties;
     }
 
     /**
@@ -70,7 +76,263 @@
      * @see android.view.View#setClipBounds(android.graphics.Rect)
      */
     public void setResizeClip(boolean resizeClip) {
-        ((ChangeBoundsInterface) mImpl).setResizeClip(resizeClip);
+        mResizeClip = resizeClip;
+    }
+
+    private void captureValues(TransitionValues values) {
+        View view = values.view;
+        values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(),
+                view.getRight(), view.getBottom()));
+        values.values.put(PROPNAME_PARENT, values.view.getParent());
+        values.view.getLocationInWindow(mTempLocation);
+        values.values.put(PROPNAME_WINDOW_X, mTempLocation[0]);
+        values.values.put(PROPNAME_WINDOW_Y, mTempLocation[1]);
+    }
+
+    @Override
+    public void captureStartValues(@NonNull TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(@NonNull TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    @Nullable
+    public Animator createAnimator(@NonNull final ViewGroup sceneRoot,
+            @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) {
+        if (startValues == null || endValues == null) {
+            return null;
+        }
+        Map<String, Object> startParentVals = startValues.values;
+        Map<String, Object> endParentVals = endValues.values;
+        ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
+        ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
+        if (startParent == null || endParent == null) {
+            return null;
+        }
+        final View view = endValues.view;
+        boolean parentsEqual = (startParent == endParent)
+                || (startParent.getId() == endParent.getId());
+        // TODO: Might want reparenting to be separate/subclass transition, or at least
+        // triggered by a property on ChangeBounds. Otherwise, we're forcing the requirement that
+        // all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect
+        // of reparenting the views.
+        if (!mReparent || parentsEqual) {
+            Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
+            Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
+            int startLeft = startBounds.left;
+            int endLeft = endBounds.left;
+            int startTop = startBounds.top;
+            int endTop = endBounds.top;
+            int startRight = startBounds.right;
+            int endRight = endBounds.right;
+            int startBottom = startBounds.bottom;
+            int endBottom = endBounds.bottom;
+            int startWidth = startRight - startLeft;
+            int startHeight = startBottom - startTop;
+            int endWidth = endRight - endLeft;
+            int endHeight = endBottom - endTop;
+            int numChanges = 0;
+            if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) {
+                if (startLeft != endLeft) {
+                    ++numChanges;
+                }
+                if (startTop != endTop) {
+                    ++numChanges;
+                }
+                if (startRight != endRight) {
+                    ++numChanges;
+                }
+                if (startBottom != endBottom) {
+                    ++numChanges;
+                }
+            }
+            if (numChanges > 0) {
+                if (!mResizeClip) {
+                    PropertyValuesHolder[] pvh = new PropertyValuesHolder[numChanges];
+                    int pvhIndex = 0;
+                    if (startLeft != endLeft) {
+                        view.setLeft(startLeft);
+                    }
+                    if (startTop != endTop) {
+                        view.setTop(startTop);
+                    }
+                    if (startRight != endRight) {
+                        view.setRight(startRight);
+                    }
+                    if (startBottom != endBottom) {
+                        view.setBottom(startBottom);
+                    }
+                    if (startLeft != endLeft) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("left", startLeft, endLeft);
+                    }
+                    if (startTop != endTop) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("top", startTop, endTop);
+                    }
+                    if (startRight != endRight) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("right",
+                                startRight, endRight);
+                    }
+                    if (startBottom != endBottom) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("bottom",
+                                startBottom, endBottom);
+                    }
+                    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh);
+                    if (view.getParent() instanceof ViewGroup) {
+                        final ViewGroup parent = (ViewGroup) view.getParent();
+                        ViewGroupUtils.suppressLayout(parent, true);
+                        TransitionListener transitionListener = new TransitionListenerAdapter() {
+                            boolean mCanceled = false;
+
+                            @Override
+                            public void onTransitionCancel(@NonNull Transition transition) {
+                                ViewGroupUtils.suppressLayout(parent, false);
+                                mCanceled = true;
+                            }
+
+                            @Override
+                            public void onTransitionEnd(@NonNull Transition transition) {
+                                if (!mCanceled) {
+                                    ViewGroupUtils.suppressLayout(parent, false);
+                                }
+                            }
+
+                            @Override
+                            public void onTransitionPause(@NonNull Transition transition) {
+                                ViewGroupUtils.suppressLayout(parent, false);
+                            }
+
+                            @Override
+                            public void onTransitionResume(@NonNull Transition transition) {
+                                ViewGroupUtils.suppressLayout(parent, true);
+                            }
+                        };
+                        addListener(transitionListener);
+                    }
+                    return anim;
+                } else {
+                    if (startWidth != endWidth) {
+                        view.setRight(endLeft + Math.max(startWidth, endWidth));
+                    }
+                    if (startHeight != endHeight) {
+                        view.setBottom(endTop + Math.max(startHeight, endHeight));
+                    }
+                    // TODO: don't clobber TX/TY
+                    if (startLeft != endLeft) {
+                        view.setTranslationX(startLeft - endLeft);
+                    }
+                    if (startTop != endTop) {
+                        view.setTranslationY(startTop - endTop);
+                    }
+                    // Animate location with translationX/Y and size with clip bounds
+                    float transXDelta = endLeft - startLeft;
+                    float transYDelta = endTop - startTop;
+                    int widthDelta = endWidth - startWidth;
+                    int heightDelta = endHeight - startHeight;
+                    numChanges = 0;
+                    if (transXDelta != 0) {
+                        numChanges++;
+                    }
+                    if (transYDelta != 0) {
+                        numChanges++;
+                    }
+                    if (widthDelta != 0 || heightDelta != 0) {
+                        numChanges++;
+                    }
+                    PropertyValuesHolder[] pvh = new PropertyValuesHolder[numChanges];
+                    int pvhIndex = 0;
+                    if (transXDelta != 0) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationX",
+                                view.getTranslationX(), 0);
+                    }
+                    if (transYDelta != 0) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationY",
+                                view.getTranslationY(), 0);
+                    }
+                    if (widthDelta != 0 || heightDelta != 0) {
+                        Rect tempStartBounds = new Rect(0, 0, startWidth, startHeight);
+                        Rect tempEndBounds = new Rect(0, 0, endWidth, endHeight);
+//                        pvh[pvhIndex++] = PropertyValuesHolder.ofObject("clipBounds",
+//                                sRectEvaluator, tempStartBounds, tempEndBounds);
+                    }
+                    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh);
+                    if (view.getParent() instanceof ViewGroup) {
+                        final ViewGroup parent = (ViewGroup) view.getParent();
+                        ViewGroupUtils.suppressLayout(parent, true);
+                        TransitionListener transitionListener = new TransitionListenerAdapter() {
+                            boolean mCanceled = false;
+
+                            @Override
+                            public void onTransitionCancel(@NonNull Transition transition) {
+                                ViewGroupUtils.suppressLayout(parent, false);
+                                mCanceled = true;
+                            }
+
+                            @Override
+                            public void onTransitionEnd(@NonNull Transition transition) {
+                                if (!mCanceled) {
+                                    ViewGroupUtils.suppressLayout(parent, false);
+                                }
+                            }
+
+                            @Override
+                            public void onTransitionPause(@NonNull Transition transition) {
+                                ViewGroupUtils.suppressLayout(parent, false);
+                            }
+
+                            @Override
+                            public void onTransitionResume(@NonNull Transition transition) {
+                                ViewGroupUtils.suppressLayout(parent, true);
+                            }
+                        };
+                        addListener(transitionListener);
+                    }
+                    anim.addListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+//                            view.setClipBounds(null);
+                        }
+                    });
+                    return anim;
+                }
+            }
+        } else {
+            int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X);
+            int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y);
+            int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X);
+            int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y);
+            // TODO: also handle size changes: check bounds and animate size changes
+            if (startX != endX || startY != endY) {
+                sceneRoot.getLocationInWindow(mTempLocation);
+                Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
+                        Bitmap.Config.ARGB_8888);
+                Canvas canvas = new Canvas(bitmap);
+                view.draw(canvas);
+                final BitmapDrawable drawable = new BitmapDrawable(bitmap);
+                view.setVisibility(View.INVISIBLE);
+                ViewUtils.getOverlay(sceneRoot).add(drawable);
+                Rect startBounds1 = new Rect(startX - mTempLocation[0], startY - mTempLocation[1],
+                        startX - mTempLocation[0] + view.getWidth(),
+                        startY - mTempLocation[1] + view.getHeight());
+                Rect endBounds1 = new Rect(endX - mTempLocation[0], endY - mTempLocation[1],
+                        endX - mTempLocation[0] + view.getWidth(),
+                        endY - mTempLocation[1] + view.getHeight());
+                ObjectAnimator anim = ObjectAnimator.ofObject(drawable, "bounds",
+                        sRectEvaluator, startBounds1, endBounds1);
+                anim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        ViewUtils.getOverlay(sceneRoot).remove(drawable);
+                        view.setVisibility(View.VISIBLE);
+                    }
+                });
+                return anim;
+            }
+        }
+        return null;
     }
 
 }
diff --git a/transition/src/android/support/transition/Fade.java b/transition/src/android/support/transition/Fade.java
index a9965a6..c2b5711 100644
--- a/transition/src/android/support/transition/Fade.java
+++ b/transition/src/android/support/transition/Fade.java
@@ -17,9 +17,11 @@
 package android.support.transition;
 
 import android.animation.Animator;
-import android.os.Build;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
 import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import android.support.v4.view.ViewCompat;
+import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -52,6 +54,10 @@
  */
 public class Fade extends Visibility {
 
+    private static final String LOG_TAG = "Fade";
+    private static final String PROPNAME_SCREEN_X = "android:fade:screenX";
+    private static final String PROPNAME_SCREEN_Y = "android:fade:screenY";
+
     /**
      * Fading mode used in {@link #Fade(int)} to make the transition
      * operate on targets that are appearing. Maybe be combined with
@@ -66,6 +72,8 @@
      */
     public static final int OUT = 0x2;
 
+    private int mFadingMode;
+
     /**
      * Constructs a Fade transition that will fade targets in
      * and/or out, according to the value of fadingMode.
@@ -74,44 +82,259 @@
      *                   {@link #IN} and {@link #OUT}.
      */
     public Fade(int fadingMode) {
-        super(true);
-        if (Build.VERSION.SDK_INT >= 19) {
-            if (fadingMode > 0) {
-                mImpl = new FadeKitKat(this, fadingMode);
-            } else {
-                mImpl = new FadeKitKat(this);
-            }
-        } else {
-            if (fadingMode > 0) {
-                mImpl = new FadeIcs(this, fadingMode);
-            } else {
-                mImpl = new FadeIcs(this);
-            }
-        }
+        mFadingMode = fadingMode;
     }
 
     /**
      * Constructs a Fade transition that will fade targets in and out.
      */
     public Fade() {
-        this(-1);
+        this(IN | OUT);
     }
 
-    @Override
-    public void captureEndValues(@NonNull TransitionValues transitionValues) {
-        mImpl.captureEndValues(transitionValues);
+    /**
+     * Utility method to handle creating and running the Animator.
+     */
+    private Animator createAnimation(View view, float startAlpha, float endAlpha,
+            AnimatorListenerAdapter listener) {
+        if (startAlpha == endAlpha) {
+            // run listener if we're noop'ing the animation, to get the end-state results now
+            if (listener != null) {
+                listener.onAnimationEnd(null);
+            }
+            return null;
+        }
+        final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", startAlpha,
+                endAlpha);
+        if (DBG) {
+            Log.d(LOG_TAG, "Created animator " + anim);
+        }
+        if (listener != null) {
+            anim.addListener(listener);
+        }
+        return anim;
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        int[] loc = new int[2];
+        transitionValues.view.getLocationOnScreen(loc);
+        transitionValues.values.put(PROPNAME_SCREEN_X, loc[0]);
+        transitionValues.values.put(PROPNAME_SCREEN_Y, loc[1]);
     }
 
     @Override
     public void captureStartValues(@NonNull TransitionValues transitionValues) {
-        mImpl.captureStartValues(transitionValues);
+        super.captureStartValues(transitionValues);
+        captureValues(transitionValues);
     }
 
     @Override
-    @Nullable
-    public Animator createAnimator(@NonNull ViewGroup sceneRoot,
-            @NonNull TransitionValues startValues, @NonNull TransitionValues endValues) {
-        return mImpl.createAnimator(sceneRoot, startValues, endValues);
+    public Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
+            TransitionValues endValues, int endVisibility) {
+        if ((mFadingMode & IN) != IN || endValues == null) {
+            return null;
+        }
+        final View endView = endValues.view;
+        if (DBG) {
+            View startView = (startValues != null) ? startValues.view : null;
+            Log.d(LOG_TAG, "Fade.onAppear: startView, startVis, endView, endVis = "
+                    + startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
+        }
+        endView.setAlpha(0);
+        TransitionListener transitionListener = new TransitionListenerAdapter() {
+            boolean mCanceled = false;
+
+            float mPausedAlpha;
+
+            @Override
+            public void onTransitionCancel(@NonNull Transition transition) {
+                endView.setAlpha(1);
+                mCanceled = true;
+            }
+
+            @Override
+            public void onTransitionEnd(@NonNull Transition transition) {
+                if (!mCanceled) {
+                    endView.setAlpha(1);
+                }
+            }
+
+            @Override
+            public void onTransitionPause(@NonNull Transition transition) {
+                mPausedAlpha = endView.getAlpha();
+                endView.setAlpha(1);
+            }
+
+            @Override
+            public void onTransitionResume(@NonNull Transition transition) {
+                endView.setAlpha(mPausedAlpha);
+            }
+        };
+        addListener(transitionListener);
+        return createAnimation(endView, 0, 1, null);
+    }
+
+    @Override
+    public Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues,
+            int startVisibility, TransitionValues endValues, int endVisibility) {
+        if ((mFadingMode & OUT) != OUT) {
+            return null;
+        }
+        View view = null;
+        View startView = (startValues != null) ? startValues.view : null;
+        View endView = (endValues != null) ? endValues.view : null;
+        if (DBG) {
+            Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = "
+                    + startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
+        }
+        View overlayView = null;
+        View viewToKeep = null;
+        if (endView == null || endView.getParent() == null) {
+            if (endView != null) {
+                // endView was removed from its parent - add it to the overlay
+                view = overlayView = endView;
+            } else if (startView != null) {
+                // endView does not exist. Use startView only under certain
+                // conditions, because placing a view in an overlay necessitates
+                // it being removed from its current parent
+                if (startView.getParent() == null) {
+                    // no parent - safe to use
+                    view = overlayView = startView;
+                } else if (startView.getParent() instanceof View
+                        && startView.getParent().getParent() == null) {
+                    View startParent = (View) startView.getParent();
+                    int id = startParent.getId();
+                    if (id != View.NO_ID && sceneRoot.findViewById(id) != null && mCanRemoveViews) {
+                        // no parent, but its parent is unparented  but the parent
+                        // hierarchy has been replaced by a new hierarchy with the same id
+                        // and it is safe to un-parent startView
+                        view = overlayView = startView;
+                    }
+                }
+            }
+        } else {
+            // visibility change
+            if (endVisibility == View.INVISIBLE) {
+                view = endView;
+                viewToKeep = view;
+            } else {
+                // Becoming GONE
+                if (startView == endView) {
+                    view = endView;
+                    viewToKeep = view;
+                } else {
+                    view = startView;
+                    overlayView = view;
+                }
+            }
+        }
+        final int finalVisibility = endVisibility;
+        // TODO: add automatic facility to Visibility superclass for keeping views around
+        if (overlayView != null) {
+            // TODO: Need to do this for general case of adding to overlay
+            int screenX = (Integer) startValues.values.get(PROPNAME_SCREEN_X);
+            int screenY = (Integer) startValues.values.get(PROPNAME_SCREEN_Y);
+            int[] loc = new int[2];
+            sceneRoot.getLocationOnScreen(loc);
+            ViewCompat.offsetLeftAndRight(overlayView, (screenX - loc[0]) - overlayView.getLeft());
+            ViewCompat.offsetTopAndBottom(overlayView, (screenY - loc[1]) - overlayView.getTop());
+            ViewGroupUtils.getOverlay(sceneRoot).add(overlayView);
+            // TODO: add automatic facility to Visibility superclass for keeping views around
+            final float startAlpha = 1;
+            float endAlpha = 0;
+            final View finalView = view;
+            final View finalOverlayView = overlayView;
+            final View finalViewToKeep = viewToKeep;
+            final ViewGroup finalSceneRoot = sceneRoot;
+            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    finalView.setAlpha(startAlpha);
+                    // TODO: restore view offset from overlay repositioning
+                    if (finalViewToKeep != null) {
+                        finalViewToKeep.setVisibility(finalVisibility);
+                    }
+                    if (finalOverlayView != null) {
+                        ViewGroupUtils.getOverlay(finalSceneRoot)
+                                .remove(finalOverlayView);
+                    }
+                }
+//
+//                @Override
+//                public void onAnimationPause(Animator animation) {
+//                    if (finalOverlayView != null) {
+//                        finalSceneRoot.getOverlay().remove(finalOverlayView);
+//                    }
+//                }
+//
+//                @Override
+//                public void onAnimationResume(Animator animation) {
+//                    if (finalOverlayView != null) {
+//                        finalSceneRoot.getOverlay().add(finalOverlayView);
+//                    }
+//                }
+            };
+            return createAnimation(view, startAlpha, endAlpha, endListener);
+        }
+        if (viewToKeep != null) {
+            // TODO: find a different way to do this, like just changing the view to be
+            // VISIBLE for the duration of the transition
+            viewToKeep.setVisibility((View.VISIBLE));
+            // TODO: add automatic facility to Visibility superclass for keeping views around
+            final float startAlpha = 1;
+            float endAlpha = 0;
+            final View finalView = view;
+            final View finalOverlayView = overlayView;
+            final View finalViewToKeep = viewToKeep;
+            final ViewGroup finalSceneRoot = sceneRoot;
+            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
+                boolean mCanceled = false;
+
+                float mPausedAlpha = -1;
+
+//                @Override
+//                public void onAnimationPause(Animator animation) {
+//                    if (finalViewToKeep != null && !mCanceled) {
+//                        finalViewToKeep.setVisibility(finalVisibility);
+//                    }
+//                    mPausedAlpha = finalView.getAlpha();
+//                    finalView.setAlpha(startAlpha);
+//                }
+//
+//                @Override
+//                public void onAnimationResume(Animator animation) {
+//                    if (finalViewToKeep != null && !mCanceled) {
+//                        finalViewToKeep.setVisibility(View.VISIBLE);
+//                    }
+//                    finalView.setAlpha(mPausedAlpha);
+//                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    mCanceled = true;
+                    if (mPausedAlpha >= 0) {
+                        finalView.setAlpha(mPausedAlpha);
+                    }
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (!mCanceled) {
+                        finalView.setAlpha(startAlpha);
+                    }
+                    // TODO: restore view offset from overlay repositioning
+                    if (finalViewToKeep != null && !mCanceled) {
+                        finalViewToKeep.setVisibility(finalVisibility);
+                    }
+                    if (finalOverlayView != null) {
+                        ViewGroupUtils.getOverlay(finalSceneRoot)
+                                .remove(finalOverlayView);
+                    }
+                }
+            };
+            return createAnimation(view, startAlpha, endAlpha, endListener);
+        }
+        return null;
     }
 
 }
diff --git a/transition/ics/android/support/transition/RectEvaluator.java b/transition/src/android/support/transition/RectEvaluator.java
similarity index 96%
rename from transition/ics/android/support/transition/RectEvaluator.java
rename to transition/src/android/support/transition/RectEvaluator.java
index c85ed18..1e757a5 100644
--- a/transition/ics/android/support/transition/RectEvaluator.java
+++ b/transition/src/android/support/transition/RectEvaluator.java
@@ -17,7 +17,6 @@
 package android.support.transition;
 
 import android.animation.TypeEvaluator;
-import android.annotation.TargetApi;
 import android.graphics.Rect;
 import android.support.annotation.RequiresApi;
 
@@ -25,7 +24,6 @@
  * This evaluator can be used to perform type interpolation between <code>Rect</code> values.
  */
 @RequiresApi(14)
-@TargetApi(14)
 class RectEvaluator implements TypeEvaluator<Rect> {
 
     /**
@@ -40,7 +38,7 @@
      * {@link RectEvaluator#RectEvaluator(android.graphics.Rect)} should be used
      * whenever possible.
      */
-    public RectEvaluator() {
+    RectEvaluator() {
     }
 
     /**
@@ -53,7 +51,7 @@
      *
      * @param reuseRect A Rect to be modified and returned by evaluate.
      */
-    public RectEvaluator(Rect reuseRect) {
+    RectEvaluator(Rect reuseRect) {
         mRect = reuseRect;
     }
 
diff --git a/transition/src/android/support/transition/Scene.java b/transition/src/android/support/transition/Scene.java
index 7684351..cc40b2c 100644
--- a/transition/src/android/support/transition/Scene.java
+++ b/transition/src/android/support/transition/Scene.java
@@ -17,11 +17,11 @@
 package android.support.transition;
 
 import android.content.Context;
-import android.os.Build;
 import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.util.SparseArray;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -34,53 +34,11 @@
  */
 public class Scene {
 
-    private static SceneStaticsImpl sImpl;
-
-    static {
-        if (Build.VERSION.SDK_INT >= 21) {
-            sImpl = new SceneStaticsApi21();
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            sImpl = new SceneStaticsKitKat();
-        } else {
-            sImpl = new SceneStaticsIcs();
-        }
-    }
-
-    /* package */ SceneImpl mImpl;
-
-    /**
-     * Constructs a Scene with no information about how values will change
-     * when this scene is applied. This constructor might be used when
-     * a Scene is created with the intention of being dynamically configured,
-     * through setting {@link #setEnterAction(Runnable)} and possibly
-     * {@link #setExitAction(Runnable)}.
-     *
-     * @param sceneRoot The root of the hierarchy in which scene changes
-     *                  and transitions will take place.
-     */
-    public Scene(@NonNull ViewGroup sceneRoot) {
-        mImpl = createSceneImpl();
-        mImpl.init(sceneRoot);
-    }
-
-    /**
-     * Constructs a Scene which, when entered, will remove any
-     * children from the sceneRoot container and add the layout
-     * object as a new child of that container.
-     *
-     * @param sceneRoot The root of the hierarchy in which scene changes
-     *                  and transitions will take place.
-     * @param layout    The view hierarchy of this scene, added as a child
-     *                  of sceneRoot when this scene is entered.
-     */
-    public Scene(@NonNull ViewGroup sceneRoot, @NonNull View layout) {
-        mImpl = createSceneImpl();
-        mImpl.init(sceneRoot, layout);
-    }
-
-    private Scene(SceneImpl scene) {
-        mImpl = scene;
-    }
+    private Context mContext;
+    private int mLayoutId = -1;
+    private ViewGroup mSceneRoot;
+    private View mLayout; // alternative to layoutId
+    private Runnable mEnterAction, mExitAction;
 
     /**
      * Returns a Scene described by the resource file associated with the given
@@ -111,20 +69,60 @@
         if (scene != null) {
             return scene;
         } else {
-            scene = new Scene(sImpl.getSceneForLayout(sceneRoot, layoutId, context));
+            scene = new Scene(sceneRoot, layoutId, context);
             scenes.put(layoutId, scene);
             return scene;
         }
     }
 
-    private SceneImpl createSceneImpl() {
-        if (Build.VERSION.SDK_INT >= 21) {
-            return new SceneApi21();
-        } else if (Build.VERSION.SDK_INT >= 19) {
-            return new SceneKitKat();
-        } else {
-            return new SceneIcs();
-        }
+    /**
+     * Constructs a Scene with no information about how values will change
+     * when this scene is applied. This constructor might be used when
+     * a Scene is created with the intention of being dynamically configured,
+     * through setting {@link #setEnterAction(Runnable)} and possibly
+     * {@link #setExitAction(Runnable)}.
+     *
+     * @param sceneRoot The root of the hierarchy in which scene changes
+     *                  and transitions will take place.
+     */
+    public Scene(@NonNull ViewGroup sceneRoot) {
+        mSceneRoot = sceneRoot;
+    }
+
+    /**
+     * Constructs a Scene which, when entered, will remove any
+     * children from the sceneRoot container and will inflate and add
+     * the hierarchy specified by the layoutId resource file.
+     *
+     * <p>This method is hidden because layoutId-based scenes should be
+     * created by the caching factory method {@link Scene#getCurrentScene(View)}.</p>
+     *
+     * @param sceneRoot The root of the hierarchy in which scene changes
+     *                  and transitions will take place.
+     * @param layoutId  The id of a resource file that defines the view
+     *                  hierarchy of this scene.
+     * @param context   The context used in the process of inflating
+     *                  the layout resource.
+     */
+    private Scene(ViewGroup sceneRoot, int layoutId, Context context) {
+        mContext = context;
+        mSceneRoot = sceneRoot;
+        mLayoutId = layoutId;
+    }
+
+    /**
+     * Constructs a Scene which, when entered, will remove any
+     * children from the sceneRoot container and add the layout
+     * object as a new child of that container.
+     *
+     * @param sceneRoot The root of the hierarchy in which scene changes
+     *                  and transitions will take place.
+     * @param layout    The view hierarchy of this scene, added as a child
+     *                  of sceneRoot when this scene is entered.
+     */
+    public Scene(@NonNull ViewGroup sceneRoot, @NonNull View layout) {
+        mSceneRoot = sceneRoot;
+        mLayout = layout;
     }
 
     /**
@@ -136,7 +134,7 @@
      */
     @NonNull
     public ViewGroup getSceneRoot() {
-        return mImpl.getSceneRoot();
+        return mSceneRoot;
     }
 
     /**
@@ -147,7 +145,11 @@
      * if there is one.
      */
     public void exit() {
-        mImpl.exit();
+        if (getCurrentScene(mSceneRoot) == this) {
+            if (mExitAction != null) {
+                mExitAction.run();
+            }
+        }
     }
 
     /**
@@ -161,7 +163,47 @@
      * use one of the methods in {@link android.support.transition.TransitionManager} instead.
      */
     public void enter() {
-        mImpl.enter();
+        // Apply layout change, if any
+        if (mLayoutId > 0 || mLayout != null) {
+            // empty out parent container before adding to it
+            getSceneRoot().removeAllViews();
+
+            if (mLayoutId > 0) {
+                LayoutInflater.from(mContext).inflate(mLayoutId, mSceneRoot);
+            } else {
+                mSceneRoot.addView(mLayout);
+            }
+        }
+
+        // Notify next scene that it is entering. Subclasses may override to configure scene.
+        if (mEnterAction != null) {
+            mEnterAction.run();
+        }
+
+        setCurrentScene(mSceneRoot, this);
+    }
+
+    /**
+     * Set the scene that the given view is in. The current scene is set only
+     * on the root view of a scene, not for every view in that hierarchy. This
+     * information is used by Scene to determine whether there is a previous
+     * scene which should be exited before the new scene is entered.
+     *
+     * @param view The view on which the current scene is being set
+     */
+    static void setCurrentScene(View view, Scene scene) {
+        view.setTag(R.id.transition_current_scene, scene);
+    }
+
+    /**
+     * Gets the current {@link Scene} set on the given view. A scene is set on a view
+     * only if that view is the scene root.
+     *
+     * @return The current Scene set on this view. A value of null indicates that
+     * no Scene is currently set.
+     */
+    static Scene getCurrentScene(View view) {
+        return (Scene) view.getTag(R.id.transition_current_scene);
     }
 
     /**
@@ -182,7 +224,7 @@
      * @see android.support.transition.Scene(android.view.ViewGroup, android.view.ViewGroup)
      */
     public void setEnterAction(@Nullable Runnable action) {
-        mImpl.setEnterAction(action);
+        mEnterAction = action;
     }
 
     /**
@@ -202,7 +244,16 @@
      * @see android.support.transition.Scene(android.view.ViewGroup, android.view.ViewGroup)
      */
     public void setExitAction(@Nullable Runnable action) {
-        mImpl.setExitAction(action);
+        mExitAction = action;
+    }
+
+    /**
+     * Returns whether this Scene was created by a layout resource file, determined
+     * by the layoutId passed into
+     * {@link #getSceneForLayout(ViewGroup, int, Context)}.
+     */
+    boolean isCreatedFromLayoutResource() {
+        return (mLayoutId > 0);
     }
 
 }
diff --git a/transition/src/android/support/transition/Transition.java b/transition/src/android/support/transition/Transition.java
index bab890e..02441ea 100644
--- a/transition/src/android/support/transition/Transition.java
+++ b/transition/src/android/support/transition/Transition.java
@@ -16,18 +16,31 @@
 
 package android.support.transition;
 
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.TimeInterpolator;
-import android.os.Build;
 import android.support.annotation.IdRes;
+import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.v4.util.ArrayMap;
+import android.support.v4.util.LongSparseArray;
+import android.support.v4.view.ViewCompat;
+import android.util.Log;
+import android.util.SparseArray;
 import android.view.SurfaceView;
 import android.view.TextureView;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.ListView;
 import android.widget.Spinner;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -54,9 +67,115 @@
  *
  * <p>Unlike the platform version, this does not support declaration by XML resources.</p>
  */
-public abstract class Transition implements TransitionInterface {
+public abstract class Transition implements Cloneable {
 
-    /* package */ TransitionImpl mImpl;
+    private static final String LOG_TAG = "Transition";
+    static final boolean DBG = false;
+
+    /**
+     * With {@link #setMatchOrder(int...)}, chooses to match by View instance.
+     */
+    public static final int MATCH_INSTANCE = 0x1;
+    private static final int MATCH_FIRST = MATCH_INSTANCE;
+
+    /**
+     * With {@link #setMatchOrder(int...)}, chooses to match by
+     * {@link android.view.View#getTransitionName()}. Null names will not be matched.
+     */
+    public static final int MATCH_NAME = 0x2;
+
+    /**
+     * With {@link #setMatchOrder(int...)}, chooses to match by
+     * {@link android.view.View#getId()}. Negative IDs will not be matched.
+     */
+    public static final int MATCH_ID = 0x3;
+
+    /**
+     * With {@link #setMatchOrder(int...)}, chooses to match by the {@link android.widget.Adapter}
+     * item id. When {@link android.widget.Adapter#hasStableIds()} returns false, no match
+     * will be made for items.
+     */
+    public static final int MATCH_ITEM_ID = 0x4;
+
+    private static final int MATCH_LAST = MATCH_ITEM_ID;
+
+    /** @hide */
+    @RestrictTo(LIBRARY_GROUP)
+    @IntDef({MATCH_INSTANCE, MATCH_NAME, MATCH_ID, MATCH_ITEM_ID})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MatchOrder {
+    }
+
+    private static final int[] DEFAULT_MATCH_ORDER = {
+            MATCH_NAME,
+            MATCH_INSTANCE,
+            MATCH_ID,
+            MATCH_ITEM_ID,
+    };
+
+    private String mName = getClass().getName();
+
+    private long mStartDelay = -1;
+    long mDuration = -1;
+    private TimeInterpolator mInterpolator = null;
+    ArrayList<Integer> mTargetIds = new ArrayList<>();
+    ArrayList<View> mTargets = new ArrayList<>();
+    private ArrayList<String> mTargetNames = null;
+    private ArrayList<Class> mTargetTypes = null;
+    private ArrayList<Integer> mTargetIdExcludes = null;
+    private ArrayList<View> mTargetExcludes = null;
+    private ArrayList<Class> mTargetTypeExcludes = null;
+    private ArrayList<String> mTargetNameExcludes = null;
+    private ArrayList<Integer> mTargetIdChildExcludes = null;
+    private ArrayList<View> mTargetChildExcludes = null;
+    private ArrayList<Class> mTargetTypeChildExcludes = null;
+    private TransitionValuesMaps mStartValues = new TransitionValuesMaps();
+    private TransitionValuesMaps mEndValues = new TransitionValuesMaps();
+    TransitionSet mParent = null;
+    private int[] mMatchOrder = DEFAULT_MATCH_ORDER;
+    private ArrayList<TransitionValues> mStartValuesList; // only valid after playTransition starts
+    private ArrayList<TransitionValues> mEndValuesList; // only valid after playTransitions starts
+
+    // Per-animator information used for later canceling when future transitions overlap
+    private static ThreadLocal<ArrayMap<Animator, Transition.AnimationInfo>> sRunningAnimators =
+            new ThreadLocal<>();
+
+    // Scene Root is set at createAnimator() time in the cloned Transition
+    private ViewGroup mSceneRoot = null;
+
+    // Whether removing views from their parent is possible. This is only for views
+    // in the start scene, which are no longer in the view hierarchy. This property
+    // is determined by whether the previous Scene was created from a layout
+    // resource, and thus the views from the exited scene are going away anyway
+    // and can be removed as necessary to achieve a particular effect, such as
+    // removing them from parents to add them to overlays.
+    boolean mCanRemoveViews = false;
+
+    // Track all animators in use in case the transition gets canceled and needs to
+    // cancel running animators
+    private ArrayList<Animator> mCurrentAnimators = new ArrayList<>();
+
+    // Number of per-target instances of this Transition currently running. This count is
+    // determined by calls to start() and end()
+    private int mNumInstances = 0;
+
+    // Whether this transition is currently paused, due to a call to pause()
+    private boolean mPaused = false;
+
+    // Whether this transition has ended. Used to avoid pause/resume on transitions
+    // that have completed
+    private boolean mEnded = false;
+
+    // The set of listeners to be sent transition lifecycle events.
+    private ArrayList<Transition.TransitionListener> mListeners = null;
+
+    // The set of animators collected from calls to createAnimator(),
+    // to be run in runAnimators()
+    private ArrayList<Animator> mAnimators = new ArrayList<>();
+
+    // For Fragment shared element transitions, linking views explicitly by mismatching
+    // transitionNames.
+    private ArrayMap<String, String> mNameOverrides;
 
     /**
      * Constructs a Transition object with no target objects. A transition with
@@ -65,152 +184,115 @@
      * objects passed down from its parent (if it is in a TransitionSet).
      */
     public Transition() {
-        this(false);
-    }
-
-    // Hidden constructor for built-in transitions
-    Transition(boolean deferred) {
-        if (!deferred) {
-            if (Build.VERSION.SDK_INT >= 23) {
-                mImpl = new TransitionApi23();
-            } else if (Build.VERSION.SDK_INT >= 19) {
-                mImpl = new TransitionKitKat();
-            } else {
-                mImpl = new TransitionIcs();
-            }
-            mImpl.init(this);
-        }
     }
 
     /**
-     * Adds a listener to the set of listeners that are sent events through the
-     * life of an animation, such as start, repeat, and end.
+     * Sets the duration of this transition. By default, there is no duration
+     * (indicated by a negative number), which means that the Animator created by
+     * the transition will have its own specified duration. If the duration of a
+     * Transition is set, that duration will override the Animator duration.
      *
-     * @param listener the listener to be added to the current set of listeners
-     *                 for this animation.
+     * @param duration The length of the animation, in milliseconds.
      * @return This transition object.
      */
     @NonNull
-    public Transition addListener(@NonNull TransitionListener listener) {
-        mImpl.addListener(listener);
+    public Transition setDuration(long duration) {
+        mDuration = duration;
         return this;
     }
 
     /**
-     * Sets the target view instances that this Transition is interested in
-     * animating. By default, there are no targets, and a Transition will
-     * listen for changes on every view in the hierarchy below the sceneRoot
-     * of the Scene being transitioned into. Setting targets constrains
-     * the Transition to only listen for, and act on, these views.
-     * All other views will be ignored.
+     * Returns the duration set on this transition. If no duration has been set,
+     * the returned value will be negative, indicating that resulting animators will
+     * retain their own durations.
      *
-     * <p>The target list is like the {@link #addTarget(int) targetId}
-     * list except this list specifies the actual View instances, not the ids
-     * of the views. This is an important distinction when scene changes involve
-     * view hierarchies which have been inflated separately; different views may
-     * share the same id but not actually be the same instance. If the transition
-     * should treat those views as the same, then {@link #addTarget(int)} should be used
-     * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve
-     * changes all within the same view hierarchy, among views which do not
-     * necessarily have ids set on them, then the target list of views may be more
-     * convenient.</p>
+     * @return The duration set on this transition, in milliseconds, if one has been
+     * set, otherwise returns a negative number.
+     */
+    public long getDuration() {
+        return mDuration;
+    }
+
+    /**
+     * Sets the startDelay of this transition. By default, there is no delay
+     * (indicated by a negative number), which means that the Animator created by
+     * the transition will have its own specified startDelay. If the delay of a
+     * Transition is set, that delay will override the Animator delay.
      *
-     * @param target A View on which the Transition will act, must be non-null.
-     * @return The Transition to which the target is added.
-     * Returning the same object makes it easier to chain calls during
-     * construction, such as
-     * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code>
-     * @see #addTarget(int)
+     * @param startDelay The length of the delay, in milliseconds.
+     * @return This transition object.
      */
     @NonNull
-    public Transition addTarget(@NonNull View target) {
-        mImpl.addTarget(target);
+    public Transition setStartDelay(long startDelay) {
+        mStartDelay = startDelay;
         return this;
     }
 
     /**
-     * Adds the id of a target view that this Transition is interested in
-     * animating. By default, there are no targetIds, and a Transition will
-     * listen for changes on every view in the hierarchy below the sceneRoot
-     * of the Scene being transitioned into. Setting targetIds constrains
-     * the Transition to only listen for, and act on, views with these IDs.
-     * Views with different IDs, or no IDs whatsoever, will be ignored.
+     * Returns the startDelay set on this transition. If no startDelay has been set,
+     * the returned value will be negative, indicating that resulting animators will
+     * retain their own startDelays.
      *
-     * <p>Note that using ids to specify targets implies that ids should be unique
-     * within the view hierarchy underneath the scene root.</p>
+     * @return The startDelay set on this transition, in milliseconds, if one has
+     * been set, otherwise returns a negative number.
+     */
+    public long getStartDelay() {
+        return mStartDelay;
+    }
+
+    /**
+     * Sets the interpolator of this transition. By default, the interpolator
+     * is null, which means that the Animator created by the transition
+     * will have its own specified interpolator. If the interpolator of a
+     * Transition is set, that interpolator will override the Animator interpolator.
      *
-     * @param targetId The id of a target view, must be a positive number.
-     * @return The Transition to which the targetId is added.
-     * Returning the same object makes it easier to chain calls during
-     * construction, such as
-     * <code>transitionSet.addTransitions(new Fade()).addTarget(someId);</code>
-     * @see View#getId()
+     * @param interpolator The time interpolator used by the transition
+     * @return This transition object.
      */
     @NonNull
-    public Transition addTarget(@IdRes int targetId) {
-        mImpl.addTarget(targetId);
+    public Transition setInterpolator(@Nullable TimeInterpolator interpolator) {
+        mInterpolator = interpolator;
         return this;
     }
 
     /**
-     * Captures the values in the end scene for the properties that this
-     * transition monitors. These values are then passed as the endValues
-     * structure in a later call to
-     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
-     * The main concern for an implementation is what the
-     * properties are that the transition cares about and what the values are
-     * for all of those properties. The start and end values will be compared
-     * later during the
-     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}
-     * method to determine what, if any, animations, should be run.
+     * Returns the interpolator set on this transition. If no interpolator has been set,
+     * the returned value will be null, indicating that resulting animators will
+     * retain their own interpolators.
      *
-     * <p>Subclasses must implement this method. The method should only be called by the
-     * transition system; it is not intended to be called from external classes.</p>
-     *
-     * @param transitionValues The holder for any values that the Transition
-     *                         wishes to store. Values are stored in the <code>values</code> field
-     *                         of this TransitionValues object and are keyed from
-     *                         a String value. For example, to store a view's rotation value,
-     *                         a transition might call
-     *                         <code>transitionValues.values.put("appname:transitionname:rotation",
-     *                         view.getRotation())</code>. The target view will already be stored
-     *                         in
-     *                         the transitionValues structure when this method is called.
-     * @see #captureStartValues(TransitionValues)
-     * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
+     * @return The interpolator set on this transition, if one has been set, otherwise
+     * returns null.
      */
-    @Override
-    public abstract void captureEndValues(@NonNull TransitionValues transitionValues);
+    @Nullable
+    public TimeInterpolator getInterpolator() {
+        return mInterpolator;
+    }
 
     /**
-     * Captures the values in the start scene for the properties that this
-     * transition monitors. These values are then passed as the startValues
-     * structure in a later call to
-     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
-     * The main concern for an implementation is what the
-     * properties are that the transition cares about and what the values are
-     * for all of those properties. The start and end values will be compared
-     * later during the
-     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}
-     * method to determine what, if any, animations, should be run.
+     * Returns the set of property names used stored in the {@link TransitionValues}
+     * object passed into {@link #captureStartValues(TransitionValues)} that
+     * this transition cares about for the purposes of canceling overlapping animations.
+     * When any transition is started on a given scene root, all transitions
+     * currently running on that same scene root are checked to see whether the
+     * properties on which they based their animations agree with the end values of
+     * the same properties in the new transition. If the end values are not equal,
+     * then the old animation is canceled since the new transition will start a new
+     * animation to these new values. If the values are equal, the old animation is
+     * allowed to continue and no new animation is started for that transition.
      *
-     * <p>Subclasses must implement this method. The method should only be called by the
-     * transition system; it is not intended to be called from external classes.</p>
+     * <p>A transition does not need to override this method. However, not doing so
+     * will mean that the cancellation logic outlined in the previous paragraph
+     * will be skipped for that transition, possibly leading to artifacts as
+     * old transitions and new transitions on the same targets run in parallel,
+     * animating views toward potentially different end values.</p>
      *
-     * @param transitionValues The holder for any values that the Transition
-     *                         wishes to store. Values are stored in the <code>values</code> field
-     *                         of this TransitionValues object and are keyed from
-     *                         a String value. For example, to store a view's rotation value,
-     *                         a transition might call
-     *                         <code>transitionValues.values.put("appname:transitionname:rotation",
-     *                         view.getRotation())</code>. The target view will already be stored
-     *                         in
-     *                         the transitionValues structure when this method is called.
-     * @see #captureEndValues(TransitionValues)
-     * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
+     * @return An array of property names as described in the class documentation for
+     * {@link TransitionValues}. The default implementation returns <code>null</code>.
      */
-    @Override
-    public abstract void captureStartValues(@NonNull TransitionValues transitionValues);
+    @Nullable
+    public String[] getTransitionProperties() {
+        return null;
+    }
 
     /**
      * This method creates an animation that will be run for this transition
@@ -257,7 +339,6 @@
      * overall transition for this scene change. A null value means no animation
      * should be run.
      */
-    @Override
     @Nullable
     public Animator createAnimator(@NonNull ViewGroup sceneRoot,
             @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) {
@@ -265,6 +346,750 @@
     }
 
     /**
+     * Sets the order in which Transition matches View start and end values.
+     * <p>
+     * The default behavior is to match first by {@link android.view.View#getTransitionName()},
+     * then by View instance, then by {@link android.view.View#getId()} and finally
+     * by its item ID if it is in a direct child of ListView. The caller can
+     * choose to have only some or all of the values of {@link #MATCH_INSTANCE},
+     * {@link #MATCH_NAME}, {@link #MATCH_ITEM_ID}, and {@link #MATCH_ID}. Only
+     * the match algorithms supplied will be used to determine whether Views are the
+     * the same in both the start and end Scene. Views that do not match will be considered
+     * as entering or leaving the Scene.
+     * </p>
+     *
+     * @param matches A list of zero or more of {@link #MATCH_INSTANCE},
+     *                {@link #MATCH_NAME}, {@link #MATCH_ITEM_ID}, and {@link #MATCH_ID}.
+     *                If none are provided, then the default match order will be set.
+     */
+    public void setMatchOrder(@MatchOrder int... matches) {
+        if (matches == null || matches.length == 0) {
+            mMatchOrder = DEFAULT_MATCH_ORDER;
+        } else {
+            for (int i = 0; i < matches.length; i++) {
+                int match = matches[i];
+                if (!isValidMatch(match)) {
+                    throw new IllegalArgumentException("matches contains invalid value");
+                }
+                if (alreadyContains(matches, i)) {
+                    throw new IllegalArgumentException("matches contains a duplicate value");
+                }
+            }
+            mMatchOrder = matches.clone();
+        }
+    }
+
+    private static boolean isValidMatch(int match) {
+        return (match >= MATCH_FIRST && match <= MATCH_LAST);
+    }
+
+    private static boolean alreadyContains(int[] array, int searchIndex) {
+        int value = array[searchIndex];
+        for (int i = 0; i < searchIndex; i++) {
+            if (array[i] == value) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Match start/end values by View instance. Adds matched values to mStartValuesList
+     * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd.
+     */
+    private void matchInstances(ArrayMap<View, TransitionValues> unmatchedStart,
+            ArrayMap<View, TransitionValues> unmatchedEnd) {
+        for (int i = unmatchedStart.size() - 1; i >= 0; i--) {
+            View view = unmatchedStart.keyAt(i);
+            if (view != null && isValidTarget(view)) {
+                TransitionValues end = unmatchedEnd.remove(view);
+                if (end != null && end.view != null && isValidTarget(end.view)) {
+                    TransitionValues start = unmatchedStart.removeAt(i);
+                    mStartValuesList.add(start);
+                    mEndValuesList.add(end);
+                }
+            }
+        }
+    }
+
+    /**
+     * Match start/end values by Adapter item ID. Adds matched values to mStartValuesList
+     * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using
+     * startItemIds and endItemIds as a guide for which Views have unique item IDs.
+     */
+    private void matchItemIds(ArrayMap<View, TransitionValues> unmatchedStart,
+            ArrayMap<View, TransitionValues> unmatchedEnd,
+            LongSparseArray<View> startItemIds, LongSparseArray<View> endItemIds) {
+        int numStartIds = startItemIds.size();
+        for (int i = 0; i < numStartIds; i++) {
+            View startView = startItemIds.valueAt(i);
+            if (startView != null && isValidTarget(startView)) {
+                View endView = endItemIds.get(startItemIds.keyAt(i));
+                if (endView != null && isValidTarget(endView)) {
+                    TransitionValues startValues = unmatchedStart.get(startView);
+                    TransitionValues endValues = unmatchedEnd.get(endView);
+                    if (startValues != null && endValues != null) {
+                        mStartValuesList.add(startValues);
+                        mEndValuesList.add(endValues);
+                        unmatchedStart.remove(startView);
+                        unmatchedEnd.remove(endView);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Match start/end values by Adapter view ID. Adds matched values to mStartValuesList
+     * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using
+     * startIds and endIds as a guide for which Views have unique IDs.
+     */
+    private void matchIds(ArrayMap<View, TransitionValues> unmatchedStart,
+            ArrayMap<View, TransitionValues> unmatchedEnd,
+            SparseArray<View> startIds, SparseArray<View> endIds) {
+        int numStartIds = startIds.size();
+        for (int i = 0; i < numStartIds; i++) {
+            View startView = startIds.valueAt(i);
+            if (startView != null && isValidTarget(startView)) {
+                View endView = endIds.get(startIds.keyAt(i));
+                if (endView != null && isValidTarget(endView)) {
+                    TransitionValues startValues = unmatchedStart.get(startView);
+                    TransitionValues endValues = unmatchedEnd.get(endView);
+                    if (startValues != null && endValues != null) {
+                        mStartValuesList.add(startValues);
+                        mEndValuesList.add(endValues);
+                        unmatchedStart.remove(startView);
+                        unmatchedEnd.remove(endView);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Match start/end values by Adapter transitionName. Adds matched values to mStartValuesList
+     * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using
+     * startNames and endNames as a guide for which Views have unique transitionNames.
+     */
+    private void matchNames(ArrayMap<View, TransitionValues> unmatchedStart,
+            ArrayMap<View, TransitionValues> unmatchedEnd,
+            ArrayMap<String, View> startNames, ArrayMap<String, View> endNames) {
+        int numStartNames = startNames.size();
+        for (int i = 0; i < numStartNames; i++) {
+            View startView = startNames.valueAt(i);
+            if (startView != null && isValidTarget(startView)) {
+                View endView = endNames.get(startNames.keyAt(i));
+                if (endView != null && isValidTarget(endView)) {
+                    TransitionValues startValues = unmatchedStart.get(startView);
+                    TransitionValues endValues = unmatchedEnd.get(endView);
+                    if (startValues != null && endValues != null) {
+                        mStartValuesList.add(startValues);
+                        mEndValuesList.add(endValues);
+                        unmatchedStart.remove(startView);
+                        unmatchedEnd.remove(endView);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds all values from unmatchedStart and unmatchedEnd to mStartValuesList and mEndValuesList,
+     * assuming that there is no match between values in the list.
+     */
+    private void addUnmatched(ArrayMap<View, TransitionValues> unmatchedStart,
+            ArrayMap<View, TransitionValues> unmatchedEnd) {
+        // Views that only exist in the start Scene
+        for (int i = 0; i < unmatchedStart.size(); i++) {
+            final TransitionValues start = unmatchedStart.valueAt(i);
+            if (isValidTarget(start.view)) {
+                mStartValuesList.add(start);
+                mEndValuesList.add(null);
+            }
+        }
+
+        // Views that only exist in the end Scene
+        for (int i = 0; i < unmatchedEnd.size(); i++) {
+            final TransitionValues end = unmatchedEnd.valueAt(i);
+            if (isValidTarget(end.view)) {
+                mEndValuesList.add(end);
+                mStartValuesList.add(null);
+            }
+        }
+    }
+
+    private void matchStartAndEnd(TransitionValuesMaps startValues,
+            TransitionValuesMaps endValues) {
+        ArrayMap<View, TransitionValues> unmatchedStart = new ArrayMap<>(startValues.mViewValues);
+        ArrayMap<View, TransitionValues> unmatchedEnd = new ArrayMap<>(endValues.mViewValues);
+
+        for (int i = 0; i < mMatchOrder.length; i++) {
+            switch (mMatchOrder[i]) {
+                case MATCH_INSTANCE:
+                    matchInstances(unmatchedStart, unmatchedEnd);
+                    break;
+                case MATCH_NAME:
+                    matchNames(unmatchedStart, unmatchedEnd,
+                            startValues.mNameValues, endValues.mNameValues);
+                    break;
+                case MATCH_ID:
+                    matchIds(unmatchedStart, unmatchedEnd,
+                            startValues.mIdValues, endValues.mIdValues);
+                    break;
+                case MATCH_ITEM_ID:
+                    matchItemIds(unmatchedStart, unmatchedEnd,
+                            startValues.mItemIdValues, endValues.mItemIdValues);
+                    break;
+            }
+        }
+        addUnmatched(unmatchedStart, unmatchedEnd);
+    }
+
+    /**
+     * This method, essentially a wrapper around all calls to createAnimator for all
+     * possible target views, is called with the entire set of start/end
+     * values. The implementation in Transition iterates through these lists
+     * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}
+     * with each set of start/end values on this transition. The
+     * TransitionSet subclass overrides this method and delegates it to
+     * each of its children in succession.
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+            TransitionValuesMaps endValues, ArrayList<TransitionValues> startValuesList,
+            ArrayList<TransitionValues> endValuesList) {
+        if (DBG) {
+            Log.d(LOG_TAG, "createAnimators() for " + this);
+        }
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        int startValuesListCount = startValuesList.size();
+        for (int i = 0; i < startValuesListCount; ++i) {
+            TransitionValues start = startValuesList.get(i);
+            TransitionValues end = endValuesList.get(i);
+            if (start != null && !start.mTargetedTransitions.contains(this)) {
+                start = null;
+            }
+            if (end != null && !end.mTargetedTransitions.contains(this)) {
+                end = null;
+            }
+            if (start == null && end == null) {
+                continue;
+            }
+            // Only bother trying to animate with values that differ between start/end
+            boolean isChanged = start == null || end == null || areValuesChanged(start, end);
+            if (isChanged) {
+                if (DBG) {
+                    View view = (end != null) ? end.view : start.view;
+                    Log.d(LOG_TAG, "  differing start/end values for view " + view);
+                    if (start == null || end == null) {
+                        Log.d(LOG_TAG, "    " + ((start == null)
+                                ? "start null, end non-null" : "start non-null, end null"));
+                    } else {
+                        for (String key : start.values.keySet()) {
+                            Object startValue = start.values.get(key);
+                            Object endValue = end.values.get(key);
+                            if (startValue != endValue && !startValue.equals(endValue)) {
+                                Log.d(LOG_TAG, "    " + key + ": start(" + startValue
+                                        + "), end(" + endValue + ")");
+                            }
+                        }
+                    }
+                }
+                // TODO: what to do about targetIds and itemIds?
+                Animator animator = createAnimator(sceneRoot, start, end);
+                if (animator != null) {
+                    // Save animation info for future cancellation purposes
+                    View view;
+                    TransitionValues infoValues = null;
+                    if (end != null) {
+                        view = end.view;
+                        String[] properties = getTransitionProperties();
+                        if (view != null && properties != null && properties.length > 0) {
+                            infoValues = new TransitionValues();
+                            infoValues.view = view;
+                            TransitionValues newValues = endValues.mViewValues.get(view);
+                            if (newValues != null) {
+                                for (int j = 0; j < properties.length; ++j) {
+                                    infoValues.values.put(properties[j],
+                                            newValues.values.get(properties[j]));
+                                }
+                            }
+                            int numExistingAnims = runningAnimators.size();
+                            for (int j = 0; j < numExistingAnims; ++j) {
+                                Animator anim = runningAnimators.keyAt(j);
+                                AnimationInfo info = runningAnimators.get(anim);
+                                if (info.mValues != null && info.mView == view
+                                        && info.mName.equals(getName())) {
+                                    if (info.mValues.equals(infoValues)) {
+                                        // Favor the old animator
+                                        animator = null;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                    } else {
+                        view = start.view;
+                    }
+                    if (animator != null) {
+                        AnimationInfo info = new AnimationInfo(view, getName(), this,
+                                ViewUtils.getWindowId(sceneRoot), infoValues);
+                        runningAnimators.put(animator, info);
+                        mAnimators.add(animator);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Internal utility method for checking whether a given view/id
+     * is valid for this transition, where "valid" means that either
+     * the Transition has no target/targetId list (the default, in which
+     * cause the transition should act on all views in the hiearchy), or
+     * the given view is in the target list or the view id is in the
+     * targetId list. If the target parameter is null, then the target list
+     * is not checked (this is in the case of ListView items, where the
+     * views are ignored and only the ids are used).
+     */
+    boolean isValidTarget(View target) {
+        int targetId = target.getId();
+        if (mTargetIdExcludes != null && mTargetIdExcludes.contains(targetId)) {
+            return false;
+        }
+        if (mTargetExcludes != null && mTargetExcludes.contains(target)) {
+            return false;
+        }
+        if (mTargetTypeExcludes != null) {
+            int numTypes = mTargetTypeExcludes.size();
+            for (int i = 0; i < numTypes; ++i) {
+                Class type = mTargetTypeExcludes.get(i);
+                if (type.isInstance(target)) {
+                    return false;
+                }
+            }
+        }
+        if (mTargetNameExcludes != null && ViewCompat.getTransitionName(target) != null) {
+            if (mTargetNameExcludes.contains(ViewCompat.getTransitionName(target))) {
+                return false;
+            }
+        }
+        if (mTargetIds.size() == 0 && mTargets.size() == 0
+                && (mTargetTypes == null || mTargetTypes.isEmpty())
+                && (mTargetNames == null || mTargetNames.isEmpty())) {
+            return true;
+        }
+        if (mTargetIds.contains(targetId) || mTargets.contains(target)) {
+            return true;
+        }
+        if (mTargetNames != null && mTargetNames.contains(ViewCompat.getTransitionName(target))) {
+            return true;
+        }
+        if (mTargetTypes != null) {
+            for (int i = 0; i < mTargetTypes.size(); ++i) {
+                if (mTargetTypes.get(i).isInstance(target)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
+        ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get();
+        if (runningAnimators == null) {
+            runningAnimators = new ArrayMap<>();
+            sRunningAnimators.set(runningAnimators);
+        }
+        return runningAnimators;
+    }
+
+    /**
+     * This is called internally once all animations have been set up by the
+     * transition hierarchy. \
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    protected void runAnimators() {
+        if (DBG) {
+            Log.d(LOG_TAG, "runAnimators() on " + this);
+        }
+        start();
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        // Now start every Animator that was previously created for this transition
+        for (Animator anim : mAnimators) {
+            if (DBG) {
+                Log.d(LOG_TAG, "  anim: " + anim);
+            }
+            if (runningAnimators.containsKey(anim)) {
+                start();
+                runAnimator(anim, runningAnimators);
+            }
+        }
+        mAnimators.clear();
+        end();
+    }
+
+    private void runAnimator(Animator animator,
+            final ArrayMap<Animator, AnimationInfo> runningAnimators) {
+        if (animator != null) {
+            // TODO: could be a single listener instance for all of them since it uses the param
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    mCurrentAnimators.add(animation);
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    runningAnimators.remove(animation);
+                    mCurrentAnimators.remove(animation);
+                }
+            });
+            animate(animator);
+        }
+    }
+
+    /**
+     * Captures the values in the start scene for the properties that this
+     * transition monitors. These values are then passed as the startValues
+     * structure in a later call to
+     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
+     * The main concern for an implementation is what the
+     * properties are that the transition cares about and what the values are
+     * for all of those properties. The start and end values will be compared
+     * later during the
+     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}
+     * method to determine what, if any, animations, should be run.
+     *
+     * <p>Subclasses must implement this method. The method should only be called by the
+     * transition system; it is not intended to be called from external classes.</p>
+     *
+     * @param transitionValues The holder for any values that the Transition
+     *                         wishes to store. Values are stored in the <code>values</code> field
+     *                         of this TransitionValues object and are keyed from
+     *                         a String value. For example, to store a view's rotation value,
+     *                         a transition might call
+     *                         <code>transitionValues.values.put("appname:transitionname:rotation",
+     *                         view.getRotation())</code>. The target view will already be stored
+     *                         in
+     *                         the transitionValues structure when this method is called.
+     * @see #captureEndValues(TransitionValues)
+     * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
+     */
+    public abstract void captureStartValues(@NonNull TransitionValues transitionValues);
+
+    /**
+     * Captures the values in the end scene for the properties that this
+     * transition monitors. These values are then passed as the endValues
+     * structure in a later call to
+     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
+     * The main concern for an implementation is what the
+     * properties are that the transition cares about and what the values are
+     * for all of those properties. The start and end values will be compared
+     * later during the
+     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}
+     * method to determine what, if any, animations, should be run.
+     *
+     * <p>Subclasses must implement this method. The method should only be called by the
+     * transition system; it is not intended to be called from external classes.</p>
+     *
+     * @param transitionValues The holder for any values that the Transition
+     *                         wishes to store. Values are stored in the <code>values</code> field
+     *                         of this TransitionValues object and are keyed from
+     *                         a String value. For example, to store a view's rotation value,
+     *                         a transition might call
+     *                         <code>transitionValues.values.put("appname:transitionname:rotation",
+     *                         view.getRotation())</code>. The target view will already be stored
+     *                         in
+     *                         the transitionValues structure when this method is called.
+     * @see #captureStartValues(TransitionValues)
+     * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
+     */
+    public abstract void captureEndValues(@NonNull TransitionValues transitionValues);
+
+    /**
+     * Sets the target view instances that this Transition is interested in
+     * animating. By default, there are no targets, and a Transition will
+     * listen for changes on every view in the hierarchy below the sceneRoot
+     * of the Scene being transitioned into. Setting targets constrains
+     * the Transition to only listen for, and act on, these views.
+     * All other views will be ignored.
+     *
+     * <p>The target list is like the {@link #addTarget(int) targetId}
+     * list except this list specifies the actual View instances, not the ids
+     * of the views. This is an important distinction when scene changes involve
+     * view hierarchies which have been inflated separately; different views may
+     * share the same id but not actually be the same instance. If the transition
+     * should treat those views as the same, then {@link #addTarget(int)} should be used
+     * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve
+     * changes all within the same view hierarchy, among views which do not
+     * necessarily have ids set on them, then the target list of views may be more
+     * convenient.</p>
+     *
+     * @param target A View on which the Transition will act, must be non-null.
+     * @return The Transition to which the target is added.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code>
+     * @see #addTarget(int)
+     */
+    @NonNull
+    public Transition addTarget(@NonNull View target) {
+        mTargets.add(target);
+        return this;
+    }
+
+    /**
+     * Adds the id of a target view that this Transition is interested in
+     * animating. By default, there are no targetIds, and a Transition will
+     * listen for changes on every view in the hierarchy below the sceneRoot
+     * of the Scene being transitioned into. Setting targetIds constrains
+     * the Transition to only listen for, and act on, views with these IDs.
+     * Views with different IDs, or no IDs whatsoever, will be ignored.
+     *
+     * <p>Note that using ids to specify targets implies that ids should be unique
+     * within the view hierarchy underneath the scene root.</p>
+     *
+     * @param targetId The id of a target view, must be a positive number.
+     * @return The Transition to which the targetId is added.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).addTarget(someId);</code>
+     * @see View#getId()
+     */
+    @NonNull
+    public Transition addTarget(@IdRes int targetId) {
+        if (targetId > 0) {
+            mTargetIds.add(targetId);
+        }
+        return this;
+    }
+
+    /**
+     * Adds the transitionName of a target view that this Transition is interested in
+     * animating. By default, there are no targetNames, and a Transition will
+     * listen for changes on every view in the hierarchy below the sceneRoot
+     * of the Scene being transitioned into. Setting targetNames constrains
+     * the Transition to only listen for, and act on, views with these transitionNames.
+     * Views with different transitionNames, or no transitionName whatsoever, will be ignored.
+     *
+     * <p>Note that transitionNames should be unique within the view hierarchy.</p>
+     *
+     * @param targetName The transitionName of a target view, must be non-null.
+     * @return The Transition to which the target transitionName is added.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).addTarget(someName);</code>
+     * @see ViewCompat#getTransitionName(View)
+     */
+    @NonNull
+    public Transition addTarget(@NonNull String targetName) {
+        if (mTargetNames == null) {
+            mTargetNames = new ArrayList<>();
+        }
+        mTargetNames.add(targetName);
+        return this;
+    }
+
+    /**
+     * Adds the Class of a target view that this Transition is interested in
+     * animating. By default, there are no targetTypes, and a Transition will
+     * listen for changes on every view in the hierarchy below the sceneRoot
+     * of the Scene being transitioned into. Setting targetTypes constrains
+     * the Transition to only listen for, and act on, views with these classes.
+     * Views with different classes will be ignored.
+     *
+     * <p>Note that any View that can be cast to targetType will be included, so
+     * if targetType is <code>View.class</code>, all Views will be included.</p>
+     *
+     * @param targetType The type to include when running this transition.
+     * @return The Transition to which the target class was added.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).addTarget(ImageView.class);</code>
+     * @see #addTarget(int)
+     * @see #addTarget(android.view.View)
+     * @see #excludeTarget(Class, boolean)
+     * @see #excludeChildren(Class, boolean)
+     */
+    @NonNull
+    public Transition addTarget(@NonNull Class targetType) {
+        if (mTargetTypes == null) {
+            mTargetTypes = new ArrayList<>();
+        }
+        mTargetTypes.add(targetType);
+        return this;
+    }
+
+    /**
+     * Removes the given target from the list of targets that this Transition
+     * is interested in animating.
+     *
+     * @param target The target view, must be non-null.
+     * @return Transition The Transition from which the target is removed.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code>
+     */
+    @NonNull
+    public Transition removeTarget(@NonNull View target) {
+        mTargets.remove(target);
+        return this;
+    }
+
+    /**
+     * Removes the given targetId from the list of ids that this Transition
+     * is interested in animating.
+     *
+     * @param targetId The id of a target view, must be a positive number.
+     * @return The Transition from which the targetId is removed.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code>
+     */
+    @NonNull
+    public Transition removeTarget(@IdRes int targetId) {
+        if (targetId > 0) {
+            mTargetIds.remove((Integer) targetId);
+        }
+        return this;
+    }
+
+    /**
+     * Removes the given targetName from the list of transitionNames that this Transition
+     * is interested in animating.
+     *
+     * @param targetName The transitionName of a target view, must not be null.
+     * @return The Transition from which the targetName is removed.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).removeTargetName(someName);</code>
+     */
+    @NonNull
+    public Transition removeTarget(@NonNull String targetName) {
+        if (mTargetNames != null) {
+            mTargetNames.remove(targetName);
+        }
+        return this;
+    }
+
+    /**
+     * Removes the given target from the list of targets that this Transition
+     * is interested in animating.
+     *
+     * @param target The type of the target view, must be non-null.
+     * @return Transition The Transition from which the target is removed.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).removeTarget(someType);</code>
+     */
+    @NonNull
+    public Transition removeTarget(@NonNull Class target) {
+        if (mTargetTypes != null) {
+            mTargetTypes.remove(target);
+        }
+        return this;
+    }
+
+    /**
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private static <T> ArrayList<T> excludeObject(ArrayList<T> list, T target, boolean exclude) {
+        if (target != null) {
+            if (exclude) {
+                list = ArrayListManager.add(list, target);
+            } else {
+                list = ArrayListManager.remove(list, target);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Whether to add the given target to the list of targets to exclude from this
+     * transition. The <code>exclude</code> parameter specifies whether the target
+     * should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @param target  The target to ignore when running this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     *                current list of excluded targets.
+     * @return This transition object.
+     * @see #excludeChildren(View, boolean)
+     * @see #excludeTarget(int, boolean)
+     * @see #excludeTarget(Class, boolean)
+     */
+    @NonNull
+    public Transition excludeTarget(@NonNull View target, boolean exclude) {
+        mTargetExcludes = excludeView(mTargetExcludes, target, exclude);
+        return this;
+    }
+
+    /**
+     * Whether to add the given id to the list of target ids to exclude from this
+     * transition. The <code>exclude</code> parameter specifies whether the target
+     * should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @param targetId The id of a target to ignore when running this transition.
+     * @param exclude  Whether to add the target to or remove the target from the
+     *                 current list of excluded targets.
+     * @return This transition object.
+     * @see #excludeChildren(int, boolean)
+     * @see #excludeTarget(View, boolean)
+     * @see #excludeTarget(Class, boolean)
+     */
+    @NonNull
+    public Transition excludeTarget(@IdRes int targetId, boolean exclude) {
+        mTargetIdExcludes = excludeId(mTargetIdExcludes, targetId, exclude);
+        return this;
+    }
+
+    /**
+     * Whether to add the given transitionName to the list of target transitionNames to exclude
+     * from this transition. The <code>exclude</code> parameter specifies whether the target
+     * should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded by their
+     * id, their instance reference, their transitionName, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeTarget(View, boolean)
+     * @see #excludeTarget(int, boolean)
+     * @see #excludeTarget(Class, boolean)
+     *
+     * @param targetName The name of a target to ignore when running this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     * current list of excluded targets.
+     * @return This transition object.
+     */
+    @NonNull
+    public Transition excludeTarget(@NonNull String targetName, boolean exclude) {
+        mTargetNameExcludes = excludeObject(mTargetNameExcludes, targetName, exclude);
+        return this;
+    }
+
+    /**
      * Whether to add the children of given target to the list of target children
      * to exclude from this transition. The <code>exclude</code> parameter specifies
      * whether the target should be added to or removed from the excluded list.
@@ -286,7 +1111,7 @@
      */
     @NonNull
     public Transition excludeChildren(@NonNull View target, boolean exclude) {
-        mImpl.excludeChildren(target, exclude);
+        mTargetChildExcludes = excludeView(mTargetChildExcludes, target, exclude);
         return this;
     }
 
@@ -316,7 +1141,63 @@
      */
     @NonNull
     public Transition excludeChildren(@IdRes int targetId, boolean exclude) {
-        mImpl.excludeChildren(targetId, exclude);
+        mTargetIdChildExcludes = excludeId(mTargetIdChildExcludes, targetId, exclude);
+        return this;
+    }
+
+    /**
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private ArrayList<Integer> excludeId(ArrayList<Integer> list, int targetId, boolean exclude) {
+        if (targetId > 0) {
+            if (exclude) {
+                list = ArrayListManager.add(list, targetId);
+            } else {
+                list = ArrayListManager.remove(list, targetId);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private ArrayList<View> excludeView(ArrayList<View> list, View target, boolean exclude) {
+        if (target != null) {
+            if (exclude) {
+                list = ArrayListManager.add(list, target);
+            } else {
+                list = ArrayListManager.remove(list, target);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Whether to add the given type to the list of types to exclude from this
+     * transition. The <code>exclude</code> parameter specifies whether the target
+     * type should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @param type    The type to ignore when running this transition.
+     * @param exclude Whether to add the target type to or remove it from the
+     *                current list of excluded target types.
+     * @return This transition object.
+     * @see #excludeChildren(Class, boolean)
+     * @see #excludeTarget(int, boolean)
+     * @see #excludeTarget(View, boolean)
+     */
+    @NonNull
+    public Transition excludeTarget(@NonNull Class type, boolean exclude) {
+        mTargetTypeExcludes = excludeType(mTargetTypeExcludes, type, exclude);
         return this;
     }
 
@@ -343,146 +1224,673 @@
      */
     @NonNull
     public Transition excludeChildren(@NonNull Class type, boolean exclude) {
-        mImpl.excludeChildren(type, exclude);
+        mTargetTypeChildExcludes = excludeType(mTargetTypeChildExcludes, type, exclude);
         return this;
     }
 
     /**
-     * Whether to add the given target to the list of targets to exclude from this
-     * transition. The <code>exclude</code> parameter specifies whether the target
-     * should be added to or removed from the excluded list.
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private ArrayList<Class> excludeType(ArrayList<Class> list, Class type, boolean exclude) {
+        if (type != null) {
+            if (exclude) {
+                list = ArrayListManager.add(list, type);
+            } else {
+                list = ArrayListManager.remove(list, type);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Returns the array of target IDs that this transition limits itself to
+     * tracking and animating. If the array is null for both this method and
+     * {@link #getTargets()}, then this transition is
+     * not limited to specific views, and will handle changes to any views
+     * in the hierarchy of a scene change.
      *
-     * <p>Excluding targets is a general mechanism for allowing transitions to run on
-     * a view hierarchy while skipping target views that should not be part of
-     * the transition. For example, you may want to avoid animating children
-     * of a specific ListView or Spinner. Views can be excluded either by their
-     * id, or by their instance reference, or by the Class of that view
-     * (eg, {@link Spinner}).</p>
-     *
-     * @param target  The target to ignore when running this transition.
-     * @param exclude Whether to add the target to or remove the target from the
-     *                current list of excluded targets.
-     * @return This transition object.
-     * @see #excludeChildren(View, boolean)
-     * @see #excludeTarget(int, boolean)
-     * @see #excludeTarget(Class, boolean)
+     * @return the list of target IDs
      */
     @NonNull
-    public Transition excludeTarget(@NonNull View target, boolean exclude) {
-        mImpl.excludeTarget(target, exclude);
-        return this;
+    public List<Integer> getTargetIds() {
+        return mTargetIds;
     }
 
     /**
-     * Whether to add the given id to the list of target ids to exclude from this
-     * transition. The <code>exclude</code> parameter specifies whether the target
-     * should be added to or removed from the excluded list.
+     * Returns the array of target views that this transition limits itself to
+     * tracking and animating. If the array is null for both this method and
+     * {@link #getTargetIds()}, then this transition is
+     * not limited to specific views, and will handle changes to any views
+     * in the hierarchy of a scene change.
      *
-     * <p>Excluding targets is a general mechanism for allowing transitions to run on
-     * a view hierarchy while skipping target views that should not be part of
-     * the transition. For example, you may want to avoid animating children
-     * of a specific ListView or Spinner. Views can be excluded either by their
-     * id, or by their instance reference, or by the Class of that view
-     * (eg, {@link Spinner}).</p>
-     *
-     * @param targetId The id of a target to ignore when running this transition.
-     * @param exclude  Whether to add the target to or remove the target from the
-     *                 current list of excluded targets.
-     * @return This transition object.
-     * @see #excludeChildren(int, boolean)
-     * @see #excludeTarget(View, boolean)
-     * @see #excludeTarget(Class, boolean)
+     * @return the list of target views
      */
     @NonNull
-    public Transition excludeTarget(@IdRes int targetId, boolean exclude) {
-        mImpl.excludeTarget(targetId, exclude);
-        return this;
+    public List<View> getTargets() {
+        return mTargets;
     }
 
     /**
-     * Whether to add the given type to the list of types to exclude from this
-     * transition. The <code>exclude</code> parameter specifies whether the target
-     * type should be added to or removed from the excluded list.
+     * Returns the list of target transitionNames that this transition limits itself to
+     * tracking and animating. If the list is null or empty for
+     * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetNames()}, and
+     * {@link #getTargetTypes()} then this transition is
+     * not limited to specific views, and will handle changes to any views
+     * in the hierarchy of a scene change.
      *
-     * <p>Excluding targets is a general mechanism for allowing transitions to run on
-     * a view hierarchy while skipping target views that should not be part of
-     * the transition. For example, you may want to avoid animating children
-     * of a specific ListView or Spinner. Views can be excluded either by their
-     * id, or by their instance reference, or by the Class of that view
-     * (eg, {@link Spinner}).</p>
-     *
-     * @param type    The type to ignore when running this transition.
-     * @param exclude Whether to add the target type to or remove it from the
-     *                current list of excluded target types.
-     * @return This transition object.
-     * @see #excludeChildren(Class, boolean)
-     * @see #excludeTarget(int, boolean)
-     * @see #excludeTarget(View, boolean)
-     */
-    @NonNull
-    public Transition excludeTarget(@NonNull Class type, boolean exclude) {
-        mImpl.excludeTarget(type, exclude);
-        return this;
-    }
-
-    /**
-     * Returns the duration set on this transition. If no duration has been set,
-     * the returned value will be negative, indicating that resulting animators will
-     * retain their own durations.
-     *
-     * @return The duration set on this transition, in milliseconds, if one has been
-     * set, otherwise returns a negative number.
-     */
-    public long getDuration() {
-        return mImpl.getDuration();
-    }
-
-    /**
-     * Sets the duration of this transition. By default, there is no duration
-     * (indicated by a negative number), which means that the Animator created by
-     * the transition will have its own specified duration. If the duration of a
-     * Transition is set, that duration will override the Animator duration.
-     *
-     * @param duration The length of the animation, in milliseconds.
-     * @return This transition object.
-     * @attr name android:duration
-     */
-    @NonNull
-    public Transition setDuration(long duration) {
-        mImpl.setDuration(duration);
-        return this;
-    }
-
-    /**
-     * Returns the interpolator set on this transition. If no interpolator has been set,
-     * the returned value will be null, indicating that resulting animators will
-     * retain their own interpolators.
-     *
-     * @return The interpolator set on this transition, if one has been set, otherwise
-     * returns null.
+     * @return the list of target transitionNames
      */
     @Nullable
-    public TimeInterpolator getInterpolator() {
-        return mImpl.getInterpolator();
+    public List<String> getTargetNames() {
+        return mTargetNames;
     }
 
     /**
-     * Sets the interpolator of this transition. By default, the interpolator
-     * is null, which means that the Animator created by the transition
-     * will have its own specified interpolator. If the interpolator of a
-     * Transition is set, that interpolator will override the Animator interpolator.
+     * Returns the list of target transitionNames that this transition limits itself to
+     * tracking and animating. If the list is null or empty for
+     * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetNames()}, and
+     * {@link #getTargetTypes()} then this transition is
+     * not limited to specific views, and will handle changes to any views
+     * in the hierarchy of a scene change.
      *
-     * @param interpolator The time interpolator used by the transition
+     * @return the list of target Types
+     */
+    @Nullable
+    public List<Class> getTargetTypes() {
+        return mTargetTypes;
+    }
+
+    /**
+     * Recursive method that captures values for the given view and the
+     * hierarchy underneath it.
+     *
+     * @param sceneRoot The root of the view hierarchy being captured
+     * @param start     true if this capture is happening before the scene change,
+     *                  false otherwise
+     */
+    void captureValues(ViewGroup sceneRoot, boolean start) {
+        clearValues(start);
+        if ((mTargetIds.size() > 0 || mTargets.size() > 0)
+                && (mTargetNames == null || mTargetNames.isEmpty())
+                && (mTargetTypes == null || mTargetTypes.isEmpty())) {
+            for (int i = 0; i < mTargetIds.size(); ++i) {
+                int id = mTargetIds.get(i);
+                View view = sceneRoot.findViewById(id);
+                if (view != null) {
+                    TransitionValues values = new TransitionValues();
+                    values.view = view;
+                    if (start) {
+                        captureStartValues(values);
+                    } else {
+                        captureEndValues(values);
+                    }
+                    values.mTargetedTransitions.add(this);
+                    if (start) {
+                        addViewValues(mStartValues, view, values);
+                    } else {
+                        addViewValues(mEndValues, view, values);
+                    }
+                }
+            }
+            for (int i = 0; i < mTargets.size(); ++i) {
+                View view = mTargets.get(i);
+                TransitionValues values = new TransitionValues();
+                values.view = view;
+                if (start) {
+                    captureStartValues(values);
+                } else {
+                    captureEndValues(values);
+                }
+                values.mTargetedTransitions.add(this);
+                if (start) {
+                    addViewValues(mStartValues, view, values);
+                } else {
+                    addViewValues(mEndValues, view, values);
+                }
+            }
+        } else {
+            captureHierarchy(sceneRoot, start);
+        }
+        if (!start && mNameOverrides != null) {
+            int numOverrides = mNameOverrides.size();
+            ArrayList<View> overriddenViews = new ArrayList<>(numOverrides);
+            for (int i = 0; i < numOverrides; i++) {
+                String fromName = mNameOverrides.keyAt(i);
+                overriddenViews.add(mStartValues.mNameValues.remove(fromName));
+            }
+            for (int i = 0; i < numOverrides; i++) {
+                View view = overriddenViews.get(i);
+                if (view != null) {
+                    String toName = mNameOverrides.valueAt(i);
+                    mStartValues.mNameValues.put(toName, view);
+                }
+            }
+        }
+    }
+
+    private static void addViewValues(TransitionValuesMaps transitionValuesMaps,
+            View view, TransitionValues transitionValues) {
+        transitionValuesMaps.mViewValues.put(view, transitionValues);
+        int id = view.getId();
+        if (id >= 0) {
+            if (transitionValuesMaps.mIdValues.indexOfKey(id) >= 0) {
+                // Duplicate IDs cannot match by ID.
+                transitionValuesMaps.mIdValues.put(id, null);
+            } else {
+                transitionValuesMaps.mIdValues.put(id, view);
+            }
+        }
+        String name = ViewCompat.getTransitionName(view);
+        if (name != null) {
+            if (transitionValuesMaps.mNameValues.containsKey(name)) {
+                // Duplicate transitionNames: cannot match by transitionName.
+                transitionValuesMaps.mNameValues.put(name, null);
+            } else {
+                transitionValuesMaps.mNameValues.put(name, view);
+            }
+        }
+        if (view.getParent() instanceof ListView) {
+            ListView listview = (ListView) view.getParent();
+            if (listview.getAdapter().hasStableIds()) {
+                int position = listview.getPositionForView(view);
+                long itemId = listview.getItemIdAtPosition(position);
+                if (transitionValuesMaps.mItemIdValues.indexOfKey(itemId) >= 0) {
+                    // Duplicate item IDs: cannot match by item ID.
+                    View alreadyMatched = transitionValuesMaps.mItemIdValues.get(itemId);
+                    if (alreadyMatched != null) {
+                        ViewCompat.setHasTransientState(alreadyMatched, false);
+                        transitionValuesMaps.mItemIdValues.put(itemId, null);
+                    }
+                } else {
+                    ViewCompat.setHasTransientState(view, true);
+                    transitionValuesMaps.mItemIdValues.put(itemId, view);
+                }
+            }
+        }
+    }
+
+    /**
+     * Clear valuesMaps for specified start/end state
+     *
+     * @param start true if the start values should be cleared, false otherwise
+     */
+    void clearValues(boolean start) {
+        if (start) {
+            mStartValues.mViewValues.clear();
+            mStartValues.mIdValues.clear();
+            mStartValues.mItemIdValues.clear();
+        } else {
+            mEndValues.mViewValues.clear();
+            mEndValues.mIdValues.clear();
+            mEndValues.mItemIdValues.clear();
+        }
+    }
+
+    /**
+     * Recursive method which captures values for an entire view hierarchy,
+     * starting at some root view. Transitions without targetIDs will use this
+     * method to capture values for all possible views.
+     *
+     * @param view  The view for which to capture values. Children of this View
+     *              will also be captured, recursively down to the leaf nodes.
+     * @param start true if values are being captured in the start scene, false
+     *              otherwise.
+     */
+    private void captureHierarchy(View view, boolean start) {
+        if (view == null) {
+            return;
+        }
+        int id = view.getId();
+        if (mTargetIdExcludes != null && mTargetIdExcludes.contains(id)) {
+            return;
+        }
+        if (mTargetExcludes != null && mTargetExcludes.contains(view)) {
+            return;
+        }
+        if (mTargetTypeExcludes != null) {
+            int numTypes = mTargetTypeExcludes.size();
+            for (int i = 0; i < numTypes; ++i) {
+                if (mTargetTypeExcludes.get(i).isInstance(view)) {
+                    return;
+                }
+            }
+        }
+        if (view.getParent() instanceof ViewGroup) {
+            TransitionValues values = new TransitionValues();
+            values.view = view;
+            if (start) {
+                captureStartValues(values);
+            } else {
+                captureEndValues(values);
+            }
+            values.mTargetedTransitions.add(this);
+            if (start) {
+                addViewValues(mStartValues, view, values);
+            } else {
+                addViewValues(mEndValues, view, values);
+            }
+        }
+        if (view instanceof ViewGroup) {
+            // Don't traverse child hierarchy if there are any child-excludes on this view
+            if (mTargetIdChildExcludes != null && mTargetIdChildExcludes.contains(id)) {
+                return;
+            }
+            if (mTargetChildExcludes != null && mTargetChildExcludes.contains(view)) {
+                return;
+            }
+            if (mTargetTypeChildExcludes != null) {
+                int numTypes = mTargetTypeChildExcludes.size();
+                for (int i = 0; i < numTypes; ++i) {
+                    if (mTargetTypeChildExcludes.get(i).isInstance(view)) {
+                        return;
+                    }
+                }
+            }
+            ViewGroup parent = (ViewGroup) view;
+            for (int i = 0; i < parent.getChildCount(); ++i) {
+                captureHierarchy(parent.getChildAt(i), start);
+            }
+        }
+    }
+
+    /**
+     * This method can be called by transitions to get the TransitionValues for
+     * any particular view during the transition-playing process. This might be
+     * necessary, for example, to query the before/after state of related views
+     * for a given transition.
+     */
+    @Nullable
+    public TransitionValues getTransitionValues(@NonNull View view, boolean start) {
+        if (mParent != null) {
+            return mParent.getTransitionValues(view, start);
+        }
+        TransitionValuesMaps valuesMaps = start ? mStartValues : mEndValues;
+        return valuesMaps.mViewValues.get(view);
+    }
+
+    /**
+     * Find the matched start or end value for a given View. This is only valid
+     * after playTransition starts. For example, it will be valid in
+     * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)}, but not
+     * in {@link #captureStartValues(TransitionValues)}.
+     *
+     * @param view        The view to find the match for.
+     * @param viewInStart Is View from the start values or end values.
+     * @return The matching TransitionValues for view in either start or end values, depending
+     * on viewInStart or null if there is no match for the given view.
+     */
+    TransitionValues getMatchedTransitionValues(View view, boolean viewInStart) {
+        if (mParent != null) {
+            return mParent.getMatchedTransitionValues(view, viewInStart);
+        }
+        ArrayList<TransitionValues> lookIn = viewInStart ? mStartValuesList : mEndValuesList;
+        if (lookIn == null) {
+            return null;
+        }
+        int count = lookIn.size();
+        int index = -1;
+        for (int i = 0; i < count; i++) {
+            TransitionValues values = lookIn.get(i);
+            if (values == null) {
+                return null;
+            }
+            if (values.view == view) {
+                index = i;
+                break;
+            }
+        }
+        TransitionValues values = null;
+        if (index >= 0) {
+            ArrayList<TransitionValues> matchIn = viewInStart ? mEndValuesList : mStartValuesList;
+            values = matchIn.get(index);
+        }
+        return values;
+    }
+
+    /**
+     * Pauses this transition, sending out calls to {@link
+     * TransitionListener#onTransitionPause(Transition)} to all listeners
+     * and pausing all running animators started by this transition.
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public void pause(View sceneRoot) {
+        if (!mEnded) {
+            ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+            int numOldAnims = runningAnimators.size();
+            WindowIdImpl windowId = ViewUtils.getWindowId(sceneRoot);
+            for (int i = numOldAnims - 1; i >= 0; i--) {
+                AnimationInfo info = runningAnimators.valueAt(i);
+                if (info.mView != null && windowId.equals(info.mWindowId)) {
+                    Animator anim = runningAnimators.keyAt(i);
+                    anim.cancel(); // pause() is API Level 19
+                }
+            }
+            if (mListeners != null && mListeners.size() > 0) {
+                @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onTransitionPause(this);
+                }
+            }
+            mPaused = true;
+        }
+    }
+
+    /**
+     * Resumes this transition, sending out calls to {@link
+     * TransitionListener#onTransitionPause(Transition)} to all listeners
+     * and pausing all running animators started by this transition.
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public void resume(View sceneRoot) {
+        if (mPaused) {
+            if (!mEnded) {
+                ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+                int numOldAnims = runningAnimators.size();
+                WindowIdImpl windowId = ViewUtils.getWindowId(sceneRoot);
+                for (int i = numOldAnims - 1; i >= 0; i--) {
+                    AnimationInfo info = runningAnimators.valueAt(i);
+                    if (info.mView != null && windowId.equals(info.mWindowId)) {
+                        Animator anim = runningAnimators.keyAt(i);
+                        anim.end(); // resume() is API Level 19
+                    }
+                }
+                if (mListeners != null && mListeners.size() > 0) {
+                    @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
+                            (ArrayList<TransitionListener>) mListeners.clone();
+                    int numListeners = tmpListeners.size();
+                    for (int i = 0; i < numListeners; ++i) {
+                        tmpListeners.get(i).onTransitionResume(this);
+                    }
+                }
+            }
+            mPaused = false;
+        }
+    }
+
+    /**
+     * Called by TransitionManager to play the transition. This calls
+     * createAnimators() to set things up and create all of the animations and then
+     * runAnimations() to actually start the animations.
+     */
+    void playTransition(ViewGroup sceneRoot) {
+        mStartValuesList = new ArrayList<>();
+        mEndValuesList = new ArrayList<>();
+        matchStartAndEnd(mStartValues, mEndValues);
+
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        int numOldAnims = runningAnimators.size();
+        WindowIdImpl windowId = ViewUtils.getWindowId(sceneRoot);
+        for (int i = numOldAnims - 1; i >= 0; i--) {
+            Animator anim = runningAnimators.keyAt(i);
+            if (anim != null) {
+                AnimationInfo oldInfo = runningAnimators.get(anim);
+                if (oldInfo != null && oldInfo.mView != null && oldInfo.mWindowId == windowId) {
+                    TransitionValues oldValues = oldInfo.mValues;
+                    View oldView = oldInfo.mView;
+                    TransitionValues startValues = getTransitionValues(oldView, true);
+                    TransitionValues endValues = getMatchedTransitionValues(oldView, true);
+                    boolean cancel = (startValues != null || endValues != null)
+                            && oldInfo.mTransition.areValuesChanged(oldValues, endValues);
+                    if (cancel) {
+                        if (anim.isRunning() || anim.isStarted()) {
+                            if (DBG) {
+                                Log.d(LOG_TAG, "Canceling anim " + anim);
+                            }
+                            anim.cancel();
+                        } else {
+                            if (DBG) {
+                                Log.d(LOG_TAG, "removing anim from info list: " + anim);
+                            }
+                            runningAnimators.remove(anim);
+                        }
+                    }
+                }
+            }
+        }
+
+        createAnimators(sceneRoot, mStartValues, mEndValues, mStartValuesList, mEndValuesList);
+        runAnimators();
+    }
+
+    boolean areValuesChanged(TransitionValues oldValues, TransitionValues newValues) {
+        boolean valuesChanged = false;
+        // if oldValues null, then transition didn't care to stash values,
+        // and won't get canceled
+        if (oldValues != null && newValues != null) {
+            String[] properties = getTransitionProperties();
+            if (properties != null) {
+                int count = properties.length;
+                for (int i = 0; i < count; i++) {
+                    if (isValueChanged(oldValues, newValues, properties[i])) {
+                        valuesChanged = true;
+                        break;
+                    }
+                }
+            } else {
+                for (String key : oldValues.values.keySet()) {
+                    if (isValueChanged(oldValues, newValues, key)) {
+                        valuesChanged = true;
+                        break;
+                    }
+                }
+            }
+        }
+        return valuesChanged;
+    }
+
+    private static boolean isValueChanged(TransitionValues oldValues, TransitionValues newValues,
+            String key) {
+        Object oldValue = oldValues.values.get(key);
+        Object newValue = newValues.values.get(key);
+        boolean changed;
+        if (oldValue == null && newValue == null) {
+            // both are null
+            changed = false;
+        } else if (oldValue == null || newValue == null) {
+            // one is null
+            changed = true;
+        } else {
+            // neither is null
+            changed = !oldValue.equals(newValue);
+        }
+        if (DBG && changed) {
+            Log.d(LOG_TAG, "Transition.playTransition: "
+                    + "oldValue != newValue for " + key
+                    + ": old, new = " + oldValue + ", " + newValue);
+        }
+        return changed;
+    }
+
+    /**
+     * This is a utility method used by subclasses to handle standard parts of
+     * setting up and running an Animator: it sets the {@link #getDuration()
+     * duration} and the {@link #getStartDelay() startDelay}, starts the
+     * animation, and, when the animator ends, calls {@link #end()}.
+     *
+     * @param animator The Animator to be run during this transition.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    protected void animate(Animator animator) {
+        // TODO: maybe pass auto-end as a boolean parameter?
+        if (animator == null) {
+            end();
+        } else {
+            if (getDuration() >= 0) {
+                animator.setDuration(getDuration());
+            }
+            if (getStartDelay() >= 0) {
+                animator.setStartDelay(getStartDelay());
+            }
+            if (getInterpolator() != null) {
+                animator.setInterpolator(getInterpolator());
+            }
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    end();
+                    animation.removeListener(this);
+                }
+            });
+            animator.start();
+        }
+    }
+
+    /**
+     * This method is called automatically by the transition and
+     * TransitionSet classes prior to a Transition subclass starting;
+     * subclasses should not need to call it directly.
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    protected void start() {
+        if (mNumInstances == 0) {
+            if (mListeners != null && mListeners.size() > 0) {
+                @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onTransitionStart(this);
+                }
+            }
+            mEnded = false;
+        }
+        mNumInstances++;
+    }
+
+    /**
+     * This method is called automatically by the Transition and
+     * TransitionSet classes when a transition finishes, either because
+     * a transition did nothing (returned a null Animator from
+     * {@link Transition#createAnimator(ViewGroup, TransitionValues,
+     * TransitionValues)}) or because the transition returned a valid
+     * Animator and end() was called in the onAnimationEnd()
+     * callback of the AnimatorListener.
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    protected void end() {
+        --mNumInstances;
+        if (mNumInstances == 0) {
+            if (mListeners != null && mListeners.size() > 0) {
+                @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onTransitionEnd(this);
+                }
+            }
+            for (int i = 0; i < mStartValues.mItemIdValues.size(); ++i) {
+                View view = mStartValues.mItemIdValues.valueAt(i);
+                if (view != null) {
+                    ViewCompat.setHasTransientState(view, false);
+                }
+            }
+            for (int i = 0; i < mEndValues.mItemIdValues.size(); ++i) {
+                View view = mEndValues.mItemIdValues.valueAt(i);
+                if (view != null) {
+                    ViewCompat.setHasTransientState(view, false);
+                }
+            }
+            mEnded = true;
+        }
+    }
+
+    /**
+     * This method cancels a transition that is currently running.
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    protected void cancel() {
+        int numAnimators = mCurrentAnimators.size();
+        for (int i = numAnimators - 1; i >= 0; i--) {
+            Animator animator = mCurrentAnimators.get(i);
+            animator.cancel();
+        }
+        if (mListeners != null && mListeners.size() > 0) {
+            @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
+                    (ArrayList<TransitionListener>) mListeners.clone();
+            int numListeners = tmpListeners.size();
+            for (int i = 0; i < numListeners; ++i) {
+                tmpListeners.get(i).onTransitionCancel(this);
+            }
+        }
+    }
+
+    /**
+     * 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.
      * @return This transition object.
-     * @attr name android:interpolator
      */
     @NonNull
-    public Transition setInterpolator(@Nullable TimeInterpolator interpolator) {
-        mImpl.setInterpolator(interpolator);
+    public Transition addListener(@NonNull TransitionListener listener) {
+        if (mListeners == null) {
+            mListeners = new ArrayList<>();
+        }
+        mListeners.add(listener);
         return this;
     }
 
     /**
+     * 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 transition.
+     * @return This transition object.
+     */
+    @NonNull
+    public Transition removeListener(@NonNull TransitionListener listener) {
+        if (mListeners == null) {
+            return this;
+        }
+        mListeners.remove(listener);
+        if (mListeners.size() == 0) {
+            mListeners = null;
+        }
+        return this;
+    }
+
+    Transition setSceneRoot(ViewGroup sceneRoot) {
+        mSceneRoot = sceneRoot;
+        return this;
+    }
+
+    void setCanRemoveViews(boolean canRemoveViews) {
+        mCanRemoveViews = canRemoveViews;
+    }
+
+    @Override
+    public String toString() {
+        return toString("");
+    }
+
+    @Override
+    public Transition clone() {
+        try {
+            Transition clone = (Transition) super.clone();
+            clone.mAnimators = new ArrayList<>();
+            clone.mStartValues = new TransitionValuesMaps();
+            clone.mEndValues = new TransitionValuesMaps();
+            return clone;
+        } catch (CloneNotSupportedException e) {
+            return null;
+        }
+    }
+
+    /**
      * Returns the name of this Transition. This name is used internally to distinguish
      * between different transitions to determine when interrupting transitions overlap.
      * For example, a ChangeBounds running on the same target view as another ChangeBounds
@@ -496,164 +1904,55 @@
      */
     @NonNull
     public String getName() {
-        return mImpl.getName();
+        return mName;
     }
 
-    /**
-     * Returns the startDelay set on this transition. If no startDelay has been set,
-     * the returned value will be negative, indicating that resulting animators will
-     * retain their own startDelays.
-     *
-     * @return The startDelay set on this transition, in milliseconds, if one has
-     * been set, otherwise returns a negative number.
-     */
-    public long getStartDelay() {
-        return mImpl.getStartDelay();
-    }
-
-    /**
-     * Sets the startDelay of this transition. By default, there is no delay
-     * (indicated by a negative number), which means that the Animator created by
-     * the transition will have its own specified startDelay. If the delay of a
-     * Transition is set, that delay will override the Animator delay.
-     *
-     * @param startDelay The length of the delay, in milliseconds.
-     * @return This transition object.
-     * @attr name android:startDelay
-     */
-    @NonNull
-    public Transition setStartDelay(long startDelay) {
-        mImpl.setStartDelay(startDelay);
-        return this;
-    }
-
-    /**
-     * Returns the array of target IDs that this transition limits itself to
-     * tracking and animating. If the array is null for both this method and
-     * {@link #getTargets()}, then this transition is
-     * not limited to specific views, and will handle changes to any views
-     * in the hierarchy of a scene change.
-     *
-     * @return the list of target IDs
-     */
-    @NonNull
-    public List<Integer> getTargetIds() {
-        return mImpl.getTargetIds();
-    }
-
-    /**
-     * Returns the array of target views that this transition limits itself to
-     * tracking and animating. If the array is null for both this method and
-     * {@link #getTargetIds()}, then this transition is
-     * not limited to specific views, and will handle changes to any views
-     * in the hierarchy of a scene change.
-     *
-     * @return the list of target views
-     */
-    @NonNull
-    public List<View> getTargets() {
-        return mImpl.getTargets();
-    }
-
-    /**
-     * Returns the set of property names used stored in the {@link TransitionValues}
-     * object passed into {@link #captureStartValues(TransitionValues)} that
-     * this transition cares about for the purposes of canceling overlapping animations.
-     * When any transition is started on a given scene root, all transitions
-     * currently running on that same scene root are checked to see whether the
-     * properties on which they based their animations agree with the end values of
-     * the same properties in the new transition. If the end values are not equal,
-     * then the old animation is canceled since the new transition will start a new
-     * animation to these new values. If the values are equal, the old animation is
-     * allowed to continue and no new animation is started for that transition.
-     *
-     * <p>A transition does not need to override this method. However, not doing so
-     * will mean that the cancellation logic outlined in the previous paragraph
-     * will be skipped for that transition, possibly leading to artifacts as
-     * old transitions and new transitions on the same targets run in parallel,
-     * animating views toward potentially different end values.</p>
-     *
-     * @return An array of property names as described in the class documentation for
-     * {@link TransitionValues}. The default implementation returns <code>null</code>.
-     */
-    @Nullable
-    public String[] getTransitionProperties() {
-        return mImpl.getTransitionProperties();
-    }
-
-    /**
-     * This method can be called by transitions to get the TransitionValues for
-     * any particular view during the transition-playing process. This might be
-     * necessary, for example, to query the before/after state of related views
-     * for a given transition.
-     */
-    @NonNull
-    public TransitionValues getTransitionValues(@NonNull View view, boolean start) {
-        return mImpl.getTransitionValues(view, start);
-    }
-
-    /**
-     * 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 transition.
-     * @return This transition object.
-     */
-    @NonNull
-    public Transition removeListener(@NonNull TransitionListener listener) {
-        mImpl.removeListener(listener);
-        return this;
-    }
-
-    /**
-     * Removes the given target from the list of targets that this Transition
-     * is interested in animating.
-     *
-     * @param target The target view, must be non-null.
-     * @return Transition The Transition from which the target is removed.
-     * Returning the same object makes it easier to chain calls during
-     * construction, such as
-     * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code>
-     */
-    @NonNull
-    public Transition removeTarget(@NonNull View target) {
-        mImpl.removeTarget(target);
-        return this;
-    }
-
-    /**
-     * Removes the given targetId from the list of ids that this Transition
-     * is interested in animating.
-     *
-     * @param targetId The id of a target view, must be a positive number.
-     * @return The Transition from which the targetId is removed.
-     * Returning the same object makes it easier to chain calls during
-     * construction, such as
-     * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code>
-     */
-    @NonNull
-    public Transition removeTarget(@IdRes int targetId) {
-        mImpl.removeTarget(targetId);
-        return this;
-    }
-
-    @Override
-    public String toString() {
-        return mImpl.toString();
+    String toString(String indent) {
+        String result = indent + getClass().getSimpleName() + "@"
+                + Integer.toHexString(hashCode()) + ": ";
+        if (mDuration != -1) {
+            result += "dur(" + mDuration + ") ";
+        }
+        if (mStartDelay != -1) {
+            result += "dly(" + mStartDelay + ") ";
+        }
+        if (mInterpolator != null) {
+            result += "interp(" + mInterpolator + ") ";
+        }
+        if (mTargetIds.size() > 0 || mTargets.size() > 0) {
+            result += "tgts(";
+            if (mTargetIds.size() > 0) {
+                for (int i = 0; i < mTargetIds.size(); ++i) {
+                    if (i > 0) {
+                        result += ", ";
+                    }
+                    result += mTargetIds.get(i);
+                }
+            }
+            if (mTargets.size() > 0) {
+                for (int i = 0; i < mTargets.size(); ++i) {
+                    if (i > 0) {
+                        result += ", ";
+                    }
+                    result += mTargets.get(i);
+                }
+            }
+            result += ")";
+        }
+        return result;
     }
 
     /**
      * A transition listener receives notifications from a transition.
      * Notifications indicate transition lifecycle events.
      */
-    public interface TransitionListener extends TransitionInterfaceListener<Transition> {
+    public interface TransitionListener {
 
         /**
          * Notification about the start of the transition.
          *
          * @param transition The started transition.
          */
-        @Override
         void onTransitionStart(@NonNull Transition transition);
 
         /**
@@ -665,7 +1964,6 @@
          *
          * @param transition The transition which reached its end.
          */
-        @Override
         void onTransitionEnd(@NonNull Transition transition);
 
         /**
@@ -678,7 +1976,6 @@
          *
          * @param transition The transition which was canceled.
          */
-        @Override
         void onTransitionCancel(@NonNull Transition transition);
 
         /**
@@ -691,7 +1988,6 @@
          *
          * @param transition The transition which was paused.
          */
-        @Override
         void onTransitionPause(@NonNull Transition transition);
 
         /**
@@ -703,8 +1999,112 @@
          *
          * @param transition The transition which was resumed.
          */
-        @Override
         void onTransitionResume(@NonNull Transition transition);
     }
 
+    /**
+     * Utility adapter class to avoid having to override all three methods
+     * whenever someone just wants to listen for a single event.
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static class TransitionListenerAdapter implements TransitionListener {
+
+        @Override
+        public void onTransitionStart(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionEnd(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionCancel(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionPause(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionResume(@NonNull Transition transition) {
+        }
+    }
+
+    /**
+     * Holds information about each animator used when a new transition starts
+     * while other transitions are still running to determine whether a running
+     * animation should be canceled or a new animation noop'd. The structure holds
+     * information about the state that an animation is going to, to be compared to
+     * end state of a new animation.
+     */
+    private static class AnimationInfo {
+
+        View mView;
+
+        String mName;
+
+        TransitionValues mValues;
+
+        WindowIdImpl mWindowId;
+
+        Transition mTransition;
+
+        AnimationInfo(View view, String name, Transition transition, WindowIdImpl windowId,
+                TransitionValues values) {
+            mView = view;
+            mName = name;
+            mValues = values;
+            mWindowId = windowId;
+            mTransition = transition;
+        }
+    }
+
+    /**
+     * Utility class for managing typed ArrayLists efficiently. In particular, this
+     * can be useful for lists that we don't expect to be used often (eg, the exclude
+     * lists), so we'd like to keep them nulled out by default. This causes the code to
+     * become tedious, with constant null checks, code to allocate when necessary,
+     * and code to null out the reference when the list is empty. This class encapsulates
+     * all of that functionality into simple add()/remove() methods which perform the
+     * necessary checks, allocation/null-out as appropriate, and return the
+     * resulting list.
+     */
+    private static class ArrayListManager {
+
+        /**
+         * Add the specified item to the list, returning the resulting list.
+         * The returned list can either the be same list passed in or, if that
+         * list was null, the new list that was created.
+         *
+         * Note that the list holds unique items; if the item already exists in the
+         * list, the list is not modified.
+         */
+        static <T> ArrayList<T> add(ArrayList<T> list, T item) {
+            if (list == null) {
+                list = new ArrayList<>();
+            }
+            if (!list.contains(item)) {
+                list.add(item);
+            }
+            return list;
+        }
+
+        /**
+         * Remove the specified item from the list, returning the resulting list.
+         * The returned list can either the be same list passed in or, if that
+         * list becomes empty as a result of the remove(), the new list was created.
+         */
+        static <T> ArrayList<T> remove(ArrayList<T> list, T item) {
+            if (list != null) {
+                list.remove(item);
+                if (list.isEmpty()) {
+                    list = null;
+                }
+            }
+            return list;
+        }
+    }
+
 }
diff --git a/transition/src/android/support/transition/TransitionManager.java b/transition/src/android/support/transition/TransitionManager.java
index da9ac08..16ef845 100644
--- a/transition/src/android/support/transition/TransitionManager.java
+++ b/transition/src/android/support/transition/TransitionManager.java
@@ -16,10 +16,17 @@
 
 package android.support.transition;
 
-import android.os.Build;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.v4.util.ArrayMap;
+import android.support.v4.view.ViewCompat;
+import android.util.Log;
+import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 
 /**
  * This class manages the set of transitions that fire when there is a
@@ -36,24 +43,244 @@
  */
 public class TransitionManager {
 
-    private static TransitionManagerStaticsImpl sImpl;
+    private static final String LOG_TAG = "TransitionManager";
 
-    static {
-        if (Build.VERSION.SDK_INT < 19) {
-            sImpl = new TransitionManagerStaticsIcs();
-        } else {
-            sImpl = new TransitionManagerStaticsKitKat();
+    private static Transition sDefaultTransition = new AutoTransition();
+
+    private ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<>();
+    private ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions = new ArrayMap<>();
+    private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>
+            sRunningTransitions = new ThreadLocal<>();
+    private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<>();
+
+    /**
+     * Sets a specific transition to occur when the given scene is entered.
+     *
+     * @param scene      The scene which, when applied, will cause the given
+     *                   transition to run.
+     * @param transition The transition that will play when the given scene is
+     *                   entered. A value of null will result in the default behavior of
+     *                   using the default transition instead.
+     */
+    public void setTransition(@NonNull Scene scene, @Nullable Transition transition) {
+        mSceneTransitions.put(scene, transition);
+    }
+
+    /**
+     * Sets a specific transition to occur when the given pair of scenes is
+     * exited/entered.
+     *
+     * @param fromScene  The scene being exited when the given transition will
+     *                   be run
+     * @param toScene    The scene being entered when the given transition will
+     *                   be run
+     * @param transition The transition that will play when the given scene is
+     *                   entered. A value of null will result in the default behavior of
+     *                   using the default transition instead.
+     */
+    public void setTransition(@NonNull Scene fromScene, @NonNull Scene toScene,
+            @Nullable Transition transition) {
+        ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene);
+        if (sceneTransitionMap == null) {
+            sceneTransitionMap = new ArrayMap<>();
+            mScenePairTransitions.put(toScene, sceneTransitionMap);
+        }
+        sceneTransitionMap.put(fromScene, transition);
+    }
+
+    /**
+     * Returns the Transition for the given scene being entered. The result
+     * depends not only on the given scene, but also the scene which the
+     * {@link Scene#getSceneRoot() sceneRoot} of the Scene is currently in.
+     *
+     * @param scene The scene being entered
+     * @return The Transition to be used for the given scene change. If no
+     * Transition was specified for this scene change, the default transition
+     * will be used instead.
+     */
+    private Transition getTransition(Scene scene) {
+        Transition transition;
+        ViewGroup sceneRoot = scene.getSceneRoot();
+        if (sceneRoot != null) {
+            // TODO: cached in Scene instead? long-term, cache in View itself
+            Scene currScene = Scene.getCurrentScene(sceneRoot);
+            if (currScene != null) {
+                ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions
+                        .get(scene);
+                if (sceneTransitionMap != null) {
+                    transition = sceneTransitionMap.get(currScene);
+                    if (transition != null) {
+                        return transition;
+                    }
+                }
+            }
+        }
+        transition = mSceneTransitions.get(scene);
+        return (transition != null) ? transition : sDefaultTransition;
+    }
+
+    /**
+     * This is where all of the work of a transition/scene-change is
+     * orchestrated. This method captures the start values for the given
+     * transition, exits the current Scene, enters the new scene, captures
+     * the end values for the transition, and finally plays the
+     * resulting values-populated transition.
+     *
+     * @param scene      The scene being entered
+     * @param transition The transition to play for this scene change
+     */
+    private static void changeScene(Scene scene, Transition transition) {
+        final ViewGroup sceneRoot = scene.getSceneRoot();
+
+        Transition transitionClone = null;
+        if (transition != null) {
+            transitionClone = transition.clone();
+            transitionClone.setSceneRoot(sceneRoot);
+        }
+
+        Scene oldScene = Scene.getCurrentScene(sceneRoot);
+        if (oldScene != null && oldScene.isCreatedFromLayoutResource()) {
+            transitionClone.setCanRemoveViews(true);
+        }
+
+        sceneChangeSetup(sceneRoot, transitionClone);
+
+        scene.enter();
+
+        sceneChangeRunTransition(sceneRoot, transitionClone);
+    }
+
+    static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() {
+        WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>> runningTransitions =
+                sRunningTransitions.get();
+        if (runningTransitions == null || runningTransitions.get() == null) {
+            ArrayMap<ViewGroup, ArrayList<Transition>> transitions = new ArrayMap<>();
+            runningTransitions = new WeakReference<>(transitions);
+            sRunningTransitions.set(runningTransitions);
+        }
+        return runningTransitions.get();
+    }
+
+    private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
+            final Transition transition) {
+        if (transition != null && sceneRoot != null) {
+            MultiListener listener = new MultiListener(transition, sceneRoot);
+            sceneRoot.addOnAttachStateChangeListener(listener);
+            sceneRoot.getViewTreeObserver().addOnPreDrawListener(listener);
         }
     }
 
-    private TransitionManagerImpl mImpl;
+    /**
+     * This private utility class is used to listen for both OnPreDraw and
+     * OnAttachStateChange events. OnPreDraw events are the main ones we care
+     * about since that's what triggers the transition to take place.
+     * OnAttachStateChange events are also important in case the view is removed
+     * from the hierarchy before the OnPreDraw event takes place; it's used to
+     * clean up things since the OnPreDraw listener didn't get called in time.
+     */
+    private static class MultiListener implements ViewTreeObserver.OnPreDrawListener,
+            View.OnAttachStateChangeListener {
 
-    public TransitionManager() {
-        if (Build.VERSION.SDK_INT < 19) {
-            mImpl = new TransitionManagerIcs();
-        } else {
-            mImpl = new TransitionManagerKitKat();
+        Transition mTransition;
+
+        ViewGroup mSceneRoot;
+
+        MultiListener(Transition transition, ViewGroup sceneRoot) {
+            mTransition = transition;
+            mSceneRoot = sceneRoot;
         }
+
+        private void removeListeners() {
+            mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+            mSceneRoot.removeOnAttachStateChangeListener(this);
+        }
+
+        @Override
+        public void onViewAttachedToWindow(View v) {
+        }
+
+        @Override
+        public void onViewDetachedFromWindow(View v) {
+            removeListeners();
+
+            sPendingTransitions.remove(mSceneRoot);
+            ArrayList<Transition> runningTransitions = getRunningTransitions().get(mSceneRoot);
+            if (runningTransitions != null && runningTransitions.size() > 0) {
+                for (Transition runningTransition : runningTransitions) {
+                    runningTransition.resume(mSceneRoot);
+                }
+            }
+            mTransition.clearValues(true);
+        }
+
+        @Override
+        public boolean onPreDraw() {
+            removeListeners();
+            sPendingTransitions.remove(mSceneRoot);
+            // Add to running list, handle end to remove it
+            final ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
+                    getRunningTransitions();
+            ArrayList<Transition> currentTransitions = runningTransitions.get(mSceneRoot);
+            ArrayList<Transition> previousRunningTransitions = null;
+            if (currentTransitions == null) {
+                currentTransitions = new ArrayList<>();
+                runningTransitions.put(mSceneRoot, currentTransitions);
+            } else if (currentTransitions.size() > 0) {
+                previousRunningTransitions = new ArrayList<>(currentTransitions);
+            }
+            currentTransitions.add(mTransition);
+            mTransition.addListener(new Transition.TransitionListenerAdapter() {
+                @Override
+                public void onTransitionEnd(@NonNull Transition transition) {
+                    ArrayList<Transition> currentTransitions = runningTransitions.get(mSceneRoot);
+                    currentTransitions.remove(transition);
+                }
+            });
+            mTransition.captureValues(mSceneRoot, false);
+            if (previousRunningTransitions != null) {
+                for (Transition runningTransition : previousRunningTransitions) {
+                    runningTransition.resume(mSceneRoot);
+                }
+            }
+            mTransition.playTransition(mSceneRoot);
+
+            return true;
+        }
+    }
+
+    private static void sceneChangeSetup(ViewGroup sceneRoot, Transition transition) {
+        // Capture current values
+        ArrayList<Transition> runningTransitions = getRunningTransitions().get(sceneRoot);
+
+        if (runningTransitions != null && runningTransitions.size() > 0) {
+            for (Transition runningTransition : runningTransitions) {
+                runningTransition.pause(sceneRoot);
+            }
+        }
+
+        if (transition != null) {
+            transition.captureValues(sceneRoot, true);
+        }
+
+        // Notify previous scene that it is being exited
+        Scene previousScene = Scene.getCurrentScene(sceneRoot);
+        if (previousScene != null) {
+            previousScene.exit();
+        }
+    }
+
+    /**
+     * Change to the given scene, using the
+     * appropriate transition for this particular scene change
+     * (as specified to the TransitionManager, or the default
+     * if no such transition exists).
+     *
+     * @param scene The Scene to change to
+     */
+    public void transitionTo(@NonNull Scene scene) {
+        // Auto transition if there is no transition declared for the Scene, but there is
+        // a root or parent view
+        changeScene(scene, getTransition(scene));
     }
 
     /**
@@ -63,7 +290,7 @@
      * @param scene The Scene to change to
      */
     public static void go(@NonNull Scene scene) {
-        sImpl.go(scene.mImpl);
+        changeScene(scene, sDefaultTransition);
     }
 
     /**
@@ -81,7 +308,7 @@
      *                   value of null causes the scene change to happen with no transition.
      */
     public static void go(@NonNull Scene scene, @Nullable Transition transition) {
-        sImpl.go(scene.mImpl, transition == null ? null : transition.mImpl);
+        changeScene(scene, transition);
     }
 
     /**
@@ -94,7 +321,7 @@
      * @param sceneRoot The root of the View hierarchy to run the transition on.
      */
     public static void beginDelayedTransition(@NonNull final ViewGroup sceneRoot) {
-        sImpl.beginDelayedTransition(sceneRoot);
+        beginDelayedTransition(sceneRoot, null);
     }
 
     /**
@@ -122,50 +349,20 @@
      */
     public static void beginDelayedTransition(@NonNull final ViewGroup sceneRoot,
             @Nullable Transition transition) {
-        sImpl.beginDelayedTransition(sceneRoot, transition == null ? null : transition.mImpl);
-    }
-
-    /**
-     * Sets a specific transition to occur when the given scene is entered.
-     *
-     * @param scene      The scene which, when applied, will cause the given
-     *                   transition to run.
-     * @param transition The transition that will play when the given scene is
-     *                   entered. A value of null will result in the default behavior of
-     *                   using the default transition instead.
-     */
-    public void setTransition(@NonNull Scene scene, @Nullable Transition transition) {
-        mImpl.setTransition(scene.mImpl, transition == null ? null : transition.mImpl);
-    }
-
-    /**
-     * Sets a specific transition to occur when the given pair of scenes is
-     * exited/entered.
-     *
-     * @param fromScene  The scene being exited when the given transition will
-     *                   be run
-     * @param toScene    The scene being entered when the given transition will
-     *                   be run
-     * @param transition The transition that will play when the given scene is
-     *                   entered. A value of null will result in the default behavior of
-     *                   using the default transition instead.
-     */
-    public void setTransition(@NonNull Scene fromScene, @NonNull Scene toScene,
-            @Nullable Transition transition) {
-        mImpl.setTransition(fromScene.mImpl, toScene.mImpl,
-                transition == null ? null : transition.mImpl);
-    }
-
-    /**
-     * Change to the given scene, using the
-     * appropriate transition for this particular scene change
-     * (as specified to the TransitionManager, or the default
-     * if no such transition exists).
-     *
-     * @param scene The Scene to change to
-     */
-    public void transitionTo(@NonNull Scene scene) {
-        mImpl.transitionTo(scene.mImpl);
+        if (!sPendingTransitions.contains(sceneRoot) && ViewCompat.isLaidOut(sceneRoot)) {
+            if (Transition.DBG) {
+                Log.d(LOG_TAG, "beginDelayedTransition: root, transition = "
+                        + sceneRoot + ", " + transition);
+            }
+            sPendingTransitions.add(sceneRoot);
+            if (transition == null) {
+                transition = sDefaultTransition;
+            }
+            final Transition transitionClone = transition.clone();
+            sceneChangeSetup(sceneRoot, transitionClone);
+            Scene.setCurrentScene(sceneRoot, null);
+            sceneChangeRunTransition(sceneRoot, transitionClone);
+        }
     }
 
 }
diff --git a/transition/src/android/support/transition/TransitionSet.java b/transition/src/android/support/transition/TransitionSet.java
index f43eeb1..66f8109 100644
--- a/transition/src/android/support/transition/TransitionSet.java
+++ b/transition/src/android/support/transition/TransitionSet.java
@@ -16,12 +16,19 @@
 
 package android.support.transition;
 
-import android.animation.Animator;
-import android.os.Build;
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.animation.TimeInterpolator;
+import android.support.annotation.IdRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.util.AndroidRuntimeException;
+import android.view.View;
 import android.view.ViewGroup;
 
+import java.util.ArrayList;
+
 /**
  * A TransitionSet is a parent of child transitions (including other
  * TransitionSets). Using TransitionSets enables more complex
@@ -34,6 +41,11 @@
  */
 public class TransitionSet extends Transition {
 
+    private ArrayList<Transition> mTransitions = new ArrayList<>();
+    private boolean mPlayTogether = true;
+    private int mCurrentListeners;
+    private boolean mStarted = false;
+
     /**
      * A flag used to indicate that the child transitions of this set
      * should all start at the same time.
@@ -55,24 +67,6 @@
      * child transitions will play {@link #ORDERING_TOGETHER together}.
      */
     public TransitionSet() {
-        super(true);
-        if (Build.VERSION.SDK_INT < 19) {
-            mImpl = new TransitionSetIcs(this);
-        } else {
-            mImpl = new TransitionSetKitKat(this);
-        }
-    }
-
-    /**
-     * Returns the ordering of this TransitionSet. By default, the value is
-     * {@link #ORDERING_TOGETHER}.
-     *
-     * @return {@link #ORDERING_TOGETHER} if child transitions will play at the same
-     * time, {@link #ORDERING_SEQUENTIAL} if they will play in sequence.
-     * @see #setOrdering(int)
-     */
-    public int getOrdering() {
-        return ((TransitionSetImpl) mImpl).getOrdering();
     }
 
     /**
@@ -85,11 +79,33 @@
      */
     @NonNull
     public TransitionSet setOrdering(int ordering) {
-        ((TransitionSetImpl) mImpl).setOrdering(ordering);
+        switch (ordering) {
+            case ORDERING_SEQUENTIAL:
+                mPlayTogether = false;
+                break;
+            case ORDERING_TOGETHER:
+                mPlayTogether = true;
+                break;
+            default:
+                throw new AndroidRuntimeException("Invalid parameter for TransitionSet "
+                        + "ordering: " + ordering);
+        }
         return this;
     }
 
     /**
+     * Returns the ordering of this TransitionSet. By default, the value is
+     * {@link #ORDERING_TOGETHER}.
+     *
+     * @return {@link #ORDERING_TOGETHER} if child transitions will play at the same
+     * time, {@link #ORDERING_SEQUENTIAL} if they will play in sequence.
+     * @see #setOrdering(int)
+     */
+    public int getOrdering() {
+        return mPlayTogether ? ORDERING_TOGETHER : ORDERING_SEQUENTIAL;
+    }
+
+    /**
      * Adds child transition to this set. The order in which this child transition
      * is added relative to other child transitions that are added, in addition to
      * the {@link #getOrdering() ordering} property, determines the
@@ -104,11 +120,192 @@
      */
     @NonNull
     public TransitionSet addTransition(@NonNull Transition transition) {
-        ((TransitionSetImpl) mImpl).addTransition(transition.mImpl);
+        mTransitions.add(transition);
+        transition.mParent = this;
+        if (mDuration >= 0) {
+            transition.setDuration(mDuration);
+        }
         return this;
     }
 
     /**
+     * Returns the number of child transitions in the TransitionSet.
+     *
+     * @return The number of child transitions in the TransitionSet.
+     * @see #addTransition(Transition)
+     * @see #getTransitionAt(int)
+     */
+    public int getTransitionCount() {
+        return mTransitions.size();
+    }
+
+    /**
+     * Returns the child Transition at the specified position in the TransitionSet.
+     *
+     * @param index The position of the Transition to retrieve.
+     * @see #addTransition(Transition)
+     * @see #getTransitionCount()
+     */
+    public Transition getTransitionAt(int index) {
+        if (index < 0 || index >= mTransitions.size()) {
+            return null;
+        }
+        return mTransitions.get(index);
+    }
+
+    /**
+     * Setting a non-negative duration on a TransitionSet causes all of the child
+     * transitions (current and future) to inherit this duration.
+     *
+     * @param duration The length of the animation, in milliseconds.
+     * @return This transitionSet object.
+     */
+    @NonNull
+    @Override
+    public TransitionSet setDuration(long duration) {
+        super.setDuration(duration);
+        if (mDuration >= 0) {
+            int numTransitions = mTransitions.size();
+            for (int i = 0; i < numTransitions; ++i) {
+                mTransitions.get(i).setDuration(duration);
+            }
+        }
+        return this;
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet setStartDelay(long startDelay) {
+        return (TransitionSet) super.setStartDelay(startDelay);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet setInterpolator(@Nullable TimeInterpolator interpolator) {
+        return (TransitionSet) super.setInterpolator(interpolator);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet addTarget(@NonNull View target) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).addTarget(target);
+        }
+        return (TransitionSet) super.addTarget(target);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet addTarget(@IdRes int targetId) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).addTarget(targetId);
+        }
+        return (TransitionSet) super.addTarget(targetId);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet addTarget(@NonNull String targetName) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).addTarget(targetName);
+        }
+        return (TransitionSet) super.addTarget(targetName);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet addTarget(@NonNull Class targetType) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).addTarget(targetType);
+        }
+        return (TransitionSet) super.addTarget(targetType);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet addListener(@NonNull TransitionListener listener) {
+        return (TransitionSet) super.addListener(listener);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet removeTarget(@IdRes int targetId) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).removeTarget(targetId);
+        }
+        return (TransitionSet) super.removeTarget(targetId);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet removeTarget(@NonNull View target) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).removeTarget(target);
+        }
+        return (TransitionSet) super.removeTarget(target);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet removeTarget(@NonNull Class target) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).removeTarget(target);
+        }
+        return (TransitionSet) super.removeTarget(target);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet removeTarget(@NonNull String target) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).removeTarget(target);
+        }
+        return (TransitionSet) super.removeTarget(target);
+    }
+
+    @NonNull
+    @Override
+    public Transition excludeTarget(@NonNull View target, boolean exclude) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).excludeTarget(target, exclude);
+        }
+        return super.excludeTarget(target, exclude);
+    }
+
+    @NonNull
+    @Override
+    public Transition excludeTarget(@NonNull String targetName, boolean exclude) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).excludeTarget(targetName, exclude);
+        }
+        return super.excludeTarget(targetName, exclude);
+    }
+
+    @NonNull
+    @Override
+    public Transition excludeTarget(int targetId, boolean exclude) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).excludeTarget(targetId, exclude);
+        }
+        return super.excludeTarget(targetId, exclude);
+    }
+
+    @NonNull
+    @Override
+    public Transition excludeTarget(@NonNull Class type, boolean exclude) {
+        for (int i = 0; i < mTransitions.size(); i++) {
+            mTransitions.get(i).excludeTarget(type, exclude);
+        }
+        return super.excludeTarget(type, exclude);
+    }
+
+    @NonNull
+    @Override
+    public TransitionSet removeListener(@NonNull TransitionListener listener) {
+        return (TransitionSet) super.removeListener(listener);
+    }
+
+    /**
      * Removes the specified child transition from this set.
      *
      * @param transition The transition to be removed.
@@ -116,25 +313,215 @@
      */
     @NonNull
     public TransitionSet removeTransition(@NonNull Transition transition) {
-        ((TransitionSetImpl) mImpl).removeTransition(transition.mImpl);
+        mTransitions.remove(transition);
+        transition.mParent = null;
         return this;
     }
 
+    /**
+     * Sets up listeners for each of the child transitions. This is used to
+     * determine when this transition set is finished (all child transitions
+     * must finish first).
+     */
+    private void setupStartEndListeners() {
+        TransitionSetListener listener = new TransitionSetListener(this);
+        for (Transition childTransition : mTransitions) {
+            childTransition.addListener(listener);
+        }
+        mCurrentListeners = mTransitions.size();
+    }
+
+    /**
+     * This listener is used to detect when all child transitions are done, at
+     * which point this transition set is also done.
+     */
+    static class TransitionSetListener extends TransitionListenerAdapter {
+
+        TransitionSet mTransitionSet;
+
+        TransitionSetListener(TransitionSet transitionSet) {
+            mTransitionSet = transitionSet;
+        }
+
+        @Override
+        public void onTransitionStart(@NonNull Transition transition) {
+            if (!mTransitionSet.mStarted) {
+                mTransitionSet.start();
+                mTransitionSet.mStarted = true;
+            }
+        }
+
+        @Override
+        public void onTransitionEnd(@NonNull Transition transition) {
+            --mTransitionSet.mCurrentListeners;
+            if (mTransitionSet.mCurrentListeners == 0) {
+                // All child trans
+                mTransitionSet.mStarted = false;
+                mTransitionSet.end();
+            }
+            transition.removeListener(this);
+        }
+
+    }
+
+    /**
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
     @Override
-    public void captureEndValues(@NonNull TransitionValues transitionValues) {
-        mImpl.captureEndValues(transitionValues);
+    protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+            TransitionValuesMaps endValues, ArrayList<TransitionValues> startValuesList,
+            ArrayList<TransitionValues> endValuesList) {
+        long startDelay = getStartDelay();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; i++) {
+            Transition childTransition = mTransitions.get(i);
+            // We only set the start delay on the first transition if we are playing
+            // the transitions sequentially.
+            if (startDelay > 0 && (mPlayTogether || i == 0)) {
+                long childStartDelay = childTransition.getStartDelay();
+                if (childStartDelay > 0) {
+                    childTransition.setStartDelay(startDelay + childStartDelay);
+                } else {
+                    childTransition.setStartDelay(startDelay);
+                }
+            }
+            childTransition.createAnimators(sceneRoot, startValues, endValues, startValuesList,
+                    endValuesList);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    protected void runAnimators() {
+        if (mTransitions.isEmpty()) {
+            start();
+            end();
+            return;
+        }
+        setupStartEndListeners();
+        if (!mPlayTogether) {
+            // Setup sequence with listeners
+            // TODO: Need to add listeners in such a way that we can remove them later if canceled
+            for (int i = 1; i < mTransitions.size(); ++i) {
+                Transition previousTransition = mTransitions.get(i - 1);
+                final Transition nextTransition = mTransitions.get(i);
+                previousTransition.addListener(new TransitionListenerAdapter() {
+                    @Override
+                    public void onTransitionEnd(@NonNull Transition transition) {
+                        nextTransition.runAnimators();
+                        transition.removeListener(this);
+                    }
+                });
+            }
+            Transition firstTransition = mTransitions.get(0);
+            if (firstTransition != null) {
+                firstTransition.runAnimators();
+            }
+        } else {
+            for (Transition childTransition : mTransitions) {
+                childTransition.runAnimators();
+            }
+        }
     }
 
     @Override
     public void captureStartValues(@NonNull TransitionValues transitionValues) {
-        mImpl.captureStartValues(transitionValues);
+        if (isValidTarget(transitionValues.view)) {
+            for (Transition childTransition : mTransitions) {
+                if (childTransition.isValidTarget(transitionValues.view)) {
+                    childTransition.captureStartValues(transitionValues);
+                    transitionValues.mTargetedTransitions.add(childTransition);
+                }
+            }
+        }
     }
 
     @Override
-    @Nullable
-    public Animator createAnimator(@NonNull ViewGroup sceneRoot,
-            @NonNull TransitionValues startValues, @NonNull TransitionValues endValues) {
-        return mImpl.createAnimator(sceneRoot, startValues, endValues);
+    public void captureEndValues(@NonNull TransitionValues transitionValues) {
+        if (isValidTarget(transitionValues.view)) {
+            for (Transition childTransition : mTransitions) {
+                if (childTransition.isValidTarget(transitionValues.view)) {
+                    childTransition.captureEndValues(transitionValues);
+                    transitionValues.mTargetedTransitions.add(childTransition);
+                }
+            }
+        }
+    }
+
+    /** @hide */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    public void pause(View sceneRoot) {
+        super.pause(sceneRoot);
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).pause(sceneRoot);
+        }
+    }
+
+    /** @hide */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    public void resume(View sceneRoot) {
+        super.resume(sceneRoot);
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).resume(sceneRoot);
+        }
+    }
+
+    /** @hide */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    protected void cancel() {
+        super.cancel();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).cancel();
+        }
+    }
+
+    @Override
+    TransitionSet setSceneRoot(ViewGroup sceneRoot) {
+        super.setSceneRoot(sceneRoot);
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).setSceneRoot(sceneRoot);
+        }
+        return this;
+    }
+
+    @Override
+    void setCanRemoveViews(boolean canRemoveViews) {
+        super.setCanRemoveViews(canRemoveViews);
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).setCanRemoveViews(canRemoveViews);
+        }
+    }
+
+    @Override
+    String toString(String indent) {
+        String result = super.toString(indent);
+        for (int i = 0; i < mTransitions.size(); ++i) {
+            result += "\n" + mTransitions.get(i).toString(indent + "  ");
+        }
+        return result;
+    }
+
+    @Override
+    public Transition clone() {
+        TransitionSet clone = (TransitionSet) super.clone();
+        clone.mTransitions = new ArrayList<>();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            clone.addTransition(mTransitions.get(i).clone());
+        }
+        return clone;
     }
 
 }
diff --git a/transition/base/android/support/transition/TransitionValues.java b/transition/src/android/support/transition/TransitionValues.java
similarity index 94%
rename from transition/base/android/support/transition/TransitionValues.java
rename to transition/src/android/support/transition/TransitionValues.java
index 8181ad4..aaec8d0 100644
--- a/transition/base/android/support/transition/TransitionValues.java
+++ b/transition/src/android/support/transition/TransitionValues.java
@@ -18,6 +18,7 @@
 
 import android.view.View;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -51,6 +52,11 @@
      */
     public View view;
 
+    /**
+     * The Transitions that targeted this view.
+     */
+    final ArrayList<Transition> mTargetedTransitions = new ArrayList<>();
+
     @Override
     public boolean equals(Object other) {
         if (other instanceof TransitionValues) {
diff --git a/transition/ics/android/support/transition/TransitionValuesMaps.java b/transition/src/android/support/transition/TransitionValuesMaps.java
similarity index 77%
rename from transition/ics/android/support/transition/TransitionValuesMaps.java
rename to transition/src/android/support/transition/TransitionValuesMaps.java
index ddf05da..98db792 100644
--- a/transition/ics/android/support/transition/TransitionValuesMaps.java
+++ b/transition/src/android/support/transition/TransitionValuesMaps.java
@@ -16,7 +16,6 @@
 
 package android.support.transition;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.support.v4.util.ArrayMap;
 import android.support.v4.util.LongSparseArray;
@@ -24,13 +23,14 @@
 import android.view.View;
 
 @RequiresApi(14)
-@TargetApi(14)
 class TransitionValuesMaps {
 
-    public ArrayMap<View, TransitionValues> viewValues = new ArrayMap<>();
+    final ArrayMap<View, TransitionValues> mViewValues = new ArrayMap<>();
 
-    public SparseArray<TransitionValues> idValues = new SparseArray<>();
+    final SparseArray<View> mIdValues = new SparseArray<>();
 
-    public LongSparseArray<TransitionValues> itemIdValues = new LongSparseArray<>();
+    final LongSparseArray<View> mItemIdValues = new LongSparseArray<>();
+
+    final ArrayMap<String, View> mNameValues = new ArrayMap<>();
 
 }
diff --git a/transition/src/android/support/transition/ViewGroupUtils.java b/transition/src/android/support/transition/ViewGroupUtils.java
new file mode 100644
index 0000000..370e3a3
--- /dev/null
+++ b/transition/src/android/support/transition/ViewGroupUtils.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.view.ViewGroup;
+
+/**
+ * Compatibility utilities for platform features of {@link ViewGroup}.
+ */
+class ViewGroupUtils {
+
+    private static final ViewGroupUtilsImpl IMPL;
+
+    static {
+        if (Build.VERSION.SDK_INT >= 18) {
+            IMPL = new ViewGroupUtilsApi18();
+        } else {
+            IMPL = new ViewGroupUtilsApi14();
+        }
+    }
+
+    /**
+     * Backward-compatible {@link ViewGroup#getOverlay()}.
+     */
+    static ViewGroupOverlayImpl getOverlay(@NonNull ViewGroup group) {
+        return IMPL.getOverlay(group);
+    }
+
+    /**
+     * Provides access to the hidden ViewGroup#suppressLayout method.
+     */
+    static void suppressLayout(@NonNull ViewGroup group, boolean suppress) {
+        IMPL.suppressLayout(group, suppress);
+    }
+
+}
diff --git a/transition/src/android/support/transition/ViewUtils.java b/transition/src/android/support/transition/ViewUtils.java
new file mode 100644
index 0000000..52186d8
--- /dev/null
+++ b/transition/src/android/support/transition/ViewUtils.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.view.View;
+
+/**
+ * Compatibility utilities for platform features of {@link View}.
+ */
+class ViewUtils {
+
+    private static final ViewUtilsImpl IMPL;
+
+    static {
+        if (Build.VERSION.SDK_INT >= 18) {
+            IMPL = new ViewUtilsApi18();
+        } else {
+            IMPL = new ViewUtilsApi14();
+        }
+    }
+
+    /**
+     * Backward-compatible {@link View#getOverlay()}.
+     */
+    static ViewOverlayImpl getOverlay(@NonNull View view) {
+        return IMPL.getOverlay(view);
+    }
+
+    /**
+     * Backward-compatible {@link View#getWindowId()}.
+     */
+    static WindowIdImpl getWindowId(@NonNull View view) {
+        return IMPL.getWindowId(view);
+    }
+
+}
diff --git a/transition/src/android/support/transition/Visibility.java b/transition/src/android/support/transition/Visibility.java
index 67b91ce..5522f6a 100644
--- a/transition/src/android/support/transition/Visibility.java
+++ b/transition/src/android/support/transition/Visibility.java
@@ -17,8 +17,8 @@
 package android.support.transition;
 
 import android.animation.Animator;
-import android.os.Build;
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -33,32 +33,48 @@
  * {@link #onAppear(ViewGroup, TransitionValues, int, TransitionValues, int)},
  * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)},
  */
-public abstract class Visibility extends Transition implements VisibilityInterface {
+public abstract class Visibility extends Transition {
+
+    private static final String PROPNAME_VISIBILITY = "android:visibility:visibility";
+    private static final String PROPNAME_PARENT = "android:visibility:parent";
+
+    private static final String[] sTransitionProperties = {
+            PROPNAME_VISIBILITY,
+            PROPNAME_PARENT,
+    };
+
+    private static class VisibilityInfo {
+        boolean mVisibilityChange;
+        boolean mFadeIn;
+        int mStartVisibility;
+        int mEndVisibility;
+        ViewGroup mStartParent;
+        ViewGroup mEndParent;
+    }
 
     public Visibility() {
-        this(false);
     }
 
-    Visibility(boolean deferred) {
-        super(true);
-        if (!deferred) {
-            if (Build.VERSION.SDK_INT >= 19) {
-                mImpl = new VisibilityKitKat();
-            } else {
-                mImpl = new VisibilityIcs();
-            }
-            mImpl.init(this);
-        }
-    }
-
+    @Nullable
     @Override
-    public void captureEndValues(@NonNull TransitionValues transitionValues) {
-        mImpl.captureEndValues(transitionValues);
+    public String[] getTransitionProperties() {
+        return sTransitionProperties;
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        int visibility = transitionValues.view.getVisibility();
+        transitionValues.values.put(PROPNAME_VISIBILITY, visibility);
+        transitionValues.values.put(PROPNAME_PARENT, transitionValues.view.getParent());
     }
 
     @Override
     public void captureStartValues(@NonNull TransitionValues transitionValues) {
-        mImpl.captureStartValues(transitionValues);
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(@NonNull TransitionValues transitionValues) {
+        captureValues(transitionValues);
     }
 
     /**
@@ -76,9 +92,96 @@
      * @return True if the view reference by <code>values</code> is visible,
      * false otherwise.
      */
-    @Override
     public boolean isVisible(TransitionValues values) {
-        return ((VisibilityImpl) mImpl).isVisible(values);
+        if (values == null) {
+            return false;
+        }
+        int visibility = (Integer) values.values.get(PROPNAME_VISIBILITY);
+        View parent = (View) values.values.get(PROPNAME_PARENT);
+
+        return visibility == View.VISIBLE && parent != null;
+    }
+
+    private VisibilityInfo getVisibilityChangeInfo(TransitionValues startValues,
+            TransitionValues endValues) {
+        final VisibilityInfo visInfo = new VisibilityInfo();
+        visInfo.mVisibilityChange = false;
+        visInfo.mFadeIn = false;
+        if (startValues != null) {
+            visInfo.mStartVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
+            visInfo.mStartParent = (ViewGroup) startValues.values.get(PROPNAME_PARENT);
+        } else {
+            visInfo.mStartVisibility = -1;
+            visInfo.mStartParent = null;
+        }
+        if (endValues != null) {
+            visInfo.mEndVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
+            visInfo.mEndParent = (ViewGroup) endValues.values.get(PROPNAME_PARENT);
+        } else {
+            visInfo.mEndVisibility = -1;
+            visInfo.mEndParent = null;
+        }
+        if (startValues != null && endValues != null) {
+            if (visInfo.mStartVisibility == visInfo.mEndVisibility
+                    && visInfo.mStartParent == visInfo.mEndParent) {
+                return visInfo;
+            } else {
+                if (visInfo.mStartVisibility != visInfo.mEndVisibility) {
+                    if (visInfo.mStartVisibility == View.VISIBLE) {
+                        visInfo.mFadeIn = false;
+                        visInfo.mVisibilityChange = true;
+                    } else if (visInfo.mEndVisibility == View.VISIBLE) {
+                        visInfo.mFadeIn = true;
+                        visInfo.mVisibilityChange = true;
+                    }
+                    // no visibilityChange if going between INVISIBLE and GONE
+                } else /* if (visInfo.mStartParent != visInfo.mEndParent) */ {
+                    if (visInfo.mEndParent == null) {
+                        visInfo.mFadeIn = false;
+                        visInfo.mVisibilityChange = true;
+                    } else if (visInfo.mStartParent == null) {
+                        visInfo.mFadeIn = true;
+                        visInfo.mVisibilityChange = true;
+                    }
+                }
+            }
+        }
+        if (startValues == null) {
+            visInfo.mFadeIn = true;
+            visInfo.mVisibilityChange = true;
+        } else if (endValues == null) {
+            visInfo.mFadeIn = false;
+            visInfo.mVisibilityChange = true;
+        }
+        return visInfo;
+    }
+
+    @Nullable
+    @Override
+    public Animator createAnimator(@NonNull ViewGroup sceneRoot,
+            @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) {
+        VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues);
+        if (visInfo.mVisibilityChange) {
+            // Only transition views that are either targets of this transition
+            // or whose parent hierarchies remain stable between scenes
+            boolean isTarget = false;
+            if (mTargets.size() > 0 || mTargetIds.size() > 0) {
+                View startView = startValues != null ? startValues.view : null;
+                View endView = endValues != null ? endValues.view : null;
+                isTarget = isValidTarget(startView) || isValidTarget(endView);
+            }
+            if (isTarget || ((visInfo.mStartParent != null || visInfo.mEndParent != null))) {
+                if (visInfo.mFadeIn) {
+                    return onAppear(sceneRoot, startValues, visInfo.mStartVisibility,
+                            endValues, visInfo.mEndVisibility);
+                } else {
+                    return onDisappear(sceneRoot, startValues, visInfo.mStartVisibility,
+                            endValues, visInfo.mEndVisibility
+                    );
+                }
+            }
+        }
+        return null;
     }
 
     /**
@@ -96,11 +199,10 @@
      * overall transition for this scene change. A null value means no animation
      * should be run.
      */
-    @Override
+    @SuppressWarnings("UnusedParameters")
     public Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues, int startVisibility,
             TransitionValues endValues, int endVisibility) {
-        return ((VisibilityImpl) mImpl).onAppear(sceneRoot, startValues, startVisibility,
-                endValues, endVisibility);
+        return null;
     }
 
     /**
@@ -118,11 +220,20 @@
      * overall transition for this scene change. A null value means no animation
      * should be run.
      */
-    @Override
+    @SuppressWarnings("UnusedParameters")
     public Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues,
             int startVisibility, TransitionValues endValues, int endVisibility) {
-        return ((VisibilityImpl) mImpl).onDisappear(sceneRoot, startValues, startVisibility,
-                endValues, endVisibility);
+        return null;
+    }
+
+    @Override
+    boolean areValuesChanged(TransitionValues oldValues, TransitionValues newValues) {
+        if (oldValues == null && newValues == null) {
+            return false;
+        }
+        VisibilityInfo changeInfo = getVisibilityChangeInfo(oldValues, newValues);
+        return changeInfo.mVisibilityChange && (changeInfo.mStartVisibility == View.VISIBLE
+                || changeInfo.mEndVisibility == View.VISIBLE);
     }
 
     // TODO: Implement API 21; onAppear (4 params), onDisappear (4 params), getMode, setMode
diff --git a/transition/tests/res/layout/activity_transition.xml b/transition/tests/res/layout/activity_transition.xml
index cfbbe61..cf25ef9 100644
--- a/transition/tests/res/layout/activity_transition.xml
+++ b/transition/tests/res/layout/activity_transition.xml
@@ -14,7 +14,9 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             android:id="@+id/root"
-             android:layout_width="match_parent"
-             android:layout_height="match_parent"/>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"/>
diff --git a/transition/tests/src/android/support/transition/AutoTransitionTest.java b/transition/tests/src/android/support/transition/AutoTransitionTest.java
new file mode 100644
index 0000000..137f6d3
--- /dev/null
+++ b/transition/tests/src/android/support/transition/AutoTransitionTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import android.graphics.Color;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.MediumTest;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@MediumTest
+public class AutoTransitionTest extends BaseTest {
+
+    private LinearLayout mRoot;
+    private View mView0;
+    private View mView1;
+
+    @UiThreadTest
+    @Before
+    public void setUp() {
+        mRoot = (LinearLayout) rule.getActivity().getRoot();
+        mView0 = new View(rule.getActivity());
+        mView0.setBackgroundColor(Color.RED);
+        mRoot.addView(mView0, new LinearLayout.LayoutParams(100, 100));
+        mView1 = new View(rule.getActivity());
+        mView1.setBackgroundColor(Color.BLUE);
+        mRoot.addView(mView1, new LinearLayout.LayoutParams(100, 100));
+    }
+
+    @Test
+    public void testLayoutBetweenFadeAndChangeBounds() throws Throwable {
+        final LayoutCounter counter = new LayoutCounter();
+        rule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertThat(mView1.getY(), is(100.f));
+                assertThat(mView0.getVisibility(), is(View.VISIBLE));
+                mView1.addOnLayoutChangeListener(counter);
+            }
+        });
+        final SyncTransitionListener listener = new SyncTransitionListener(
+                SyncTransitionListener.EVENT_END);
+        final Transition transition = new AutoTransition();
+        transition.addListener(listener);
+        rule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mRoot, transition);
+                // This makes view0 fade out and causes view1 to move upwards.
+                mView0.setVisibility(View.GONE);
+            }
+        });
+        assertThat("Timed out waiting for the TransitionListener",
+                listener.await(), is(true));
+        assertThat(mView1.getY(), is(0.f));
+        assertThat(mView0.getVisibility(), is(View.GONE));
+        counter.reset();
+        listener.reset();
+        rule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mRoot, transition);
+                // Revert
+                mView0.setVisibility(View.VISIBLE);
+            }
+        });
+        assertThat("Timed out waiting for the TransitionListener",
+                listener.await(), is(true));
+        assertThat(mView1.getY(), is(100.f));
+        assertThat(mView0.getVisibility(), is(View.VISIBLE));
+    }
+
+    private static class LayoutCounter implements View.OnLayoutChangeListener {
+
+        private int mCalledCount;
+
+        @Override
+        public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                int oldLeft, int oldTop, int oldRight, int oldBottom) {
+            mCalledCount++;
+            // There should not be more than one layout request to view1.
+            if (mCalledCount > 1) {
+                fail("View layout happened too many times");
+            }
+        }
+
+        void reset() {
+            mCalledCount = 0;
+        }
+
+    }
+
+}
diff --git a/transition/tests/src/android/support/transition/SyncRunnable.java b/transition/tests/src/android/support/transition/SyncRunnable.java
new file mode 100644
index 0000000..2e8a2e1
--- /dev/null
+++ b/transition/tests/src/android/support/transition/SyncRunnable.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+class SyncRunnable implements Runnable {
+
+    private final CountDownLatch mLatch = new CountDownLatch(1);
+
+    @Override
+    public void run() {
+        mLatch.countDown();
+    }
+
+    boolean await() {
+        try {
+            return mLatch.await(3000, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+        return false;
+    }
+
+}
diff --git a/transition/tests/src/android/support/transition/SyncTransitionListener.java b/transition/tests/src/android/support/transition/SyncTransitionListener.java
new file mode 100644
index 0000000..4d7e02e
--- /dev/null
+++ b/transition/tests/src/android/support/transition/SyncTransitionListener.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.transition;
+
+import android.support.annotation.NonNull;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This {@link Transition.TransitionListener} synchronously waits for the specified callback.
+ */
+class SyncTransitionListener implements Transition.TransitionListener {
+
+    static final int EVENT_START = 1;
+    static final int EVENT_END = 2;
+    static final int EVENT_CANCEL = 3;
+    static final int EVENT_PAUSE = 4;
+    static final int EVENT_RESUME = 5;
+
+    private final int mTargetEvent;
+    private CountDownLatch mLatch = new CountDownLatch(1);
+
+    SyncTransitionListener(int event) {
+        mTargetEvent = event;
+    }
+
+    boolean await() {
+        try {
+            return mLatch.await(3000, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            return false;
+        }
+    }
+
+    void reset() {
+        mLatch = new CountDownLatch(1);
+    }
+
+    @Override
+    public void onTransitionStart(@NonNull Transition transition) {
+        if (mTargetEvent == EVENT_START) {
+            mLatch.countDown();
+        }
+    }
+
+    @Override
+    public void onTransitionEnd(@NonNull Transition transition) {
+        if (mTargetEvent == EVENT_END) {
+            mLatch.countDown();
+        }
+    }
+
+    @Override
+    public void onTransitionCancel(@NonNull Transition transition) {
+        if (mTargetEvent == EVENT_CANCEL) {
+            mLatch.countDown();
+        }
+    }
+
+    @Override
+    public void onTransitionPause(@NonNull Transition transition) {
+        if (mTargetEvent == EVENT_PAUSE) {
+            mLatch.countDown();
+        }
+    }
+
+    @Override
+    public void onTransitionResume(@NonNull Transition transition) {
+        if (mTargetEvent == EVENT_RESUME) {
+            mLatch.countDown();
+        }
+    }
+}
diff --git a/transition/tests/src/android/support/transition/TransitionActivity.java b/transition/tests/src/android/support/transition/TransitionActivity.java
index ff9dbcc..43f03d3 100644
--- a/transition/tests/src/android/support/transition/TransitionActivity.java
+++ b/transition/tests/src/android/support/transition/TransitionActivity.java
@@ -20,17 +20,17 @@
 import android.os.Bundle;
 import android.support.transition.test.R;
 import android.view.ViewGroup;
-import android.widget.FrameLayout;
+import android.widget.LinearLayout;
 
 public class TransitionActivity extends Activity {
 
-    private FrameLayout mRoot;
+    private LinearLayout mRoot;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_transition);
-        mRoot = (FrameLayout) findViewById(R.id.root);
+        mRoot = (LinearLayout) findViewById(R.id.root);
     }
 
     ViewGroup getRoot() {
diff --git a/transition/tests/src/android/support/transition/TransitionManagerTest.java b/transition/tests/src/android/support/transition/TransitionManagerTest.java
index 21bf413..82fb17b 100644
--- a/transition/tests/src/android/support/transition/TransitionManagerTest.java
+++ b/transition/tests/src/android/support/transition/TransitionManagerTest.java
@@ -29,9 +29,6 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
 @MediumTest
 public class TransitionManagerTest extends BaseTest {
 
@@ -121,66 +118,4 @@
                 listener.await(), is(true));
     }
 
-    /**
-     * This {@link Transition.TransitionListener} synchronously waits for the specified callback.
-     */
-    private static class SyncTransitionListener implements Transition.TransitionListener {
-
-        static final int EVENT_START = 1;
-        static final int EVENT_END = 2;
-        static final int EVENT_CANCEL = 3;
-        static final int EVENT_PAUSE = 4;
-        static final int EVENT_RESUME = 5;
-
-        private final int mTargetEvent;
-        private final CountDownLatch mLatch = new CountDownLatch(1);
-
-        SyncTransitionListener(int event) {
-            mTargetEvent = event;
-        }
-
-        boolean await() {
-            try {
-                return mLatch.await(3000, TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-                return false;
-            }
-        }
-
-        @Override
-        public void onTransitionStart(Transition transition) {
-            if (mTargetEvent == EVENT_START) {
-                mLatch.countDown();
-            }
-        }
-
-        @Override
-        public void onTransitionEnd(Transition transition) {
-            if (mTargetEvent == EVENT_END) {
-                mLatch.countDown();
-            }
-        }
-
-        @Override
-        public void onTransitionCancel(Transition transition) {
-            if (mTargetEvent == EVENT_CANCEL) {
-                mLatch.countDown();
-            }
-        }
-
-        @Override
-        public void onTransitionPause(Transition transition) {
-            if (mTargetEvent == EVENT_PAUSE) {
-                mLatch.countDown();
-            }
-        }
-
-        @Override
-        public void onTransitionResume(Transition transition) {
-            if (mTargetEvent == EVENT_RESUME) {
-                mLatch.countDown();
-            }
-        }
-    }
-
 }
diff --git a/transition/tests/src/android/support/transition/TransitionSetTest.java b/transition/tests/src/android/support/transition/TransitionSetTest.java
new file mode 100644
index 0000000..aec9ecb
--- /dev/null
+++ b/transition/tests/src/android/support/transition/TransitionSetTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
+
+import android.support.test.filters.MediumTest;
+import android.support.transition.test.R;
+import android.view.View;
+
+import org.junit.Before;
+import org.junit.Test;
+
+@MediumTest
+public class TransitionSetTest extends BaseTest {
+
+    private final TransitionSet mTransitionSet = new TransitionSet();
+    private final Transition mTransition = new TransitionTest.EmptyTransition();
+
+    @Before
+    public void setUp() {
+        // mTransitionSet has 1 item from the start
+        mTransitionSet.addTransition(mTransition);
+    }
+
+    @Test
+    public void testOrdering() {
+        assertThat(mTransitionSet.getOrdering(), is(TransitionSet.ORDERING_TOGETHER));
+        assertThat(mTransitionSet.setOrdering(TransitionSet.ORDERING_SEQUENTIAL),
+                is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getOrdering(), is(TransitionSet.ORDERING_SEQUENTIAL));
+    }
+
+    @Test
+    public void testAddAndRemoveTransition() {
+        assertThat(mTransitionSet.getTransitionCount(), is(1));
+        assertThat(mTransitionSet.getTransitionAt(0), is(sameInstance(mTransition)));
+        Transition anotherTransition = new TransitionTest.EmptyTransition();
+        assertThat(mTransitionSet.addTransition(anotherTransition),
+                is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTransitionCount(), is(2));
+        assertThat(mTransitionSet.getTransitionAt(0), is(sameInstance(mTransition)));
+        assertThat(mTransitionSet.getTransitionAt(1), is(sameInstance(anotherTransition)));
+        assertThat(mTransitionSet.removeTransition(mTransition),
+                is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTransitionCount(), is(1));
+    }
+
+    @Test
+    public void testSetDuration() {
+        assertThat(mTransitionSet.setDuration(123), is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getDuration(), is(123L));
+        assertThat(mTransition.getDuration(), is(123L));
+    }
+
+    @Test
+    public void testTargetId() {
+        assertThat(mTransitionSet.addTarget(R.id.view0), is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTargetIds(), hasItem(R.id.view0));
+        assertThat(mTransitionSet.getTargetIds(), hasSize(1));
+        assertThat(mTransition.getTargetIds(), hasItem(R.id.view0));
+        assertThat(mTransition.getTargetIds(), hasSize(1));
+        assertThat(mTransitionSet.removeTarget(R.id.view0), is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTargetIds(), hasSize(0));
+        assertThat(mTransition.getTargetIds(), hasSize(0));
+    }
+
+    @Test
+    public void testTargetView() {
+        final View view = new View(rule.getActivity());
+        assertThat(mTransitionSet.addTarget(view), is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTargets(), hasItem(view));
+        assertThat(mTransitionSet.getTargets(), hasSize(1));
+        assertThat(mTransition.getTargets(), hasItem(view));
+        assertThat(mTransition.getTargets(), hasSize(1));
+        assertThat(mTransitionSet.removeTarget(view), is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTargets(), hasSize(0));
+        assertThat(mTransition.getTargets(), hasSize(0));
+    }
+
+    @Test
+    public void testTargetName() {
+        assertThat(mTransitionSet.addTarget("abc"), is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTargetNames(), hasItem("abc"));
+        assertThat(mTransitionSet.getTargetNames(), hasSize(1));
+        assertThat(mTransition.getTargetNames(), hasItem("abc"));
+        assertThat(mTransition.getTargetNames(), hasSize(1));
+        assertThat(mTransitionSet.removeTarget("abc"), is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTargetNames(), hasSize(0));
+        assertThat(mTransition.getTargetNames(), hasSize(0));
+    }
+
+    @Test
+    public void testTargetClass() {
+        assertThat(mTransitionSet.addTarget(View.class), is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTargetTypes(), hasItem(View.class));
+        assertThat(mTransitionSet.getTargetTypes(), hasSize(1));
+        assertThat(mTransition.getTargetTypes(), hasItem(View.class));
+        assertThat(mTransition.getTargetTypes(), hasSize(1));
+        assertThat(mTransitionSet.removeTarget(View.class), is(sameInstance(mTransitionSet)));
+        assertThat(mTransitionSet.getTargetTypes(), hasSize(0));
+        assertThat(mTransition.getTargetTypes(), hasSize(0));
+    }
+
+}
diff --git a/transition/tests/src/android/support/transition/TransitionTest.java b/transition/tests/src/android/support/transition/TransitionTest.java
index 0e87629..03623b5 100644
--- a/transition/tests/src/android/support/transition/TransitionTest.java
+++ b/transition/tests/src/android/support/transition/TransitionTest.java
@@ -16,22 +16,38 @@
 
 package android.support.transition;
 
+
+import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.sameInstance;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 
 import android.animation.Animator;
+import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.MediumTest;
 import android.support.transition.test.R;
+import android.support.v4.view.ViewCompat;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.LinearInterpolator;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
 
+import org.junit.Before;
 import org.junit.Test;
 
 import java.util.List;
@@ -39,6 +55,24 @@
 @MediumTest
 public class TransitionTest extends BaseTest {
 
+    private Scene[] mScenes = new Scene[2];
+    private View[] mViews = new View[3];
+
+    @Before
+    public void prepareScenes() {
+        TransitionActivity activity = rule.getActivity();
+        ViewGroup root = activity.getRoot();
+        mScenes[0] = Scene.getSceneForLayout(root, R.layout.scene0, activity);
+        mScenes[1] = Scene.getSceneForLayout(root, R.layout.scene1, activity);
+    }
+
+    @Test
+    public void testName() {
+        Transition transition = new EmptyTransition();
+        assertThat(transition.getName(),
+                is(equalTo("android.support.transition.TransitionTest$EmptyTransition")));
+    }
+
     @Test
     public void testDuration() {
         Transition transition = new EmptyTransition();
@@ -81,7 +115,7 @@
 
     @Test
     @UiThreadTest
-    public void testTargets() {
+    public void testTargetView() {
         // Set up views
         TransitionActivity activity = rule.getActivity();
         ViewGroup root = activity.getRoot();
@@ -105,6 +139,99 @@
     }
 
     @Test
+    public void testTargetName() {
+        Transition transition = new EmptyTransition();
+        assertThat(transition.addTarget("a"), is(sameInstance(transition)));
+        assertThat(transition.addTarget("b"), is(sameInstance(transition)));
+        List<String> targetNames = transition.getTargetNames();
+        assertNotNull(targetNames);
+        assertThat(targetNames.size(), is(2));
+        assertThat(targetNames, hasItem("a"));
+        assertThat(targetNames, hasItem("b"));
+        transition.removeTarget("a");
+        assertThat(targetNames.size(), is(1));
+        assertThat(targetNames, not(hasItem("a")));
+        assertThat(targetNames, hasItem("b"));
+    }
+
+    @Test
+    public void testTargetType() {
+        Transition transition = new EmptyTransition();
+        assertThat(transition.addTarget(Button.class), is(sameInstance(transition)));
+        assertThat(transition.addTarget(ImageView.class), is(sameInstance(transition)));
+        List<Class> targetTypes = transition.getTargetTypes();
+        assertNotNull(targetTypes);
+        assertThat(targetTypes.size(), is(2));
+        assertThat(targetTypes, hasItem(Button.class));
+        assertThat(targetTypes, hasItem(ImageView.class));
+        transition.removeTarget(Button.class);
+        assertThat(targetTypes.size(), is(1));
+        assertThat(targetTypes, not(hasItem(Button.class)));
+        assertThat(targetTypes, hasItem(ImageView.class));
+    }
+
+    @Test
+    public void testExcludeTargetId() throws Throwable {
+        showInitialScene();
+        Transition transition = new EmptyTransition();
+        transition.addTarget(R.id.view0);
+        transition.addTarget(R.id.view1);
+        View view0 = rule.getActivity().findViewById(R.id.view0);
+        View view1 = rule.getActivity().findViewById(R.id.view1);
+        assertThat(transition.isValidTarget(view0), is(true));
+        assertThat(transition.isValidTarget(view1), is(true));
+        transition.excludeTarget(R.id.view0, true);
+        assertThat(transition.isValidTarget(view0), is(false));
+        assertThat(transition.isValidTarget(view1), is(true));
+    }
+
+    @Test
+    public void testExcludeTargetView() throws Throwable {
+        showInitialScene();
+        Transition transition = new EmptyTransition();
+        View view0 = rule.getActivity().findViewById(R.id.view0);
+        View view1 = rule.getActivity().findViewById(R.id.view1);
+        transition.addTarget(view0);
+        transition.addTarget(view1);
+        assertThat(transition.isValidTarget(view0), is(true));
+        assertThat(transition.isValidTarget(view1), is(true));
+        transition.excludeTarget(view0, true);
+        assertThat(transition.isValidTarget(view0), is(false));
+        assertThat(transition.isValidTarget(view1), is(true));
+    }
+
+    @Test
+    public void testExcludeTargetName() throws Throwable {
+        showInitialScene();
+        Transition transition = new EmptyTransition();
+        View view0 = rule.getActivity().findViewById(R.id.view0);
+        View view1 = rule.getActivity().findViewById(R.id.view1);
+        ViewCompat.setTransitionName(view0, "zero");
+        ViewCompat.setTransitionName(view1, "one");
+        transition.addTarget("zero");
+        transition.addTarget("one");
+        assertThat(transition.isValidTarget(view0), is(true));
+        assertThat(transition.isValidTarget(view1), is(true));
+        transition.excludeTarget("zero", true);
+        assertThat(transition.isValidTarget(view0), is(false));
+        assertThat(transition.isValidTarget(view1), is(true));
+    }
+
+    @Test
+    public void testExcludeTargetType() throws Throwable {
+        showInitialScene();
+        Transition transition = new EmptyTransition();
+        FrameLayout container = (FrameLayout) rule.getActivity().findViewById(R.id.container);
+        View view0 = rule.getActivity().findViewById(R.id.view0);
+        transition.addTarget(View.class);
+        assertThat(transition.isValidTarget(container), is(true));
+        assertThat(transition.isValidTarget(view0), is(true));
+        transition.excludeTarget(FrameLayout.class, true);
+        assertThat(transition.isValidTarget(container), is(false));
+        assertThat(transition.isValidTarget(view0), is(true));
+    }
+
+    @Test
     public void testListener() {
         Transition transition = new EmptyTransition();
         Transition.TransitionListener listener = new EmptyTransitionListener();
@@ -112,16 +239,90 @@
         assertThat(transition.removeListener(listener), is(sameInstance(transition)));
     }
 
+    @Test
+    public void testMatchOrder() throws Throwable {
+        showInitialScene();
+        final Transition transition = new ChangeBounds() {
+            @Nullable
+            @Override
+            public Animator createAnimator(@NonNull ViewGroup sceneRoot,
+                    @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) {
+                if (startValues != null && endValues != null) {
+                    fail("Match by View ID should be prevented");
+                }
+                return super.createAnimator(sceneRoot, startValues, endValues);
+            }
+        };
+        transition.setDuration(0);
+        // This prevents matches between start and end scenes because they have different set of
+        // View instances. They will be regarded as independent views even though they share the
+        // same View IDs.
+        transition.setMatchOrder(Transition.MATCH_INSTANCE);
+        SyncRunnable enter1 = new SyncRunnable();
+        mScenes[1].setEnterAction(enter1);
+        goToScene(mScenes[1], transition);
+        if (!enter1.await()) {
+            fail("Timed out while waiting for scene change");
+        }
+    }
+
+    @Test
+    public void testExcludedTransitionAnimator() throws Throwable {
+        showInitialScene();
+        final Animator.AnimatorListener animatorListener = mock(Animator.AnimatorListener.class);
+        final DummyTransition transition = new DummyTransition(animatorListener);
+        final SyncTransitionListener transitionListener = new SyncTransitionListener(
+                SyncTransitionListener.EVENT_END);
+        transition.addListener(transitionListener);
+        transition.addTarget(mViews[0]);
+        transition.excludeTarget(mViews[0], true);
+        rule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(rule.getActivity().getRoot(), transition);
+                mViews[0].setTranslationX(3.f);
+            }
+        });
+        if (!transitionListener.await()) {
+            fail("Timed out waiting for the TransitionListener");
+        }
+        verify(animatorListener, never()).onAnimationStart(any(Animator.class));
+    }
+
+    private void showInitialScene() throws Throwable {
+        SyncRunnable enter0 = new SyncRunnable();
+        mScenes[0].setEnterAction(enter0);
+        AutoTransition transition1 = new AutoTransition();
+        transition1.setDuration(0);
+        goToScene(mScenes[0], transition1);
+        if (!enter0.await()) {
+            fail("Timed out while waiting for scene change");
+        }
+        mViews[0] = rule.getActivity().findViewById(R.id.view0);
+        mViews[1] = rule.getActivity().findViewById(R.id.view1);
+        mViews[2] = rule.getActivity().findViewById(R.id.view2);
+    }
+
+    private void goToScene(final Scene scene, final Transition transition) throws Throwable {
+        rule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.go(scene, transition);
+            }
+        });
+    }
+
     public static class EmptyTransition extends Transition {
 
-        public void captureEndValues(TransitionValues transitionValues) {
+        public void captureEndValues(@NonNull TransitionValues transitionValues) {
         }
 
-        public void captureStartValues(TransitionValues transitionValues) {
+        public void captureStartValues(@NonNull TransitionValues transitionValues) {
         }
 
-        public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
-                TransitionValues endValues) {
+        public Animator createAnimator(@NonNull ViewGroup sceneRoot,
+                @Nullable TransitionValues startValues,
+                @Nullable TransitionValues endValues) {
             return null;
         }
 
@@ -129,21 +330,55 @@
 
     public static class EmptyTransitionListener implements Transition.TransitionListener {
 
-        public void onTransitionStart(Transition transition) {
+        public void onTransitionStart(@NonNull Transition transition) {
         }
 
-        public void onTransitionEnd(Transition transition) {
+        public void onTransitionEnd(@NonNull Transition transition) {
         }
 
-        public void onTransitionCancel(Transition transition) {
+        public void onTransitionCancel(@NonNull Transition transition) {
         }
 
-        public void onTransitionPause(Transition transition) {
+        public void onTransitionPause(@NonNull Transition transition) {
         }
 
-        public void onTransitionResume(Transition transition) {
+        public void onTransitionResume(@NonNull Transition transition) {
         }
 
     }
 
+    /**
+     * A dummy transition for monitoring use of its animator by the Transition framework.
+     */
+    private static class DummyTransition extends Transition {
+
+        private final Animator.AnimatorListener mListener;
+
+        DummyTransition(Animator.AnimatorListener listener) {
+            mListener = listener;
+        }
+
+        @Override
+        public void captureStartValues(@NonNull TransitionValues transitionValues) {
+            transitionValues.values.put("state", 1);
+        }
+
+        @Override
+        public void captureEndValues(@NonNull TransitionValues transitionValues) {
+            transitionValues.values.put("state", 2);
+        }
+
+        @Override
+        public Animator createAnimator(@NonNull ViewGroup sceneRoot, TransitionValues startValues,
+                TransitionValues endValues) {
+            if (startValues == null || endValues == null) {
+                return null;
+            }
+            final ObjectAnimator animator = ObjectAnimator
+                    .ofFloat(startValues.view, "translationX", 1.f, 2.f);
+            animator.addListener(mListener);
+            return animator;
+        }
+
+    }
 }
diff --git a/transition/tests/src/android/support/transition/VisibilityTest.java b/transition/tests/src/android/support/transition/VisibilityTest.java
new file mode 100644
index 0000000..4897a85
--- /dev/null
+++ b/transition/tests/src/android/support/transition/VisibilityTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.transition;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.MediumTest;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+@MediumTest
+public class VisibilityTest extends BaseTest {
+
+    private View mView;
+    private ViewGroup mRoot;
+
+    @UiThreadTest
+    @Before
+    public void setUp() {
+        mRoot = rule.getActivity().getRoot();
+        mView = new View(rule.getActivity());
+        mRoot.addView(mView, new ViewGroup.LayoutParams(100, 100));
+    }
+
+    @Test
+    @UiThreadTest
+    public void testCustomVisibility() {
+        final CustomVisibility visibility = new CustomVisibility();
+        assertThat(visibility.getName(), is(equalTo(CustomVisibility.class.getName())));
+        assertNotNull(visibility.getTransitionProperties());
+
+        // Capture start values
+        mView.setScaleX(0.5f);
+        final TransitionValues startValues = new TransitionValues();
+        startValues.view = mView;
+        visibility.captureStartValues(startValues);
+        assertThat((float) startValues.values.get(CustomVisibility.PROPNAME_SCALE_X), is(0.5f));
+
+        // Hide the view and capture end values
+        mView.setVisibility(View.GONE);
+        final TransitionValues endValues = new TransitionValues();
+        endValues.view = mView;
+        visibility.captureEndValues(endValues);
+
+        // This should invoke onDisappear, not onAppear
+        ObjectAnimator animator = (ObjectAnimator) visibility
+                .createAnimator(mRoot, startValues, endValues);
+        assertNotNull(animator);
+        assertThat(animator.getPropertyName(), is(equalTo("scaleX")));
+
+        // Jump to the end of the animation
+        animator.end();
+
+        // This value confirms that onDisappear, not onAppear, was called
+        assertThat((float) animator.getAnimatedValue(), is(0.25f));
+    }
+
+    public static class CustomVisibility extends Visibility {
+
+        static final String PROPNAME_SCALE_X = "customVisibility:scaleX";
+
+        private static String[] sTransitionProperties;
+
+        @Nullable
+        @Override
+        public String[] getTransitionProperties() {
+            if (sTransitionProperties == null) {
+                String[] properties = super.getTransitionProperties();
+                if (properties != null) {
+                    sTransitionProperties = Arrays.copyOf(properties, properties.length + 1);
+                } else {
+                    sTransitionProperties = new String[1];
+                }
+                sTransitionProperties[sTransitionProperties.length - 1] = PROPNAME_SCALE_X;
+            }
+            return sTransitionProperties;
+        }
+
+        @Override
+        public void captureStartValues(@NonNull TransitionValues transitionValues) {
+            super.captureStartValues(transitionValues);
+            transitionValues.values.put(PROPNAME_SCALE_X, transitionValues.view.getScaleX());
+        }
+
+        @Override
+        public Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues,
+                int startVisibility, TransitionValues endValues, int endVisibility) {
+            if (startValues == null) {
+                return null;
+            }
+            float startScaleX = (float) startValues.values.get(PROPNAME_SCALE_X);
+            return ObjectAnimator.ofFloat(startValues.view, "scaleX", startScaleX, 0.75f);
+        }
+
+        @Override
+        public Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues,
+                int startVisibility, TransitionValues endValues, int endVisibility) {
+            if (startValues == null) {
+                return null;
+            }
+            float startScaleX = (float) startValues.values.get(PROPNAME_SCALE_X);
+            return ObjectAnimator.ofFloat(startValues.view, "scaleX", startScaleX, 0.25f);
+        }
+
+    }
+
+}
diff --git a/documents-archive/Android.mk b/tv-provider/Android.mk
similarity index 67%
copy from documents-archive/Android.mk
copy to tv-provider/Android.mk
index 32ec7d6..4fa8af4 100644
--- a/documents-archive/Android.mk
+++ b/tv-provider/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 The Android Open Source Project
+# Copyright (C) 2017 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.
@@ -15,24 +15,19 @@
 LOCAL_PATH := $(call my-dir)
 
 # Here is the final static library that apps can link against.
-# Applications that use this library must specify
+# Applications that use this library must include it with
 #
-#   LOCAL_STATIC_ANDROID_LIBRARIES := \
-#       android-support-documents-archive \
-#       android-support-v4 \
-#       android-support-annotations
+#   LOCAL_STATIC_ANDROID_LIBRARIES := android-support-tv-provider
 #
-# in their makefiles to include the resources and their dependencies in their package.
 include $(CLEAR_VARS)
 LOCAL_USE_AAPT2 := true
-LOCAL_MODULE := android-support-documents-archive
+LOCAL_MODULE := android-support-tv-provider
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 LOCAL_SHARED_ANDROID_LIBRARIES := \
-    android-support-annotations \
-    android-support-v4
+    android-support-compat \
+    android-support-annotations
 LOCAL_JAR_EXCLUDE_FILES := none
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
diff --git a/v7/palette/src/main/AndroidManifest.xml b/tv-provider/AndroidManifest.xml
similarity index 84%
copy from v7/palette/src/main/AndroidManifest.xml
copy to tv-provider/AndroidManifest.xml
index 52e90a2..e479417 100644
--- a/v7/palette/src/main/AndroidManifest.xml
+++ b/tv-provider/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2017 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.
@@ -14,8 +14,8 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.v7.palette">
-    <uses-sdk android:minSdkVersion="9"/>
+          package="android.support.media.tv">
+    <uses-sdk android:minSdkVersion="21"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/tv-provider/build.gradle b/tv-provider/build.gradle
new file mode 100644
index 0000000..23146c9
--- /dev/null
+++ b/tv-provider/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: android.support.SupportLibraryPlugin
+archivesBaseName = 'support-tv-provider'
+
+dependencies {
+    compile project(':support-annotations')
+    compile project(':support-compat')
+    androidTestCompile (libs.test_runner) {
+        exclude module: 'support-annotations'
+    }
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 21
+    }
+
+    sourceSets {
+        main.java.srcDirs = ['src']
+        main.res.srcDir 'res'
+    }
+}
+
+supportLibrary {
+    name 'Android Support TV Provider'
+    inceptionYear '2017'
+    description 'Android Support Library for TV Provider'
+}
\ No newline at end of file
diff --git a/tv-provider/src/android/support/media/tv/Channel.java b/tv-provider/src/android/support/media/tv/Channel.java
new file mode 100644
index 0000000..45b8d8b
--- /dev/null
+++ b/tv-provider/src/android/support/media/tv/Channel.java
@@ -0,0 +1,962 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.tv;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.ContentValues;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.support.annotation.RestrictTo;
+import android.support.media.tv.TvContractCompat.Channels;
+import android.support.v4.os.BuildCompat;
+import android.text.TextUtils;
+
+import java.net.URISyntaxException;
+
+/**
+ * A convenience class to create and insert channel entries into the database.
+ */
+public final class Channel {
+    /**
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static final String[] PROJECTION = getProjection();
+
+    private static final long INVALID_CHANNEL_ID = -1;
+    private static final int INVALID_INTEGER_VALUE = -1;
+    private static final int IS_SEARCHABLE = 1;
+    private static final int IS_TRANSIENT = 1;
+
+    private final long mId;
+    private final String mPackageName;
+    private final String mInputId;
+    private final String mType;
+    private final String mDisplayNumber;
+    private final String mDisplayName;
+    private final String mDescription;
+    private final String mChannelLogo;
+    private final String mVideoFormat;
+    private final int mOriginalNetworkId;
+    private final int mTransportStreamId;
+    private final int mServiceId;
+    private final String mAppLinkText;
+    private final int mAppLinkColor;
+    private final Uri mAppLinkIconUri;
+    private final Uri mAppLinkPosterArtUri;
+    private final Uri mAppLinkIntentUri;
+    private final byte[] mInternalProviderData;
+    private final String mNetworkAffiliation;
+    private final int mSearchable;
+    private final String mServiceType;
+    private final Long mInternalProviderFlag1;
+    private final Long mInternalProviderFlag2;
+    private final Long mInternalProviderFlag3;
+    private final Long mInternalProviderFlag4;
+    private final int mTransient;
+
+    private Channel(Builder builder) {
+        mId = builder.mId;
+        mPackageName = builder.mPackageName;
+        mInputId = builder.mInputId;
+        mType = builder.mType;
+        mDisplayNumber = builder.mDisplayNumber;
+        mDisplayName = builder.mDisplayName;
+        mDescription = builder.mDescription;
+        mVideoFormat = builder.mVideoFormat;
+        mOriginalNetworkId = builder.mOriginalNetworkId;
+        mTransportStreamId = builder.mTransportStreamId;
+        mServiceId = builder.mServiceId;
+        mAppLinkText = builder.mAppLinkText;
+        mAppLinkColor = builder.mAppLinkColor;
+        mAppLinkIconUri = builder.mAppLinkIconUri;
+        mAppLinkPosterArtUri = builder.mAppLinkPosterArtUri;
+        mAppLinkIntentUri = builder.mAppLinkIntentUri;
+        mChannelLogo = builder.mChannelLogo;
+        mInternalProviderData = builder.mInternalProviderData;
+        mNetworkAffiliation = builder.mNetworkAffiliation;
+        mSearchable = builder.mSearchable;
+        mServiceType = builder.mServiceType;
+        mInternalProviderFlag1 = builder.mInternalProviderFlag1;
+        mInternalProviderFlag2 = builder.mInternalProviderFlag2;
+        mInternalProviderFlag3 = builder.mInternalProviderFlag3;
+        mInternalProviderFlag4 = builder.mInternalProviderFlag4;
+        mTransient = builder.mTransient;
+    }
+
+    /**
+     * @return The value of {@link Channels#_ID} for the channel.
+     */
+    public long getId() {
+        return mId;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_PACKAGE_NAME} for the channel.
+     */
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_INPUT_ID} for the channel.
+     */
+    public String getInputId() {
+        return mInputId;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_TYPE} for the channel.
+     */
+    public String getType() {
+        return mType;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_DISPLAY_NUMBER} for the channel.
+     */
+    public String getDisplayNumber() {
+        return mDisplayNumber;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_DISPLAY_NAME} for the channel.
+     */
+    public String getDisplayName() {
+        return mDisplayName;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_DESCRIPTION} for the channel.
+     */
+    public String getDescription() {
+        return mDescription;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_VIDEO_FORMAT} for the channel.
+     */
+    public String getVideoFormat() {
+        return mVideoFormat;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_ORIGINAL_NETWORK_ID} for the channel.
+     */
+    public int getOriginalNetworkId() {
+        return mOriginalNetworkId;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_TRANSPORT_STREAM_ID} for the channel.
+     */
+    public int getTransportStreamId() {
+        return mTransportStreamId;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_SERVICE_ID} for the channel.
+     */
+    public int getServiceId() {
+        return mServiceId;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_APP_LINK_TEXT} for the channel.
+     */
+    public String getAppLinkText() {
+        return mAppLinkText;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_APP_LINK_COLOR} for the channel.
+     */
+    public int getAppLinkColor() {
+        return mAppLinkColor;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_APP_LINK_ICON_URI} for the channel.
+     */
+    public Uri getAppLinkIconUri() {
+        return mAppLinkIconUri;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_APP_LINK_POSTER_ART_URI} for the channel.
+     */
+    public Uri getAppLinkPosterArtUri() {
+        return mAppLinkPosterArtUri;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_APP_LINK_INTENT_URI} for the channel.
+     */
+    public Uri getAppLinkIntentUri() {
+        return mAppLinkIntentUri;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_APP_LINK_INTENT_URI} for the program.
+     */
+    public Intent getAppLinkIntent() throws URISyntaxException {
+        return Intent.parseUri(mAppLinkIntentUri.toString(), Intent.URI_INTENT_SCHEME);
+    }
+
+
+    /**
+     * @return The value of {@link Channels.Logo} for the channel.
+     */
+    public String getChannelLogo() {
+        return mChannelLogo;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_NETWORK_AFFILIATION} for the channel.
+     */
+    public String getNetworkAffiliation() {
+        return mNetworkAffiliation;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_SEARCHABLE} for the channel.
+     */
+    public boolean isSearchable() {
+        return mSearchable == IS_SEARCHABLE;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_DATA} for the channel.
+     */
+    public byte[] getInternalProviderDataByteArray() {
+        return mInternalProviderData;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_SERVICE_TYPE} for the channel.
+     *
+     * <p>Returns {@link Channels#SERVICE_TYPE_AUDIO}, {@link Channels#SERVICE_TYPE_AUDIO_VIDEO}, or
+     * {@link Channels#SERVICE_TYPE_OTHER}.
+     */
+    public String getServiceType() {
+        return mServiceType;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_FLAG1} for the channel.
+     */
+    public Long getInternalProviderFlag1() {
+        return mInternalProviderFlag1;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_FLAG2} for the channel.
+     */
+    public Long getInternalProviderFlag2() {
+        return mInternalProviderFlag2;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_FLAG3} for the channel.
+     */
+    public Long getInternalProviderFlag3() {
+        return mInternalProviderFlag3;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_FLAG4} for the channel.
+     */
+    public Long getInternalProviderFlag4() {
+        return mInternalProviderFlag4;
+    }
+
+    /**
+     * @return The value of {@link Channels#COLUMN_TRANSIENT} for the channel.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public boolean isTransient() {
+        return mTransient == IS_TRANSIENT;
+    }
+
+    @Override
+    public String toString() {
+        return "Channel{"
+                + "id=" + mId
+                + ", packageName=" + mPackageName
+                + ", inputId=" + mInputId
+                + ", originalNetworkId=" + mOriginalNetworkId
+                + ", type=" + mType
+                + ", displayNumber=" + mDisplayNumber
+                + ", displayName=" + mDisplayName
+                + ", description=" + mDescription
+                + ", channelLogo=" + mChannelLogo
+                + ", videoFormat=" + mVideoFormat
+                + ", appLinkText=" + mAppLinkText + "}";
+    }
+
+    /**
+     * @return The fields of the Channel in the ContentValues format to be easily inserted into the
+     * TV Input Framework database.
+     */
+    public ContentValues toContentValues() {
+        ContentValues values = new ContentValues();
+        if (mId != INVALID_CHANNEL_ID) {
+            values.put(Channels._ID, mId);
+        }
+        if (!TextUtils.isEmpty(mPackageName)) {
+            values.put(Channels.COLUMN_PACKAGE_NAME, mPackageName);
+        } else {
+            values.putNull(Channels.COLUMN_PACKAGE_NAME);
+        }
+        if (!TextUtils.isEmpty(mInputId)) {
+            values.put(Channels.COLUMN_INPUT_ID, mInputId);
+        } else {
+            values.putNull(Channels.COLUMN_INPUT_ID);
+        }
+        if (!TextUtils.isEmpty(mType)) {
+            values.put(Channels.COLUMN_TYPE, mType);
+        } else {
+            values.putNull(Channels.COLUMN_TYPE);
+        }
+        if (!TextUtils.isEmpty(mDisplayNumber)) {
+            values.put(Channels.COLUMN_DISPLAY_NUMBER, mDisplayNumber);
+        } else {
+            values.putNull(Channels.COLUMN_DISPLAY_NUMBER);
+        }
+        if (!TextUtils.isEmpty(mDisplayName)) {
+            values.put(Channels.COLUMN_DISPLAY_NAME, mDisplayName);
+        } else {
+            values.putNull(Channels.COLUMN_DISPLAY_NAME);
+        }
+        if (!TextUtils.isEmpty(mDescription)) {
+            values.put(Channels.COLUMN_DESCRIPTION, mDescription);
+        } else {
+            values.putNull(Channels.COLUMN_DESCRIPTION);
+        }
+        if (!TextUtils.isEmpty(mVideoFormat)) {
+            values.put(Channels.COLUMN_VIDEO_FORMAT, mVideoFormat);
+        } else {
+            values.putNull(Channels.COLUMN_VIDEO_FORMAT);
+        }
+        if (mInternalProviderData != null && mInternalProviderData.length > 0) {
+            values.put(Channels.COLUMN_INTERNAL_PROVIDER_DATA,
+                    mInternalProviderData);
+        } else {
+            values.putNull(Channels.COLUMN_INTERNAL_PROVIDER_DATA);
+        }
+        values.put(Channels.COLUMN_ORIGINAL_NETWORK_ID, mOriginalNetworkId);
+        values.put(Channels.COLUMN_TRANSPORT_STREAM_ID, mTransportStreamId);
+        values.put(Channels.COLUMN_SERVICE_ID, mServiceId);
+        values.put(Channels.COLUMN_NETWORK_AFFILIATION, mNetworkAffiliation);
+        values.put(Channels.COLUMN_SEARCHABLE, mSearchable);
+        values.put(Channels.COLUMN_SERVICE_TYPE, mServiceType);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            values.put(Channels.COLUMN_APP_LINK_COLOR, mAppLinkColor);
+            if (!TextUtils.isEmpty(mAppLinkText)) {
+                values.put(Channels.COLUMN_APP_LINK_TEXT, mAppLinkText);
+            } else {
+                values.putNull(Channels.COLUMN_APP_LINK_TEXT);
+            }
+            if (mAppLinkIconUri != null) {
+                values.put(Channels.COLUMN_APP_LINK_ICON_URI, mAppLinkIconUri.toString());
+            } else {
+                values.putNull(Channels.COLUMN_APP_LINK_ICON_URI);
+            }
+            if (mAppLinkPosterArtUri != null) {
+                values.put(Channels.COLUMN_APP_LINK_POSTER_ART_URI,
+                        mAppLinkPosterArtUri.toString());
+            } else {
+                values.putNull(Channels.COLUMN_APP_LINK_POSTER_ART_URI);
+            }
+            if (mAppLinkIntentUri != null) {
+                values.put(Channels.COLUMN_APP_LINK_INTENT_URI, mAppLinkIntentUri.toString());
+            } else {
+                values.putNull(Channels.COLUMN_APP_LINK_INTENT_URI);
+            }
+            if (mInternalProviderFlag1 != null) {
+                values.put(Channels.COLUMN_INTERNAL_PROVIDER_FLAG1, mInternalProviderFlag1);
+            }
+            if (mInternalProviderFlag2 != null) {
+                values.put(Channels.COLUMN_INTERNAL_PROVIDER_FLAG2, mInternalProviderFlag2);
+            }
+            if (mInternalProviderFlag3 != null) {
+                values.put(Channels.COLUMN_INTERNAL_PROVIDER_FLAG3, mInternalProviderFlag3);
+            }
+            if (mInternalProviderFlag4 != null) {
+                values.put(Channels.COLUMN_INTERNAL_PROVIDER_FLAG4, mInternalProviderFlag4);
+            }
+        }
+        if (BuildCompat.isAtLeastO()) {
+            values.put(Channels.COLUMN_TRANSIENT, mTransient);
+        }
+        return values;
+    }
+
+    /**
+     * Creates a Channel object from a cursor including the fields defined in {@link Channels}.
+     *
+     * @param cursor A row from the TV Input Framework database.
+     * @return A channel with the values taken from the cursor.
+     */
+    public static Channel fromCursor(Cursor cursor) {
+        // TODO: Add additional API which does not use costly getColumnIndex().
+        Builder builder = new Builder();
+        int index;
+        if ((index = cursor.getColumnIndex(Channels._ID)) >= 0 && !cursor.isNull(index)) {
+            builder.setId(cursor.getLong(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_DESCRIPTION)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setDescription(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_DISPLAY_NAME)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setDisplayName(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_DISPLAY_NUMBER)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setDisplayNumber(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_INPUT_ID)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setInputId(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_INTERNAL_PROVIDER_DATA)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setInternalProviderData(cursor.getBlob(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_NETWORK_AFFILIATION)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setNetworkAffiliation(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_ORIGINAL_NETWORK_ID)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setOriginalNetworkId(cursor.getInt(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_PACKAGE_NAME)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setPackageName(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_SEARCHABLE)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setSearchable(cursor.getInt(index) == IS_SEARCHABLE);
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_SERVICE_ID)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setServiceId(cursor.getInt(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_SERVICE_TYPE)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setServiceType(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_TRANSPORT_STREAM_ID)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setTransportStreamId(cursor.getInt(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_TYPE)) >= 0 && !cursor.isNull(index)) {
+            builder.setType(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Channels.COLUMN_VIDEO_FORMAT)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setVideoFormat(cursor.getString(index));
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_APP_LINK_COLOR)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setAppLinkColor(cursor.getInt(index));
+            }
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_APP_LINK_ICON_URI)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setAppLinkIconUri(Uri.parse(cursor.getString(index)));
+            }
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_APP_LINK_INTENT_URI)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setAppLinkIntentUri(Uri.parse(cursor.getString(index)));
+            }
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_APP_LINK_POSTER_ART_URI)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setAppLinkPosterArtUri(Uri.parse(cursor.getString(index)));
+            }
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_APP_LINK_TEXT)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setAppLinkText(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_INTERNAL_PROVIDER_FLAG1)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInternalProviderFlag1(cursor.getLong(index));
+            }
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_INTERNAL_PROVIDER_FLAG2)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInternalProviderFlag2(cursor.getLong(index));
+            }
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_INTERNAL_PROVIDER_FLAG3)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInternalProviderFlag3(cursor.getLong(index));
+            }
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_INTERNAL_PROVIDER_FLAG4)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInternalProviderFlag4(cursor.getLong(index));
+            }
+        }
+        if (BuildCompat.isAtLeastO()) {
+            if ((index = cursor.getColumnIndex(Channels.COLUMN_TRANSIENT)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setTransient(cursor.getInt(index) == IS_TRANSIENT);
+            }
+        }
+        return builder.build();
+    }
+
+    private static String[] getProjection() {
+        String[] baseColumns = new String[] {
+                Channels._ID,
+                Channels.COLUMN_DESCRIPTION,
+                Channels.COLUMN_DISPLAY_NAME,
+                Channels.COLUMN_DISPLAY_NUMBER,
+                Channels.COLUMN_INPUT_ID,
+                Channels.COLUMN_INTERNAL_PROVIDER_DATA,
+                Channels.COLUMN_NETWORK_AFFILIATION,
+                Channels.COLUMN_ORIGINAL_NETWORK_ID,
+                Channels.COLUMN_PACKAGE_NAME,
+                Channels.COLUMN_SEARCHABLE,
+                Channels.COLUMN_SERVICE_ID,
+                Channels.COLUMN_SERVICE_TYPE,
+                Channels.COLUMN_TRANSPORT_STREAM_ID,
+                Channels.COLUMN_TYPE,
+                Channels.COLUMN_VIDEO_FORMAT,
+        };
+        String[] marshmallowColumns = new String[] {
+                Channels.COLUMN_APP_LINK_COLOR,
+                Channels.COLUMN_APP_LINK_ICON_URI,
+                Channels.COLUMN_APP_LINK_INTENT_URI,
+                Channels.COLUMN_APP_LINK_POSTER_ART_URI,
+                Channels.COLUMN_APP_LINK_TEXT,
+                Channels.COLUMN_INTERNAL_PROVIDER_FLAG1,
+                Channels.COLUMN_INTERNAL_PROVIDER_FLAG2,
+                Channels.COLUMN_INTERNAL_PROVIDER_FLAG3,
+                Channels.COLUMN_INTERNAL_PROVIDER_FLAG4,
+        };
+        String[] oReleaseColumns = new String[] {
+                Channels.COLUMN_TRANSIENT,
+        };
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            return CollectionUtils.concatAll(baseColumns, marshmallowColumns);
+        }
+        if (BuildCompat.isAtLeastO()) {
+            return CollectionUtils.concatAll(baseColumns, marshmallowColumns, oReleaseColumns);
+        }
+        return baseColumns;
+    }
+
+    /**
+     * The builder class that makes it easy to chain setters to create a {@link Channel} object.
+     */
+    public static final class Builder {
+        private long mId = INVALID_CHANNEL_ID;
+        private String mPackageName;
+        private String mInputId;
+        private String mType;
+        private String mDisplayNumber;
+        private String mDisplayName;
+        private String mDescription;
+        private String mChannelLogo;
+        private String mVideoFormat;
+        private int mOriginalNetworkId = INVALID_INTEGER_VALUE;
+        private int mTransportStreamId;
+        private int mServiceId;
+        private String mAppLinkText;
+        private int mAppLinkColor;
+        private Uri mAppLinkIconUri;
+        private Uri mAppLinkPosterArtUri;
+        private Uri mAppLinkIntentUri;
+        private byte[] mInternalProviderData;
+        private String mNetworkAffiliation;
+        private int mSearchable;
+        private String mServiceType = Channels.SERVICE_TYPE_AUDIO_VIDEO;
+        private Long mInternalProviderFlag1;
+        private Long mInternalProviderFlag2;
+        private Long mInternalProviderFlag3;
+        private Long mInternalProviderFlag4;
+        private int mTransient;
+
+        public Builder() {
+        }
+
+        public Builder(Channel other) {
+            mId = other.mId;
+            mPackageName = other.mPackageName;
+            mInputId = other.mInputId;
+            mType = other.mType;
+            mDisplayNumber = other.mDisplayNumber;
+            mDisplayName = other.mDisplayName;
+            mDescription = other.mDescription;
+            mVideoFormat = other.mVideoFormat;
+            mOriginalNetworkId = other.mOriginalNetworkId;
+            mTransportStreamId = other.mTransportStreamId;
+            mServiceId = other.mServiceId;
+            mAppLinkText = other.mAppLinkText;
+            mAppLinkColor = other.mAppLinkColor;
+            mAppLinkIconUri = other.mAppLinkIconUri;
+            mAppLinkPosterArtUri = other.mAppLinkPosterArtUri;
+            mAppLinkIntentUri = other.mAppLinkIntentUri;
+            mChannelLogo = other.mChannelLogo;
+            mInternalProviderData = other.mInternalProviderData;
+            mNetworkAffiliation = other.mNetworkAffiliation;
+            mSearchable = other.mSearchable;
+            mServiceType = other.mServiceType;
+            mInternalProviderFlag1 = other.mInternalProviderFlag1;
+            mInternalProviderFlag2 = other.mInternalProviderFlag2;
+            mInternalProviderFlag3 = other.mInternalProviderFlag3;
+            mInternalProviderFlag4 = other.mInternalProviderFlag4;
+            mTransient = other.mTransient;
+        }
+
+        /**
+         * Sets the ID of the Channel.
+         *
+         * @param id The value of {@link Channels#_ID} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        private Builder setId(long id) {
+            mId = id;
+            return this;
+        }
+
+        /**
+         * Sets the package name of the Channel.
+         *
+         * @param packageName The value of {@link Channels#COLUMN_PACKAGE_NAME} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setPackageName(String packageName) {
+            mPackageName = packageName;
+            return this;
+        }
+
+        /**
+         * Sets the input id of the Channel.
+         *
+         * @param inputId The value of {@link Channels#COLUMN_INPUT_ID} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInputId(String inputId) {
+            mInputId = inputId;
+            return this;
+        }
+
+        /**
+         * Sets the broadcast standard of the Channel.
+         *
+         * @param type The value of {@link Channels#COLUMN_TYPE} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setType(String type) {
+            mType = type;
+            return this;
+        }
+
+        /**
+         * Sets the display number of the Channel.
+         *
+         * @param displayNumber The value of {@link Channels#COLUMN_DISPLAY_NUMBER} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setDisplayNumber(String displayNumber) {
+            mDisplayNumber = displayNumber;
+            return this;
+        }
+
+        /**
+         * Sets the name to be displayed for the Channel.
+         *
+         * @param displayName The value of {@link Channels#COLUMN_DISPLAY_NAME} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setDisplayName(String displayName) {
+            mDisplayName = displayName;
+            return this;
+        }
+
+        /**
+         * Sets the description of the Channel.
+         *
+         * @param description The value of {@link Channels#COLUMN_DESCRIPTION} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setDescription(String description) {
+            mDescription = description;
+            return this;
+        }
+
+        /**
+         * Sets the logo of the channel.
+         *
+         * @param channelLogo The Uri corresponding to the logo for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @see Channels.Logo
+         */
+        public Builder setChannelLogo(String channelLogo) {
+            mChannelLogo = channelLogo;
+            return this;
+        }
+
+        /**
+         * Sets the video format of the Channel.
+         *
+         * @param videoFormat The value of {@link Channels#COLUMN_VIDEO_FORMAT} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setVideoFormat(String videoFormat) {
+            mVideoFormat = videoFormat;
+            return this;
+        }
+
+        /**
+         * Sets the original network id of the Channel.
+         *
+         * @param originalNetworkId The value of {@link Channels#COLUMN_ORIGINAL_NETWORK_ID} for the
+         *                          channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setOriginalNetworkId(int originalNetworkId) {
+            mOriginalNetworkId = originalNetworkId;
+            return this;
+        }
+
+        /**
+         * Sets the transport stream id of the Channel.
+         *
+         * @param transportStreamId The value of {@link Channels#COLUMN_TRANSPORT_STREAM_ID} for the
+         *                          channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setTransportStreamId(int transportStreamId) {
+            mTransportStreamId = transportStreamId;
+            return this;
+        }
+
+        /**
+         * Sets the service id of the Channel.
+         *
+         * @param serviceId The value of {@link Channels#COLUMN_SERVICE_ID} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setServiceId(int serviceId) {
+            mServiceId = serviceId;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider data of the channel.
+         *
+         * @param internalProviderData The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_DATA}
+         *                             for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderData(byte[] internalProviderData) {
+            mInternalProviderData = internalProviderData;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider data of the channel.
+         *
+         * @param internalProviderData The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_DATA}
+         *                             for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderData(String internalProviderData) {
+            mInternalProviderData = internalProviderData.getBytes();
+            return this;
+        }
+
+        /**
+         * Sets the text to be displayed in the App Linking card.
+         *
+         * @param appLinkText The value of {@link Channels#COLUMN_APP_LINK_TEXT} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAppLinkText(String appLinkText) {
+            mAppLinkText = appLinkText;
+            return this;
+        }
+
+        /**
+         * Sets the background color of the App Linking card.
+         *
+         * @param appLinkColor The value of {@link Channels#COLUMN_APP_LINK_COLOR} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAppLinkColor(int appLinkColor) {
+            mAppLinkColor = appLinkColor;
+            return this;
+        }
+
+        /**
+         * Sets the icon to be displayed next to the text of the App Linking card.
+         *
+         * @param appLinkIconUri The value of {@link Channels#COLUMN_APP_LINK_ICON_URI} for the
+         *                       channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAppLinkIconUri(Uri appLinkIconUri) {
+            mAppLinkIconUri = appLinkIconUri;
+            return this;
+        }
+
+        /**
+         * Sets the background image of the App Linking card.
+         *
+         * @param appLinkPosterArtUri The value of {@link Channels#COLUMN_APP_LINK_POSTER_ART_URI}
+         *                            for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAppLinkPosterArtUri(Uri appLinkPosterArtUri) {
+            mAppLinkPosterArtUri = appLinkPosterArtUri;
+            return this;
+        }
+
+        /**
+         * Sets the App Linking Intent.
+         *
+         * @param appLinkIntent The Intent to be executed when the App Linking card is selected
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAppLinkIntent(Intent appLinkIntent) {
+            return setAppLinkIntentUri(Uri.parse(appLinkIntent.toUri(Intent.URI_INTENT_SCHEME)));
+        }
+
+        /**
+         * Sets the App Linking Intent.
+         *
+         * @param appLinkIntentUri The Intent that should be executed when the App Linking card is
+         *                         selected. Use the method toUri(Intent.URI_INTENT_SCHEME) on your
+         *                         Intent to turn it into a String. See
+         *                         {@link Channels#COLUMN_APP_LINK_INTENT_URI}.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAppLinkIntentUri(Uri appLinkIntentUri) {
+            mAppLinkIntentUri = appLinkIntentUri;
+            return this;
+        }
+
+        /**
+         * Sets the network name for the channel, which may be different from its display name.
+         *
+         * @param networkAffiliation The value of
+         * {@link Channels#COLUMN_NETWORK_AFFILIATION} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setNetworkAffiliation(String networkAffiliation) {
+            mNetworkAffiliation = networkAffiliation;
+            return this;
+        }
+
+        /**
+         * Sets whether this channel can be searched for in other applications.
+         *
+         * @param searchable The value of {@link Channels#COLUMN_SEARCHABLE} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setSearchable(boolean searchable) {
+            mSearchable = searchable ? IS_SEARCHABLE : 0;
+            return this;
+        }
+
+        /**
+         * Sets the type of content that will appear on this channel. This could refer to the
+         * underlying broadcast standard or refer to {@link Channels#SERVICE_TYPE_AUDIO},
+         * {@link Channels#SERVICE_TYPE_AUDIO_VIDEO}, or {@link Channels#SERVICE_TYPE_OTHER}.
+         *
+         * @param serviceType The value of {@link Channels#COLUMN_SERVICE_TYPE} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setServiceType(String serviceType) {
+            mServiceType = serviceType;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider flag1 for the channel.
+         *
+         * @param flag The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_FLAG1} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderFlag1(long flag) {
+            mInternalProviderFlag1 = flag;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider flag2 for the channel.
+         *
+         * @param flag The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_FLAG2} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderFlag2(long flag) {
+            mInternalProviderFlag2 = flag;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider flag3 for the channel.
+         *
+         * @param flag The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_FLAG3} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderFlag3(long flag) {
+            mInternalProviderFlag3 = flag;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider flag4 for the channel.
+         *
+         * @param flag The value of {@link Channels#COLUMN_INTERNAL_PROVIDER_FLAG4} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderFlag4(long flag) {
+            mInternalProviderFlag4 = flag;
+            return this;
+        }
+
+        /**
+         * Sets whether this channel is transient or not.
+         *
+         * @param value The value of {@link Channels#COLUMN_TRANSIENT} for the channel.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @RestrictTo(LIBRARY_GROUP)
+        public Builder setTransient(boolean value) {
+            mTransient = value ? IS_TRANSIENT : 0;
+            return this;
+        }
+
+        /**
+         * Takes the values of the Builder object and creates a Channel object.
+         * @return Channel object with values from the Builder.
+         */
+        public Channel build() {
+            return new Channel(this);
+        }
+    }
+}
diff --git a/tv-provider/src/android/support/media/tv/CollectionUtils.java b/tv-provider/src/android/support/media/tv/CollectionUtils.java
new file mode 100644
index 0000000..7aa1074
--- /dev/null
+++ b/tv-provider/src/android/support/media/tv/CollectionUtils.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.tv;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.support.annotation.RestrictTo;
+
+import java.util.Arrays;
+
+/**
+ * Static utilities for collections
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+public class CollectionUtils {
+    /**
+     * Returns an array with the arrays concatenated together.
+     *
+     * @see <a href="http://stackoverflow.com/a/784842/1122089">Stackoverflow answer</a> by
+     *      <a href="http://stackoverflow.com/users/40342/joachim-sauer">Joachim Sauer</a>
+     */
+    public static <T> T[] concatAll(T[] first, T[]... rest) {
+        int totalLength = first.length;
+        for (T[] array : rest) {
+            totalLength += array.length;
+        }
+        T[] result = Arrays.copyOf(first, totalLength);
+        int offset = first.length;
+        for (T[] array : rest) {
+            System.arraycopy(array, 0, result, offset, array.length);
+            offset += array.length;
+        }
+        return result;
+    }
+}
diff --git a/tv-provider/src/android/support/media/tv/Program.java b/tv-provider/src/android/support/media/tv/Program.java
new file mode 100644
index 0000000..2f9a4eb
--- /dev/null
+++ b/tv-provider/src/android/support/media/tv/Program.java
@@ -0,0 +1,1929 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.tv;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.ContentValues;
+import android.content.Intent;
+import android.database.Cursor;
+import android.media.tv.TvContentRating;
+import android.net.Uri;
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.support.media.tv.TvContractCompat.Programs;
+import android.support.v4.os.BuildCompat;
+import android.text.TextUtils;
+
+import java.net.URISyntaxException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * A convenience class to create and insert program information into the database.
+ */
+public final class Program implements Comparable<Program> {
+    /**
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static final String[] PROJECTION = getProjection();
+
+    private static final long INVALID_LONG_VALUE = -1;
+    private static final int INVALID_INT_VALUE = -1;
+    private static final int IS_RECORDING_PROHIBITED = 1;
+    private static final int IS_SEARCHABLE = 1;
+    private static final int IS_TRANSIENT = 1;
+    private static final int IS_LIVE = 1;
+
+    private final long mId;
+    private final long mChannelId;
+    private final String mTitle;
+    private final String mEpisodeTitle;
+    private final String mSeasonNumber;
+    private final String mEpisodeNumber;
+    private final long mStartTimeUtcMillis;
+    private final long mEndTimeUtcMillis;
+    private final String mDescription;
+    private final String mLongDescription;
+    private final int mVideoWidth;
+    private final int mVideoHeight;
+    private final Uri mPosterArtUri;
+    private final Uri mThumbnailUri;
+    private final String[] mBroadcastGenres;
+    private final String[] mCanonicalGenres;
+    private final TvContentRating[] mContentRatings;
+    private final byte[] mInternalProviderData;
+    private final String[] mAudioLanguages;
+    private final int mSearchable;
+    private final Long mInternalProviderFlag1;
+    private final Long mInternalProviderFlag2;
+    private final Long mInternalProviderFlag3;
+    private final Long mInternalProviderFlag4;
+    private final int mRecordingProhibited;
+    private final String mSeasonTitle;
+    private final String mInternalProviderId;
+    private final Uri mPreviewVideoUri;
+    private final int mLastPlaybackPositionMillis;
+    private final int mDurationMillis;
+    private final Uri mAppLinkIntentUri;
+    private final int mWeight;
+    private final int mTransient;
+    private final String mType;
+    private final String mWatchNextType;
+    private final String mPosterArtAspectRatio;
+    private final String mThumbnailAspectRatio;
+    private final Uri mLogoUri;
+    private final String mAvailability;
+    private final String mStartingPrice;
+    private final String mOfferPrice;
+    private final String mReleaseDate;
+    private final int mItemCount;
+    private final int mLive;
+    private final String mInteractionType;
+    private final int mInteractionCount;
+    private final String mAuthor;
+    private final String mReviewRatingStyle;
+    private final String mReviewRating;
+
+    private Program(Builder builder) {
+        mId = builder.mId;
+        mChannelId = builder.mChannelId;
+        mTitle = builder.mTitle;
+        mEpisodeTitle = builder.mEpisodeTitle;
+        mSeasonNumber = builder.mSeasonNumber;
+        mEpisodeNumber = builder.mEpisodeNumber;
+        mStartTimeUtcMillis = builder.mStartTimeUtcMillis;
+        mEndTimeUtcMillis = builder.mEndTimeUtcMillis;
+        mDescription = builder.mDescription;
+        mLongDescription = builder.mLongDescription;
+        mVideoWidth = builder.mVideoWidth;
+        mVideoHeight = builder.mVideoHeight;
+        mPosterArtUri = builder.mPosterArtUri;
+        mThumbnailUri = builder.mThumbnailUri;
+        mBroadcastGenres = builder.mBroadcastGenres;
+        mCanonicalGenres = builder.mCanonicalGenres;
+        mContentRatings = builder.mContentRatings;
+        mInternalProviderData = builder.mInternalProviderData;
+        mAudioLanguages = builder.mAudioLanguages;
+        mSearchable = builder.mSearchable;
+        mInternalProviderFlag1 = builder.mInternalProviderFlag1;
+        mInternalProviderFlag2 = builder.mInternalProviderFlag2;
+        mInternalProviderFlag3 = builder.mInternalProviderFlag3;
+        mInternalProviderFlag4 = builder.mInternalProviderFlag4;
+        mRecordingProhibited = builder.mRecordingProhibited;
+        mSeasonTitle = builder.mSeasonTitle;
+        mInternalProviderId = builder.mExternalId;
+        mPreviewVideoUri = builder.mPreviewVideoUri;
+        mLastPlaybackPositionMillis = builder.mLastPlaybackPositionMillis;
+        mDurationMillis = builder.mDurationMillis;
+        mAppLinkIntentUri = builder.mAppLinkIntentUri;
+        mWeight = builder.mWeight;
+        mTransient = builder.mTransient;
+        mType = builder.mType;
+        mWatchNextType = builder.mWatchNextType;
+        mPosterArtAspectRatio = builder.mPosterArtAspectRatio;
+        mThumbnailAspectRatio = builder.mThumbnailAspectRatio;
+        mLogoUri = builder.mLogoUri;
+        mAvailability = builder.mAvailability;
+        mStartingPrice = builder.mStartingPrice;
+        mOfferPrice = builder.mOfferPrice;
+        mReleaseDate = builder.mReleaseDate;
+        mItemCount = builder.mItemCount;
+        mLive = builder.mLive;
+        mInteractionType = builder.mInteractionType;
+        mInteractionCount = builder.mInteractionCount;
+        mAuthor = builder.mAuthor;
+        mReviewRatingStyle = builder.mReviewRatingStyle;
+        mReviewRating = builder.mReviewRating;
+    }
+
+    /**
+     * @return The value of {@link Programs#_ID} for the program.
+     */
+    public long getId() {
+        return mId;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_CHANNEL_ID} for the program.
+     */
+    public long getChannelId() {
+        return mChannelId;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_TITLE} for the program.
+     */
+    public String getTitle() {
+        return mTitle;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_EPISODE_TITLE} for the program.
+     */
+    public String getEpisodeTitle() {
+        return mEpisodeTitle;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_SEASON_DISPLAY_NUMBER} for the program.
+     */
+    public String getSeasonNumber() {
+        return mSeasonNumber;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_EPISODE_DISPLAY_NUMBER} for the program.
+     */
+    public String getEpisodeNumber() {
+        return mEpisodeNumber;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_START_TIME_UTC_MILLIS} for the program.
+     */
+    public long getStartTimeUtcMillis() {
+        return mStartTimeUtcMillis;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_END_TIME_UTC_MILLIS} for the program.
+     */
+    public long getEndTimeUtcMillis() {
+        return mEndTimeUtcMillis;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_SHORT_DESCRIPTION} for the program.
+     */
+    public String getDescription() {
+        return mDescription;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_LONG_DESCRIPTION} for the program.
+     */
+    public String getLongDescription() {
+        return mLongDescription;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_VIDEO_WIDTH} for the program.
+     */
+    public int getVideoWidth() {
+        return mVideoWidth;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_VIDEO_HEIGHT} for the program.
+     */
+    public int getVideoHeight() {
+        return mVideoHeight;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_BROADCAST_GENRE} for the program.
+     */
+    public String[] getBroadcastGenres() {
+        return mBroadcastGenres;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_CANONICAL_GENRE} for the program.
+     */
+    public String[] getCanonicalGenres() {
+        return mCanonicalGenres;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_CONTENT_RATING} for the program.
+     */
+    public TvContentRating[] getContentRatings() {
+        return mContentRatings;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_POSTER_ART_URI} for the program.
+     */
+    public Uri getPosterArtUri() {
+        return mPosterArtUri;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_THUMBNAIL_URI} for the program.
+     */
+    public Uri getThumbnailUri() {
+        return mThumbnailUri;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_DATA} for the program.
+     */
+    public byte[] getInternalProviderDataByteArray() {
+        return mInternalProviderData;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_AUDIO_LANGUAGE} for the program.
+     */
+    public String[] getAudioLanguages() {
+        return mAudioLanguages;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_SEARCHABLE} for the program.
+     */
+    public boolean isSearchable() {
+        return mSearchable == IS_SEARCHABLE || mSearchable == INVALID_INT_VALUE;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG1} for the program.
+     */
+    public Long getInternalProviderFlag1() {
+        return mInternalProviderFlag1;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG2} for the program.
+     */
+    public Long getInternalProviderFlag2() {
+        return mInternalProviderFlag2;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG3} for the program.
+     */
+    public Long getInternalProviderFlag3() {
+        return mInternalProviderFlag3;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG4} for the program.
+     */
+    public Long getInternalProviderFlag4() {
+        return mInternalProviderFlag4;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_RECORDING_PROHIBITED} for the program.
+     */
+    public boolean isRecordingProhibited() {
+        return mRecordingProhibited == IS_RECORDING_PROHIBITED;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_SEASON_TITLE} for the program.
+     */
+    public String getSeasonTitle() {
+        return mSeasonTitle;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_ID} for the program.
+     */
+    public String getInternalProviderId() {
+        return mInternalProviderId;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_PREVIEW_VIDEO_URI} for the program.
+     */
+    public Uri getPreviewVideoUri() {
+        return mPreviewVideoUri;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_LAST_PLAYBACK_POSITION_MILLIS} for the program.
+     */
+    public int getLastPlaybackPositionMillis() {
+        return mLastPlaybackPositionMillis;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_DURATION_MILLIS} for the program.
+     */
+    public int getDurationMillis() {
+        return mDurationMillis;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_APP_LINK_INTENT_URI} for the program.
+     */
+    public Uri getAppLinkIntentUri() {
+        return mAppLinkIntentUri;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_APP_LINK_INTENT_URI} for the program.
+     */
+    public Intent getAppLinkIntent() throws URISyntaxException {
+        return Intent.parseUri(mAppLinkIntentUri.toString(), Intent.URI_INTENT_SCHEME);
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_WEIGHT} for the program.
+     */
+    public int getWeight() {
+        return mWeight;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_TRANSIENT} for the program.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public boolean isTransient() {
+        return mTransient == IS_TRANSIENT;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_TYPE} for the program.
+     */
+    public String getType() {
+        return mType;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_WATCH_NEXT_TYPE} for the program.
+     */
+    public String getWatchNextType() {
+        return mWatchNextType;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_POSTER_ART_ASPECT_RATIO} for the program.
+     */
+    public String getPosterArtAspectRatio() {
+        return mPosterArtAspectRatio;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_THUMBNAIL_ASPECT_RATIO} for the program.
+     */
+    public String getThumbnailAspectRatio() {
+        return mThumbnailAspectRatio;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_LOGO_URI} for the program.
+     */
+    public Uri getLogoUri() {
+        return mLogoUri;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_AVAILABILITY} for the program.
+     */
+    public String getAvailability() {
+        return mAvailability;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_STARTING_PRICE} for the program.
+     */
+    public String getStartingPrice() {
+        return mStartingPrice;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_OFFER_PRICE} for the program.
+     */
+    public String getOfferPrice() {
+        return mOfferPrice;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_RELEASE_DATE} for the program.
+     */
+    public String getReleaseDate() {
+        return mReleaseDate;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_ITEM_COUNT} for the program.
+     */
+    public int getItemCount() {
+        return mItemCount;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_LIVE} for the program.
+     */
+    public boolean isLive() {
+        return mLive == IS_LIVE;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_INTERACTION_TYPE} for the program.
+     */
+    public String getInteractionType() {
+        return mInteractionType;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_INTERACTION_COUNT} for the program.
+     */
+    public int getInteractionCount() {
+        return mInteractionCount;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_AUTHOR} for the program.
+     */
+    public String getAuthor() {
+        return mAuthor;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_REVIEW_RATING_STYLE} for the program.
+     */
+    public String getReviewRatingStyle() {
+        return mReviewRatingStyle;
+    }
+
+    /**
+     * @return The value of {@link Programs#COLUMN_REVIEW_RATING} for the program.
+     */
+    public String getReviewRating() {
+        return mReviewRating;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mChannelId, mStartTimeUtcMillis, mEndTimeUtcMillis,
+                mTitle, mEpisodeTitle, mDescription, mLongDescription, mVideoWidth, mVideoHeight,
+                mPosterArtUri, mThumbnailUri, mContentRatings, mCanonicalGenres, mSeasonNumber,
+                mEpisodeNumber);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (!(other instanceof Program)) {
+            return false;
+        }
+        Program program = (Program) other;
+        return mChannelId == program.mChannelId
+                && mStartTimeUtcMillis == program.mStartTimeUtcMillis
+                && mEndTimeUtcMillis == program.mEndTimeUtcMillis
+                && Objects.equals(mTitle, program.mTitle)
+                && Objects.equals(mEpisodeTitle, program.mEpisodeTitle)
+                && Objects.equals(mSeasonNumber, program.mSeasonNumber)
+                && Objects.equals(mEpisodeNumber, program.mEpisodeNumber)
+                && Objects.equals(mDescription, program.mDescription)
+                && Objects.equals(mLongDescription, program.mLongDescription)
+                && mVideoWidth == program.mVideoWidth
+                && mVideoHeight == program.mVideoHeight
+                && Objects.equals(mPosterArtUri, program.mPosterArtUri)
+                && Objects.equals(mThumbnailUri, program.mThumbnailUri)
+                && Arrays.equals(mInternalProviderData, program.mInternalProviderData)
+                && Arrays.equals(mBroadcastGenres, program.mBroadcastGenres)
+                && Arrays.equals(mCanonicalGenres, program.mCanonicalGenres)
+                && Arrays.equals(mContentRatings, program.mContentRatings)
+                && Arrays.equals(mAudioLanguages, program.mAudioLanguages)
+                && (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
+                        || Objects.equals(mSearchable, program.mSearchable)
+                        && Objects.equals(mInternalProviderFlag1, program.mInternalProviderFlag1)
+                        && Objects.equals(mInternalProviderFlag2, program.mInternalProviderFlag2)
+                        && Objects.equals(mInternalProviderFlag3, program.mInternalProviderFlag3)
+                        && Objects.equals(mInternalProviderFlag4, program.mInternalProviderFlag4))
+                && (Build.VERSION.SDK_INT < Build.VERSION_CODES.N
+                        || Objects.equals(mSeasonTitle, program.mSeasonTitle)
+                        && Objects.equals(mRecordingProhibited, program.mRecordingProhibited))
+                && (!BuildCompat.isAtLeastO()
+                        || Objects.equals(mInternalProviderId, program.mInternalProviderId)
+                        && Objects.equals(mPreviewVideoUri, program.mPreviewVideoUri)
+                        && Objects.equals(mLastPlaybackPositionMillis,
+                                program.mLastPlaybackPositionMillis)
+                        && Objects.equals(mDurationMillis, program.mDurationMillis)
+                        && Objects.equals(mAppLinkIntentUri,
+                                program.mAppLinkIntentUri)
+                        && Objects.equals(mWeight, program.mWeight)
+                        && Objects.equals(mTransient, program.mTransient)
+                        && Objects.equals(mType, program.mType)
+                        && Objects.equals(mWatchNextType, program.mWatchNextType)
+                        && Objects.equals(mPosterArtAspectRatio, program.mPosterArtAspectRatio)
+                        && Objects.equals(mThumbnailAspectRatio, program.mThumbnailAspectRatio)
+                        && Objects.equals(mLogoUri, program.mLogoUri)
+                        && Objects.equals(mAvailability, program.mAvailability)
+                        && Objects.equals(mStartingPrice, program.mStartingPrice)
+                        && Objects.equals(mOfferPrice, program.mOfferPrice)
+                        && Objects.equals(mReleaseDate, program.mReleaseDate)
+                        && Objects.equals(mItemCount, program.mItemCount)
+                        && Objects.equals(mLive, program.mLive)
+                        && Objects.equals(mInteractionType, program.mInteractionType)
+                        && Objects.equals(mInteractionCount, program.mInteractionCount)
+                        && Objects.equals(mAuthor, program.mAuthor)
+                        && Objects.equals(mReviewRatingStyle, program.mReviewRatingStyle)
+                        && Objects.equals(mReviewRating, program.mReviewRating));
+    }
+
+    /**
+     * @param other The program you're comparing to.
+     * @return The chronological order of the programs.
+     */
+    @Override
+    public int compareTo(@NonNull Program other) {
+        return Long.compare(mStartTimeUtcMillis, other.mStartTimeUtcMillis);
+    }
+
+    @Override
+    public String toString() {
+        return "Program{"
+                + "id=" + mId
+                + ", channelId=" + mChannelId
+                + ", title=" + mTitle
+                + ", episodeTitle=" + mEpisodeTitle
+                + ", seasonNumber=" + mSeasonNumber
+                + ", episodeNumber=" + mEpisodeNumber
+                + ", startTimeUtcSec=" + mStartTimeUtcMillis
+                + ", endTimeUtcSec=" + mEndTimeUtcMillis
+                + ", videoWidth=" + mVideoWidth
+                + ", videoHeight=" + mVideoHeight
+                + ", contentRatings=" + Arrays.toString(mContentRatings)
+                + ", posterArtUri=" + mPosterArtUri
+                + ", thumbnailUri=" + mThumbnailUri
+                + ", contentRatings=" + Arrays.toString(mContentRatings)
+                + ", genres=" + Arrays.toString(mCanonicalGenres)
+                + "}";
+    }
+
+    /**
+     * @return The fields of the Program in the ContentValues format to be easily inserted into the
+     * TV Input Framework database.
+     */
+    public ContentValues toContentValues() {
+        ContentValues values = new ContentValues();
+        if (mId != INVALID_LONG_VALUE) {
+            values.put(Programs._ID, mId);
+        }
+        if (mChannelId != INVALID_LONG_VALUE) {
+            values.put(Programs.COLUMN_CHANNEL_ID, mChannelId);
+        } else {
+            values.putNull(Programs.COLUMN_CHANNEL_ID);
+        }
+        if (!TextUtils.isEmpty(mTitle)) {
+            values.put(Programs.COLUMN_TITLE, mTitle);
+        } else {
+            values.putNull(Programs.COLUMN_TITLE);
+        }
+        if (!TextUtils.isEmpty(mEpisodeTitle)) {
+            values.put(Programs.COLUMN_EPISODE_TITLE, mEpisodeTitle);
+        } else {
+            values.putNull(Programs.COLUMN_EPISODE_TITLE);
+        }
+        if (!TextUtils.isEmpty(mSeasonNumber) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            values.put(Programs.COLUMN_SEASON_DISPLAY_NUMBER, mSeasonNumber);
+        } else if (!TextUtils.isEmpty(mSeasonNumber)
+                && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+            values.put(Programs.COLUMN_SEASON_NUMBER,
+                    Integer.parseInt(mSeasonNumber));
+        } else {
+            values.putNull(Programs.COLUMN_SEASON_NUMBER);
+        }
+        if (!TextUtils.isEmpty(mEpisodeNumber) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            values.put(Programs.COLUMN_EPISODE_DISPLAY_NUMBER, mEpisodeNumber);
+        } else if (!TextUtils.isEmpty(mEpisodeNumber)
+                && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+            values.put(Programs.COLUMN_EPISODE_NUMBER,
+                    Integer.parseInt(mEpisodeNumber));
+        } else {
+            values.putNull(Programs.COLUMN_EPISODE_NUMBER);
+        }
+        if (!TextUtils.isEmpty(mDescription)) {
+            values.put(Programs.COLUMN_SHORT_DESCRIPTION, mDescription);
+        } else {
+            values.putNull(Programs.COLUMN_SHORT_DESCRIPTION);
+        }
+        if (!TextUtils.isEmpty(mDescription)) {
+            values.put(Programs.COLUMN_LONG_DESCRIPTION, mLongDescription);
+        } else {
+            values.putNull(Programs.COLUMN_LONG_DESCRIPTION);
+        }
+        if (mPosterArtUri != null) {
+            values.put(Programs.COLUMN_POSTER_ART_URI, mPosterArtUri.toString());
+        } else {
+            values.putNull(Programs.COLUMN_POSTER_ART_URI);
+        }
+        if (mThumbnailUri != null) {
+            values.put(Programs.COLUMN_THUMBNAIL_URI, mThumbnailUri.toString());
+        } else {
+            values.putNull(Programs.COLUMN_THUMBNAIL_URI);
+        }
+        if (mAudioLanguages != null && mAudioLanguages.length > 0) {
+            values.put(Programs.COLUMN_AUDIO_LANGUAGE,
+                    TvContractUtils.audioLanguagesToString(mAudioLanguages));
+        } else {
+            values.putNull(Programs.COLUMN_AUDIO_LANGUAGE);
+        }
+        if (mBroadcastGenres != null && mBroadcastGenres.length > 0) {
+            values.put(Programs.COLUMN_BROADCAST_GENRE,
+                    Programs.Genres.encode(mBroadcastGenres));
+        } else {
+            values.putNull(Programs.COLUMN_BROADCAST_GENRE);
+        }
+        if (mCanonicalGenres != null && mCanonicalGenres.length > 0) {
+            values.put(Programs.COLUMN_CANONICAL_GENRE,
+                    Programs.Genres.encode(mCanonicalGenres));
+        } else {
+            values.putNull(Programs.COLUMN_CANONICAL_GENRE);
+        }
+        if (mContentRatings != null && mContentRatings.length > 0) {
+            values.put(Programs.COLUMN_CONTENT_RATING,
+                    TvContractUtils.contentRatingsToString(mContentRatings));
+        } else {
+            values.putNull(Programs.COLUMN_CONTENT_RATING);
+        }
+        if (mStartTimeUtcMillis != INVALID_LONG_VALUE) {
+            values.put(Programs.COLUMN_START_TIME_UTC_MILLIS, mStartTimeUtcMillis);
+        } else {
+            values.putNull(Programs.COLUMN_START_TIME_UTC_MILLIS);
+        }
+        if (mEndTimeUtcMillis != INVALID_LONG_VALUE) {
+            values.put(Programs.COLUMN_END_TIME_UTC_MILLIS, mEndTimeUtcMillis);
+        } else {
+            values.putNull(Programs.COLUMN_END_TIME_UTC_MILLIS);
+        }
+        if (mVideoWidth != INVALID_INT_VALUE) {
+            values.put(Programs.COLUMN_VIDEO_WIDTH, mVideoWidth);
+        } else {
+            values.putNull(Programs.COLUMN_VIDEO_WIDTH);
+        }
+        if (mVideoHeight != INVALID_INT_VALUE) {
+            values.put(Programs.COLUMN_VIDEO_HEIGHT, mVideoHeight);
+        } else {
+            values.putNull(Programs.COLUMN_VIDEO_HEIGHT);
+        }
+        if (mInternalProviderData != null && mInternalProviderData.length > 0) {
+            values.put(Programs.COLUMN_INTERNAL_PROVIDER_DATA,
+                    mInternalProviderData);
+        } else {
+            values.putNull(Programs.COLUMN_INTERNAL_PROVIDER_DATA);
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            if (mSearchable != INVALID_INT_VALUE) {
+                values.put(Programs.COLUMN_SEARCHABLE, mSearchable);
+            }
+            if (mInternalProviderFlag1 != null) {
+                values.put(Programs.COLUMN_INTERNAL_PROVIDER_FLAG1, mInternalProviderFlag1);
+            }
+            if (mInternalProviderFlag2 != null) {
+                values.put(Programs.COLUMN_INTERNAL_PROVIDER_FLAG2, mInternalProviderFlag2);
+            }
+            if (mInternalProviderFlag3 != null) {
+                values.put(Programs.COLUMN_INTERNAL_PROVIDER_FLAG3, mInternalProviderFlag3);
+            }
+            if (mInternalProviderFlag4 != null) {
+                values.put(Programs.COLUMN_INTERNAL_PROVIDER_FLAG4, mInternalProviderFlag4);
+            }
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            if (!TextUtils.isEmpty(mSeasonTitle)) {
+                values.put(Programs.COLUMN_SEASON_TITLE, mSeasonTitle);
+            }
+            if (mRecordingProhibited != INVALID_INT_VALUE) {
+                values.put(Programs.COLUMN_RECORDING_PROHIBITED, mRecordingProhibited);
+            }
+        }
+        if (BuildCompat.isAtLeastO()) {
+            if (!TextUtils.isEmpty(mInternalProviderId)) {
+                values.put(Programs.COLUMN_INTERNAL_PROVIDER_ID, mInternalProviderId);
+            }
+            if (mPreviewVideoUri != null) {
+                values.put(Programs.COLUMN_PREVIEW_VIDEO_URI, mPreviewVideoUri.toString());
+            }
+            if (mLastPlaybackPositionMillis != INVALID_INT_VALUE) {
+                values.put(Programs.COLUMN_LAST_PLAYBACK_POSITION_MILLIS,
+                        mLastPlaybackPositionMillis);
+            }
+            if (mDurationMillis != INVALID_INT_VALUE) {
+                values.put(Programs.COLUMN_DURATION_MILLIS, mDurationMillis);
+            }
+            if (mAppLinkIntentUri != null) {
+                values.put(Programs.COLUMN_APP_LINK_INTENT_URI, mAppLinkIntentUri.toString());
+            }
+            if (mWeight != INVALID_INT_VALUE) {
+                values.put(Programs.COLUMN_WEIGHT, mWeight);
+            }
+            if (mTransient == IS_TRANSIENT) {
+                values.put(Programs.COLUMN_TRANSIENT, mTransient);
+            }
+            if (!TextUtils.isEmpty(mType)) {
+                values.put(Programs.COLUMN_TYPE, mType);
+            }
+            if (!TextUtils.isEmpty(mWatchNextType)) {
+                values.put(Programs.COLUMN_WATCH_NEXT_TYPE, mWatchNextType);
+            }
+            if (!TextUtils.isEmpty(mPosterArtAspectRatio)) {
+                values.put(Programs.COLUMN_POSTER_ART_ASPECT_RATIO, mPosterArtAspectRatio);
+            }
+            if (!TextUtils.isEmpty(mThumbnailAspectRatio)) {
+                values.put(Programs.COLUMN_THUMBNAIL_ASPECT_RATIO, mThumbnailAspectRatio);
+            }
+            if (mLogoUri != null) {
+                values.put(Programs.COLUMN_LOGO_URI, mLogoUri.toString());
+            }
+            if (!TextUtils.isEmpty(mAvailability)) {
+                values.put(Programs.COLUMN_AVAILABILITY, mAvailability);
+            }
+            if (!TextUtils.isEmpty(mStartingPrice)) {
+                values.put(Programs.COLUMN_STARTING_PRICE, mStartingPrice);
+            }
+            if (!TextUtils.isEmpty(mOfferPrice)) {
+                values.put(Programs.COLUMN_OFFER_PRICE, mOfferPrice);
+            }
+            if (!TextUtils.isEmpty(mReleaseDate)) {
+                values.put(Programs.COLUMN_RELEASE_DATE, mReleaseDate);
+            }
+            if (mItemCount != INVALID_INT_VALUE) {
+                values.put(Programs.COLUMN_ITEM_COUNT, mItemCount);
+            }
+            if (mLive != INVALID_INT_VALUE) {
+                values.put(Programs.COLUMN_LIVE, mLive);
+            }
+            if (!TextUtils.isEmpty(mInteractionType)) {
+                values.put(Programs.COLUMN_INTERACTION_TYPE, mInteractionType);
+            }
+            if (mInteractionCount != INVALID_INT_VALUE) {
+                values.put(Programs.COLUMN_INTERACTION_COUNT, mInteractionCount);
+            }
+            if (!TextUtils.isEmpty(mAuthor)) {
+                values.put(Programs.COLUMN_AUTHOR, mAuthor);
+            }
+            if (!TextUtils.isEmpty(mReviewRatingStyle)) {
+                values.put(Programs.COLUMN_REVIEW_RATING_STYLE, mReviewRatingStyle);
+            }
+            if (!TextUtils.isEmpty(mReviewRating)) {
+                values.put(Programs.COLUMN_REVIEW_RATING, mReviewRating);
+            }
+        }
+        return values;
+    }
+
+    /**
+     * Creates a Program object from a cursor including the fields defined in {@link Programs}.
+     *
+     * @param cursor A row from the TV Input Framework database.
+     * @return A Program with the values taken from the cursor.
+     */
+    public static Program fromCursor(Cursor cursor) {
+        // TODO: Add additional API which does not use costly getColumnIndex().
+        Builder builder = new Builder();
+        int index;
+        if ((index = cursor.getColumnIndex(Programs._ID)) >= 0 && !cursor.isNull(index)) {
+            builder.setId(cursor.getLong(index));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_CHANNEL_ID)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setChannelId(cursor.getLong(index));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_TITLE)) >= 0 && !cursor.isNull(index)) {
+            builder.setTitle(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_EPISODE_TITLE)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setEpisodeTitle(cursor.getString(index));
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_SEASON_DISPLAY_NUMBER)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setSeasonNumber(cursor.getString(index), INVALID_INT_VALUE);
+            }
+        } else {
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_SEASON_NUMBER)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setSeasonNumber(cursor.getInt(index));
+            }
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_EPISODE_DISPLAY_NUMBER)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setEpisodeNumber(cursor.getString(index), INVALID_INT_VALUE);
+            }
+        } else {
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_EPISODE_NUMBER)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setEpisodeNumber(cursor.getInt(index));
+            }
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_SHORT_DESCRIPTION)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setDescription(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_LONG_DESCRIPTION)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setLongDescription(cursor.getString(index));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_POSTER_ART_URI)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setPosterArtUri(Uri.parse(cursor.getString(index)));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_THUMBNAIL_URI)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setThumbnailUri(Uri.parse(cursor.getString(index)));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_AUDIO_LANGUAGE)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setAudioLanguages(
+                    TvContractUtils.stringToAudioLanguages(cursor.getString(index)));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_BROADCAST_GENRE)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setBroadcastGenres(Programs.Genres.decode(
+                    cursor.getString(index)));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_CANONICAL_GENRE)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setCanonicalGenres(Programs.Genres.decode(
+                    cursor.getString(index)));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_CONTENT_RATING)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setContentRatings(
+                    TvContractUtils.stringToContentRatings(cursor.getString(index)));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_START_TIME_UTC_MILLIS)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setStartTimeUtcMillis(cursor.getLong(index));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_END_TIME_UTC_MILLIS)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setEndTimeUtcMillis(cursor.getLong(index));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_VIDEO_WIDTH)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setVideoWidth((int) cursor.getLong(index));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_VIDEO_HEIGHT)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setVideoHeight((int) cursor.getLong(index));
+        }
+        if ((index = cursor.getColumnIndex(Programs.COLUMN_INTERNAL_PROVIDER_DATA)) >= 0
+                && !cursor.isNull(index)) {
+            builder.setInternalProviderData(cursor.getBlob(index));
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_SEARCHABLE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setSearchable(cursor.getInt(index) == IS_SEARCHABLE);
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_INTERNAL_PROVIDER_FLAG1)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInternalProviderFlag1(cursor.getLong(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_INTERNAL_PROVIDER_FLAG2)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInternalProviderFlag2(cursor.getLong(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_INTERNAL_PROVIDER_FLAG3)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInternalProviderFlag3(cursor.getLong(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_INTERNAL_PROVIDER_FLAG4)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInternalProviderFlag4(cursor.getLong(index));
+            }
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_SEASON_TITLE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setSeasonTitle(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_RECORDING_PROHIBITED)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setRecordingProhibited(cursor.getInt(index) == IS_RECORDING_PROHIBITED);
+            }
+        }
+        if (BuildCompat.isAtLeastO()) {
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_INTERNAL_PROVIDER_ID)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInternalProviderId(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_PREVIEW_VIDEO_URI)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setPreviewVideoUri(Uri.parse(cursor.getString(index)));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_LAST_PLAYBACK_POSITION_MILLIS)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setLastPlaybackPositionMillis(cursor.getInt(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_DURATION_MILLIS)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setDurationMillis(cursor.getInt(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_APP_LINK_INTENT_URI)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setAppLinkIntentUri(Uri.parse(cursor.getString(index)));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_WEIGHT)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setWeight(cursor.getInt(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_TRANSIENT)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setTransient(cursor.getInt(index) == IS_TRANSIENT);
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_TYPE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setType(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_WATCH_NEXT_TYPE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setWatchNextType(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_POSTER_ART_ASPECT_RATIO)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setPosterArtAspectRatio(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_THUMBNAIL_ASPECT_RATIO)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setThumbnailAspectRatio(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_LOGO_URI)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setLogoUri(Uri.parse(cursor.getString(index)));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_AVAILABILITY)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setAvailability(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_STARTING_PRICE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setStartingPrice(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_OFFER_PRICE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setOfferPrice(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_RELEASE_DATE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setReleaseDate(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_ITEM_COUNT)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setItemCount(cursor.getInt(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_LIVE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setLive(cursor.getInt(index) == IS_LIVE);
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_INTERACTION_TYPE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInteractionType(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_INTERACTION_COUNT)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setInteractionCount(cursor.getInt(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_AUTHOR)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setAuthor(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_REVIEW_RATING_STYLE)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setReviewRatingStyle(cursor.getString(index));
+            }
+            if ((index = cursor.getColumnIndex(Programs.COLUMN_REVIEW_RATING)) >= 0
+                    && !cursor.isNull(index)) {
+                builder.setReviewRating(cursor.getString(index));
+            }
+        }
+        return builder.build();
+    }
+
+    private static String[] getProjection() {
+        String[] baseColumns = new String[] {
+                Programs._ID,
+                Programs.COLUMN_CHANNEL_ID,
+                Programs.COLUMN_TITLE,
+                Programs.COLUMN_EPISODE_TITLE,
+                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+                        ? Programs.COLUMN_SEASON_DISPLAY_NUMBER : Programs.COLUMN_SEASON_NUMBER,
+                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+                        ? Programs.COLUMN_EPISODE_DISPLAY_NUMBER : Programs.COLUMN_EPISODE_NUMBER,
+                Programs.COLUMN_SHORT_DESCRIPTION,
+                Programs.COLUMN_LONG_DESCRIPTION,
+                Programs.COLUMN_POSTER_ART_URI,
+                Programs.COLUMN_THUMBNAIL_URI,
+                Programs.COLUMN_AUDIO_LANGUAGE,
+                Programs.COLUMN_BROADCAST_GENRE,
+                Programs.COLUMN_CANONICAL_GENRE,
+                Programs.COLUMN_CONTENT_RATING,
+                Programs.COLUMN_START_TIME_UTC_MILLIS,
+                Programs.COLUMN_END_TIME_UTC_MILLIS,
+                Programs.COLUMN_VIDEO_WIDTH,
+                Programs.COLUMN_VIDEO_HEIGHT,
+                Programs.COLUMN_INTERNAL_PROVIDER_DATA
+        };
+        String[] marshmallowColumns = new String[] {
+                Programs.COLUMN_SEARCHABLE,
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG1,
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG2,
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG3,
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG4,
+        };
+        String[] nougatColumns = new String[] {
+                Programs.COLUMN_SEASON_TITLE,
+                Programs.COLUMN_RECORDING_PROHIBITED
+        };
+        String[] oColumns = new String[] {
+                Programs.COLUMN_INTERNAL_PROVIDER_ID,
+                Programs.COLUMN_PREVIEW_VIDEO_URI,
+                Programs.COLUMN_LAST_PLAYBACK_POSITION_MILLIS,
+                Programs.COLUMN_DURATION_MILLIS,
+                Programs.COLUMN_APP_LINK_INTENT_URI,
+                Programs.COLUMN_WEIGHT,
+                Programs.COLUMN_TRANSIENT,
+                Programs.COLUMN_TYPE,
+                Programs.COLUMN_WATCH_NEXT_TYPE,
+                Programs.COLUMN_POSTER_ART_ASPECT_RATIO,
+                Programs.COLUMN_THUMBNAIL_ASPECT_RATIO,
+                Programs.COLUMN_LOGO_URI,
+                Programs.COLUMN_AVAILABILITY,
+                Programs.COLUMN_STARTING_PRICE,
+                Programs.COLUMN_OFFER_PRICE,
+                Programs.COLUMN_RELEASE_DATE,
+                Programs.COLUMN_ITEM_COUNT,
+                Programs.COLUMN_LIVE,
+                Programs.COLUMN_INTERACTION_TYPE,
+                Programs.COLUMN_INTERACTION_COUNT,
+                Programs.COLUMN_AUTHOR,
+                Programs.COLUMN_REVIEW_RATING_STYLE,
+                Programs.COLUMN_REVIEW_RATING,
+        };
+        if (BuildCompat.isAtLeastO()) {
+            return CollectionUtils.concatAll(baseColumns, marshmallowColumns, nougatColumns,
+                    oColumns);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            return CollectionUtils.concatAll(baseColumns, marshmallowColumns, nougatColumns);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            return CollectionUtils.concatAll(baseColumns, marshmallowColumns);
+        } else {
+            return baseColumns;
+        }
+    }
+
+    /**
+     * This Builder class simplifies the creation of a {@link Program} object.
+     */
+    public static final class Builder {
+        private static final SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+        private long mId = INVALID_LONG_VALUE;
+        private long mChannelId = INVALID_LONG_VALUE;
+        private String mTitle;
+        private String mEpisodeTitle;
+        private String mSeasonNumber;
+        private String mEpisodeNumber;
+        private long mStartTimeUtcMillis = INVALID_LONG_VALUE;
+        private long mEndTimeUtcMillis = INVALID_LONG_VALUE;
+        private String mDescription;
+        private String mLongDescription;
+        private int mVideoWidth = INVALID_INT_VALUE;
+        private int mVideoHeight = INVALID_INT_VALUE;
+        private Uri mPosterArtUri;
+        private Uri mThumbnailUri;
+        private String[] mBroadcastGenres;
+        private String[] mCanonicalGenres;
+        private TvContentRating[] mContentRatings;
+        private byte[] mInternalProviderData;
+        private String[] mAudioLanguages;
+        private int mSearchable = INVALID_INT_VALUE;
+        private Long mInternalProviderFlag1;
+        private Long mInternalProviderFlag2;
+        private Long mInternalProviderFlag3;
+        private Long mInternalProviderFlag4;
+        private int mRecordingProhibited = INVALID_INT_VALUE;
+        private String mSeasonTitle;
+        private String mExternalId;
+        private Uri mPreviewVideoUri;
+        private int mLastPlaybackPositionMillis = INVALID_INT_VALUE;
+        private int mDurationMillis = INVALID_INT_VALUE;
+        private Uri mAppLinkIntentUri;
+        private int mWeight = INVALID_INT_VALUE;
+        private int mTransient;
+        private String mType;
+        private String mWatchNextType;
+        private String mPosterArtAspectRatio;
+        private String mThumbnailAspectRatio;
+        private Uri mLogoUri;
+        private String mAvailability;
+        private String mStartingPrice;
+        private String mOfferPrice;
+        private String mReleaseDate;  // XXX: change this to Date class.
+        private int mItemCount = INVALID_INT_VALUE;
+        private int mLive = INVALID_INT_VALUE;
+        private String mInteractionType;
+        private int mInteractionCount = INVALID_INT_VALUE;
+        private String mAuthor;
+        private String mReviewRatingStyle;
+        private String mReviewRating;
+
+        /**
+         * Creates a new Builder object.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Creates a new Builder object with values copied from another Program.
+         * @param other The Program you're copying from.
+         */
+        public Builder(Program other) {
+            mId = other.mId;
+            mChannelId = other.mChannelId;
+            mTitle = other.mTitle;
+            mEpisodeTitle = other.mEpisodeTitle;
+            mSeasonNumber = other.mSeasonNumber;
+            mEpisodeNumber = other.mEpisodeNumber;
+            mStartTimeUtcMillis = other.mStartTimeUtcMillis;
+            mEndTimeUtcMillis = other.mEndTimeUtcMillis;
+            mDescription = other.mDescription;
+            mLongDescription = other.mLongDescription;
+            mVideoWidth = other.mVideoWidth;
+            mVideoHeight = other.mVideoHeight;
+            mPosterArtUri = other.mPosterArtUri;
+            mThumbnailUri = other.mThumbnailUri;
+            mBroadcastGenres = other.mBroadcastGenres;
+            mCanonicalGenres = other.mCanonicalGenres;
+            mContentRatings = other.mContentRatings;
+            mInternalProviderData = other.mInternalProviderData;
+            mAudioLanguages = other.mAudioLanguages;
+            mSearchable = other.mSearchable;
+            mInternalProviderFlag1 = other.mInternalProviderFlag1;
+            mInternalProviderFlag2 = other.mInternalProviderFlag2;
+            mInternalProviderFlag3 = other.mInternalProviderFlag3;
+            mInternalProviderFlag4 = other.mInternalProviderFlag4;
+            mRecordingProhibited = other.mRecordingProhibited;
+            mSeasonTitle = other.mSeasonTitle;
+            mExternalId = other.mInternalProviderId;
+            mPreviewVideoUri = other.mPreviewVideoUri;
+            mLastPlaybackPositionMillis = other.mLastPlaybackPositionMillis;
+            mDurationMillis = other.mDurationMillis;
+            mAppLinkIntentUri = other.mAppLinkIntentUri;
+            mWeight = other.mWeight;
+            mTransient = other.mTransient;
+            mType = other.mType;
+            mWatchNextType = other.mWatchNextType;
+            mPosterArtAspectRatio = other.mPosterArtAspectRatio;
+            mThumbnailAspectRatio = other.mThumbnailAspectRatio;
+            mLogoUri = other.mLogoUri;
+            mAvailability = other.mAvailability;
+            mStartingPrice = other.mStartingPrice;
+            mOfferPrice = other.mOfferPrice;
+            mReleaseDate = other.mReleaseDate;
+            mItemCount = other.mItemCount;
+            mLive = other.mLive;
+            mInteractionType = other.mInteractionType;
+            mInteractionCount  = other.mInteractionCount;
+            mAuthor = other.mAuthor;
+            mReviewRatingStyle = other.mReviewRatingStyle;
+            mReviewRating = other.mReviewRating;
+        }
+
+        /**
+         * Sets a unique id for this program.
+         *
+         * @param programId The value of {@link Programs#_ID} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setId(long programId) {
+            mId = programId;
+            return this;
+        }
+
+        /**
+         * Sets the ID of the {@link Channel} that contains this program.
+         *
+         * @param channelId The value of {@link Programs#COLUMN_CHANNEL_ID for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setChannelId(long channelId) {
+            mChannelId = channelId;
+            return this;
+        }
+
+        /**
+         * Sets the title of this program. For a series, this is the series title.
+         *
+         * @param title The value of {@link Programs#COLUMN_TITLE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setTitle(String title) {
+            mTitle = title;
+            return this;
+        }
+
+        /**
+         * Sets the title of this particular episode for a series.
+         *
+         * @param episodeTitle The value of {@link Programs#COLUMN_EPISODE_TITLE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setEpisodeTitle(String episodeTitle) {
+            mEpisodeTitle = episodeTitle;
+            return this;
+        }
+
+        /**
+         * Sets the season number for this episode for a series.
+         *
+         * @param seasonNumber The value of
+         * {@link Programs#COLUMN_SEASON_DISPLAY_NUMBER} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setSeasonNumber(int seasonNumber) {
+            mSeasonNumber = String.valueOf(seasonNumber);
+            return this;
+        }
+
+        /**
+         * Sets the season number for this episode for a series.
+         *
+         * @param seasonNumber The value of {@link Programs#COLUMN_SEASON_NUMBER} for the program.
+         * @param numericalSeasonNumber An integer value for {@link Programs#COLUMN_SEASON_NUMBER}
+         *                              which will be used for API Level 23 and below.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setSeasonNumber(String seasonNumber, int numericalSeasonNumber) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                mSeasonNumber = seasonNumber;
+            } else {
+                mSeasonNumber = String.valueOf(numericalSeasonNumber);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the episode number in a season for this episode for a series.
+         *
+         * @param episodeNumber The value of
+         * {@link Programs#COLUMN_EPISODE_DISPLAY_NUMBER} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setEpisodeNumber(int episodeNumber) {
+            mEpisodeNumber = String.valueOf(episodeNumber);
+            return this;
+        }
+
+        /**
+         * Sets the episode number in a season for this episode for a series.
+         *
+         * @param episodeNumber The value of {@link Programs#COLUMN_EPISODE_DISPLAY_NUMBER} for the
+         *                      program.
+         * @param numericalEpisodeNumber An integer value for {@link Programs#COLUMN_SEASON_NUMBER}
+         *                               which will be used for API Level 23 and below.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setEpisodeNumber(String episodeNumber, int numericalEpisodeNumber) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                mEpisodeNumber = episodeNumber;
+            } else {
+                mEpisodeNumber = String.valueOf(numericalEpisodeNumber);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the time when the program is going to begin in milliseconds since the epoch.
+         *
+         * @param startTimeUtcMillis The value of {@link Programs#COLUMN_START_TIME_UTC_MILLIS} for
+         *                           the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setStartTimeUtcMillis(long startTimeUtcMillis) {
+            mStartTimeUtcMillis = startTimeUtcMillis;
+            return this;
+        }
+
+        /**
+         * Sets the time when this program is going to end in milliseconds since the epoch.
+         *
+         * @param endTimeUtcMillis The value of {@link Programs#COLUMN_END_TIME_UTC_MILLIS} for the
+         *                         program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setEndTimeUtcMillis(long endTimeUtcMillis) {
+            mEndTimeUtcMillis = endTimeUtcMillis;
+            return this;
+        }
+
+        /**
+         * Sets a brief description of the program. For a series, this would be a brief description
+         * of the episode.
+         *
+         * @param description The value of {@link Programs#COLUMN_SHORT_DESCRIPTION} for the
+         *                    program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setDescription(String description) {
+            mDescription = description;
+            return this;
+        }
+
+        /**
+         * Sets a longer description of a program if one exists.
+         *
+         * @param longDescription The value of {@link Programs#COLUMN_LONG_DESCRIPTION} for the
+         *                        program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setLongDescription(String longDescription) {
+            mLongDescription = longDescription;
+            return this;
+        }
+
+        /**
+         * Sets the video width of the program.
+         *
+         * @param width The value of {@link Programs#COLUMN_VIDEO_WIDTH} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setVideoWidth(int width) {
+            mVideoWidth = width;
+            return this;
+        }
+
+        /**
+         * Sets the video height of the program.
+         *
+         * @param height The value of {@link Programs#COLUMN_VIDEO_HEIGHT} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setVideoHeight(int height) {
+            mVideoHeight = height;
+            return this;
+        }
+
+        /**
+         * Sets the content ratings for this program.
+         *
+         * @param contentRatings An array of {@link TvContentRating} that apply to this program
+         *                       which will be flattened to a String to store in a database.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @see Programs#COLUMN_CONTENT_RATING
+         */
+        public Builder setContentRatings(TvContentRating[] contentRatings) {
+            mContentRatings = contentRatings;
+            return this;
+        }
+
+        /**
+         * Sets the large poster art of the program.
+         *
+         * @param posterArtUri The value of {@link Programs#COLUMN_POSTER_ART_URI} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setPosterArtUri(Uri posterArtUri) {
+            mPosterArtUri = posterArtUri;
+            return this;
+        }
+
+        /**
+         * Sets a small thumbnail of the program.
+         *
+         * @param thumbnailUri The value of {@link Programs#COLUMN_THUMBNAIL_URI} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setThumbnailUri(Uri thumbnailUri) {
+            mThumbnailUri = thumbnailUri;
+            return this;
+        }
+
+        /**
+         * Sets the broadcast-specified genres of the program.
+         *
+         * @param genres Array of genres that apply to the program based on the broadcast standard
+         *               which will be flattened to a String to store in a database.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @see Programs#COLUMN_BROADCAST_GENRE
+         */
+        public Builder setBroadcastGenres(String[] genres) {
+            mBroadcastGenres = genres;
+            return this;
+        }
+
+        /**
+         * Sets the genres of the program.
+         *
+         * @param genres An array of {@link Programs.Genres} that apply to the program which will be
+         *               flattened to a String to store in a database.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @see Programs#COLUMN_CANONICAL_GENRE
+         */
+        public Builder setCanonicalGenres(String[] genres) {
+            mCanonicalGenres = genres;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider data for the program as raw bytes.
+         *
+         * @param data The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_DATA} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderData(byte[] data) {
+            mInternalProviderData = data;
+            return this;
+        }
+
+        /**
+         * Sets the available audio languages for this program as a comma-separated String.
+         *
+         * @param audioLanguages An array of audio languages, in ISO 639-1 or 639-2/T codes, that
+         *                       apply to this program which will be stored in a database.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAudioLanguages(String[] audioLanguages) {
+            mAudioLanguages = audioLanguages;
+            return this;
+        }
+
+        /**
+         * Sets whether this channel can be searched for in other applications.
+         *
+         * @param searchable The value of {@link Programs#COLUMN_SEARCHABLE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setSearchable(boolean searchable) {
+            mSearchable = searchable ? IS_SEARCHABLE : 0;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider flag1 for the program.
+         *
+         * @param flag The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG1} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderFlag1(long flag) {
+            mInternalProviderFlag1 = flag;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider flag2 for the program.
+         *
+         * @param flag The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG2} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderFlag2(long flag) {
+            mInternalProviderFlag2 = flag;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider flag3 for the program.
+         *
+         * @param flag The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG3} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderFlag3(long flag) {
+            mInternalProviderFlag3 = flag;
+            return this;
+        }
+
+        /**
+         * Sets the internal provider flag4 for the program.
+         *
+         * @param flag The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG4} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderFlag4(long flag) {
+            mInternalProviderFlag4 = flag;
+            return this;
+        }
+
+        /**
+         * Sets whether this program cannot be recorded.
+         *
+         * @param prohibited The value of {@link Programs#COLUMN_RECORDING_PROHIBITED} for the
+         *                   program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setRecordingProhibited(boolean prohibited) {
+            mRecordingProhibited = prohibited ? IS_RECORDING_PROHIBITED : 0;
+            return this;
+        }
+
+        /**
+         * Sets a custom name for the season, if applicable.
+         *
+         * @param seasonTitle The value of {@link Programs#COLUMN_SEASON_TITLE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setSeasonTitle(String seasonTitle) {
+            mSeasonTitle = seasonTitle;
+            return this;
+        }
+
+        /**
+         * Sets external ID for the program.
+         *
+         * @param externalId The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_ID} for the
+         *                   program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInternalProviderId(String externalId) {
+            mExternalId = externalId;
+            return this;
+        }
+
+        /**
+         * Sets a URI for the preview video.
+         *
+         * @param previewVideoUri The value of {@link Programs#COLUMN_PREVIEW_VIDEO_URI} for the
+         *                        program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setPreviewVideoUri(Uri previewVideoUri) {
+            mPreviewVideoUri = previewVideoUri;
+            return this;
+        }
+
+        /**
+         * Sets the last playback position (in milliseconds) of the preview video.
+         *
+         * @param position The value of {@link Programs#COLUMN_LAST_PLAYBACK_POSITION_MILLIS} for
+         *                 the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setLastPlaybackPositionMillis(int position) {
+            mLastPlaybackPositionMillis = position;
+            return this;
+        }
+
+        /**
+         * Sets the last playback duration (in milliseconds) of the preview video.
+         *
+         * @param duration The value of {@link Programs#COLUMN_DURATION_MILLIS} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setDurationMillis(int duration) {
+            mDurationMillis = duration;
+            return this;
+        }
+
+        /**
+         * Sets the intent URI of the app link for the preview video.
+         *
+         * @param appLinkIntentUri The value of {@link Programs#COLUMN_APP_LINK_INTENT_URI}
+         *                         for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAppLinkIntentUri(Uri appLinkIntentUri) {
+            mAppLinkIntentUri = appLinkIntentUri;
+            return this;
+        }
+
+        /**
+         * Sets the intent of the app link for the preview video.
+         *
+         * @param appLinkIntent The Intent to be executed when the App Linking card is selected
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAppLinkIntent(Intent appLinkIntent) {
+            return setAppLinkIntentUri(Uri.parse(appLinkIntent.toUri(Intent.URI_INTENT_SCHEME)));
+        }
+
+        /**
+         * Sets the weight of the preview program within the channel.
+         *
+         * @param weight The value of {@link Programs#COLUMN_WEIGHT} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setWeight(int weight) {
+            mWeight = weight;
+            return this;
+        }
+
+        /**
+         * Sets whether this program is transient or not.
+         *
+         * @param transientValue The value of {@link Programs#COLUMN_TRANSIENT} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @RestrictTo(LIBRARY_GROUP)
+        public Builder setTransient(boolean transientValue) {
+            mTransient = transientValue ? IS_TRANSIENT : 0;
+            return this;
+        }
+
+        /**
+         * Sets the type of this program content.
+         *
+         * <p>The value should match one of the followings:
+         * {@link Programs#TYPE_MOVIE},
+         * {@link Programs#TYPE_TV_SERIES},
+         * {@link Programs#TYPE_TV_SEASON},
+         * {@link Programs#TYPE_TV_EPISODE},
+         * {@link Programs#TYPE_CLIP},
+         * {@link Programs#TYPE_EVENT},
+         * {@link Programs#TYPE_CHANNEL},
+         * {@link Programs#TYPE_TRACK},
+         * {@link Programs#TYPE_ALBUM},
+         * {@link Programs#TYPE_ARTIST},
+         * {@link Programs#TYPE_PLAYLIST}, and
+         * {@link Programs#TYPE_STATION}.
+         *
+         * @param type The value of {@link Programs#COLUMN_TYPE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setType(String type) {
+            mType = type;
+            return this;
+        }
+
+        /**
+         * Sets the "watch next" type of this program content.
+         *
+         * <p>The value should match one of the followings:
+         * {@link Programs#WATCH_NEXT_TYPE_CONTINUE},
+         * {@link Programs#WATCH_NEXT_TYPE_NEXT}, and
+         * {@link Programs#WATCH_NEXT_TYPE_NEW}.
+         *
+         * @param watchNextType The value of {@link Programs#COLUMN_WATCH_NEXT_TYPE} for the
+         *                      program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setWatchNextType(String watchNextType) {
+            mWatchNextType = watchNextType;
+            return this;
+        }
+
+        /**
+         * Sets the aspect ratio of the poster art for this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link Programs#ASPECT_RATIO_16_9},
+         * {@link Programs#ASPECT_RATIO_3_2},
+         * {@link Programs#ASPECT_RATIO_1_1}, and
+         * {@link Programs#ASPECT_RATIO_2_3}.
+         *
+         * @param ratio The value of {@link Programs#COLUMN_POSTER_ART_ASPECT_RATIO} for the
+         *              program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setPosterArtAspectRatio(String ratio) {
+            mPosterArtAspectRatio = ratio;
+            return this;
+        }
+
+        /**
+         * Sets the aspect ratio of the thumbnail for this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link Programs#ASPECT_RATIO_16_9},
+         * {@link Programs#ASPECT_RATIO_3_2},
+         * {@link Programs#ASPECT_RATIO_1_1}, and
+         * {@link Programs#ASPECT_RATIO_2_3}.
+         *
+         * @param ratio The value of {@link Programs#COLUMN_THUMBNAIL_ASPECT_RATIO} for the
+         *              program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setThumbnailAspectRatio(String ratio) {
+            mThumbnailAspectRatio = ratio;
+            return this;
+        }
+
+        /**
+         * Sets the URI for the logo of this TV program.
+         *
+         * @param logoUri The value of {@link Programs#COLUMN_LOGO_URI} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setLogoUri(Uri logoUri) {
+            mLogoUri = logoUri;
+            return this;
+        }
+
+        /**
+         * Sets the availability of this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link Programs#AVAILABILITY_AVAILABLE},
+         * {@link Programs#AVAILABILITY_FREE_WITH_SUBSCRIPTION}, and
+         * {@link Programs#AVAILABILITY_PAID_CONTENT}.
+         *
+         * @param availability The value of {@link Programs#COLUMN_AVAILABILITY} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAvailability(String availability) {
+            mAvailability = availability;
+            return this;
+        }
+
+        /**
+         * Sets the starting price of this TV program.
+         *
+         * @param price The value of {@link Programs#COLUMN_STARTING_PRICE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setStartingPrice(String price) {
+            mStartingPrice = price;
+            return this;
+        }
+
+        /**
+         * Sets the offer price of this TV program.
+         *
+         * @param price The value of {@link Programs#COLUMN_OFFER_PRICE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setOfferPrice(String price) {
+            mOfferPrice = price;
+            return this;
+        }
+
+        /**
+         * Sets the release date of this TV program.
+         *
+         * <p>The value should be in the form of either "yyyy-MM-dd" or "yyyy".
+         *
+         * @param releaseDate The value of {@link Programs#COLUMN_RELEASE_DATE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setReleaseDate(String releaseDate) {
+            mReleaseDate = releaseDate;
+            return this;
+        }
+
+        /**
+         * Sets the release date of this TV program.
+         *
+         * @param releaseDate The value of {@link Programs#COLUMN_RELEASE_DATE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setReleaseDate(Date releaseDate) {
+            mReleaseDate = sFormat.format(releaseDate);
+            return this;
+        }
+
+        /**
+         * Sets the count of the items included in this TV program.
+         *
+         * @param itemCount value of {@link Programs#COLUMN_ITEM_COUNT} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setItemCount(int itemCount) {
+            mItemCount = itemCount;
+            return this;
+        }
+
+        /**
+         * Sets whether this TV program is live or not.
+         *
+         * @param live The value of {@link Programs#COLUMN_LIVE} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setLive(boolean live) {
+            mLive = live ? IS_LIVE : 0;
+            return this;
+        }
+
+        /**
+         * Sets the type of interaction for this TV program.
+         *
+         * <p> The value should match one of the followings:
+         * {@link Programs#INTERACTION_TYPE_LISTENS},
+         * {@link Programs#INTERACTION_TYPE_FOLLOWERS},
+         * {@link Programs#INTERACTION_TYPE_FANS},
+         * {@link Programs#INTERACTION_TYPE_LIKES},
+         * {@link Programs#INTERACTION_TYPE_THUMBS},
+         * {@link Programs#INTERACTION_TYPE_VIEWS}, and
+         * {@link Programs#INTERACTION_TYPE_VIEWERS}.
+         *
+         * @param interactionType The value of {@link Programs#COLUMN_AVAILABILITY} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInteractionType(String interactionType) {
+            mInteractionType = interactionType;
+            return this;
+        }
+
+        /**
+         * Sets the interaction count for this program.
+         *
+         * @param interactionCount value of {@link Programs#COLUMN_INTERACTION_COUNT} for the
+         *                         program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setInteractionCount(int interactionCount) {
+            mInteractionCount = interactionCount;
+            return this;
+        }
+
+        /**
+         * Sets the author or artist of this content.
+         *
+         * @param author The value of {@link Programs#COLUMN_AUTHOR} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setAuthor(String author) {
+            mAuthor = author;
+            return this;
+        }
+
+        /**
+         * The review rating score style used for {@link #setReviewRating}.
+         *
+         * <p> The value should match one of the followings:
+         * {@link Programs#REVIEW_RATING_STYLE_STARS},
+         * {@link Programs#REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, and
+         * {@link Programs#REVIEW_RATING_STYLE_PERCENTAGE}.
+         *
+         * @param reviewRatingStyle The value of {@link Programs#COLUMN_REVIEW_RATING_STYLE} for the
+         *                          program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setReviewRatingStyle(String reviewRatingStyle) {
+            mReviewRatingStyle = reviewRatingStyle;
+            return this;
+        }
+
+        /**
+         * Sets the review rating score for this program.
+         *
+         * <p>The format of the value is dependent on {@link Programs#COLUMN_REVIEW_RATING_STYLE}.
+         * If the style is {@link Programs#REVIEW_RATING_STYLE_STARS}, the value should be a real
+         * number between 0.0 and 5.0. (e.g. "4.5") If the style is
+         * {@link Programs#REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, the value should be two integers,
+         * one for thumbs-up count and the other for thumbs-down count, with a comma between them.
+         * (e.g. "200,40") If the style is {@link Programs#REVIEW_RATING_STYLE_PERCENTAGE}, the
+         * value shoule be a real number between 0 and 100. (e.g. "99.9")
+         *
+         * @param reviewRating The value of {@link Programs#COLUMN_AVAILABILITY} for the program.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setReviewRating(String reviewRating) {
+            mReviewRating = reviewRating;
+            return this;
+        }
+
+        /**
+         * @return A new Program with values supplied by the Builder.
+         */
+        public Program build() {
+            return new Program(this);
+        }
+    }
+}
diff --git a/tv-provider/src/android/support/media/tv/TvContractCompat.java b/tv-provider/src/android/support/media/tv/TvContractCompat.java
new file mode 100644
index 0000000..412640c
--- /dev/null
+++ b/tv-provider/src/android/support/media/tv/TvContractCompat.java
@@ -0,0 +1,2533 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.tv;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Intent;
+import android.media.tv.TvContentRating;
+import android.media.tv.TvContract;
+import android.net.Uri;
+import android.provider.BaseColumns;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The contract between the TV provider and applications. Contains definitions for the supported
+ * URIs and columns.
+ * <h3>Overview</h3>
+ *
+ * <p>TvContract defines a basic database of TV content metadata such as channel and program
+ * information. The information is stored in {@link Channels} and {@link Programs} tables.
+ *
+ * <ul>
+ *     <li>A row in the {@link Channels} table represents information about a TV channel. The data
+ *         format can vary greatly from standard to standard or according to service provider, thus
+ *         the columns here are mostly comprised of basic entities that are usually seen to users
+ *         regardless of standard such as channel number and name.</li>
+ *     <li>A row in the {@link Programs} table represents a set of data describing a TV program such
+ *         as program title and start time.</li>
+ * </ul>
+ */
+public final class TvContractCompat {
+    /** The authority for the TV provider. */
+    public static final String AUTHORITY = "android.media.tv";
+
+    /**
+     * Permission to read TV listings. This is required to read all the TV channel and program
+     * information available on the system.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS";
+
+    private static final String PATH_CHANNEL = "channel";
+    private static final String PATH_PROGRAM = "program";
+    private static final String PATH_RECORDED_PROGRAM = "recorded_program";
+    private static final String PATH_PASSTHROUGH = "passthrough";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify TV input
+     * ID to filter channels.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static final String PARAM_INPUT = "input";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify channel
+     * ID to filter programs.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static final String PARAM_CHANNEL = "channel";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify start
+     * time (in milliseconds since the epoch) to filter programs.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static final String PARAM_START_TIME = "start_time";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify end time
+     * (in milliseconds since the epoch) to filter programs.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static final String PARAM_END_TIME = "end_time";
+
+    /**
+     * A query, update or delete URI parameter that allows the caller to operate on all or
+     * browsable-only channels. If set to "true", the rows that contain non-browsable channels are
+     * not affected.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static final String PARAM_BROWSABLE_ONLY = "browsable_only";
+
+    /**
+     * A optional query, update or delete URI parameter that allows the caller to specify canonical
+     * genre to filter programs.
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public static final String PARAM_CANONICAL_GENRE = "canonical_genre";
+
+    /**
+     * Builds an ID that uniquely identifies a TV input service.
+     *
+     * @param name The {@link ComponentName} of the TV input service to build ID for.
+     * @return the ID for the given TV input service.
+     */
+    public static String buildInputId(ComponentName name) {
+        return TvContract.buildInputId(name);
+    }
+
+    /**
+     * Builds a URI that points to a specific channel.
+     *
+     * @param channelId The ID of the channel to point to.
+     */
+    public static Uri buildChannelUri(long channelId) {
+        return TvContract.buildChannelUri(channelId);
+    }
+
+    /**
+     * Build a special channel URI intended to be used with pass-through inputs. (e.g. HDMI)
+     *
+     * @param inputId The ID of the pass-through input to build a channels URI for.
+     */
+    public static Uri buildChannelUriForPassthroughInput(String inputId) {
+        return TvContract.buildChannelUriForPassthroughInput(inputId);
+    }
+
+    /**
+     * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
+     *
+     * @param channelId The ID of the channel whose logo is pointed to.
+     */
+    public static Uri buildChannelLogoUri(long channelId) {
+        return TvContract.buildChannelLogoUri(channelId);
+    }
+
+    /**
+     * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
+     *
+     * @param channelUri The URI of the channel whose logo is pointed to.
+     */
+    public static Uri buildChannelLogoUri(Uri channelUri) {
+        return TvContract.buildChannelLogoUri(channelUri);
+    }
+
+    /**
+     * Builds a URI that points to all channels from a given TV input.
+     *
+     * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a
+     *            URI for all the TV inputs.
+     */
+    public static Uri buildChannelsUriForInput(@Nullable String inputId) {
+        return TvContract.buildChannelsUriForInput(inputId);
+    }
+
+    /**
+     * Builds a URI that points to a specific program.
+     *
+     * @param programId The ID of the program to point to.
+     */
+    public static Uri buildProgramUri(long programId) {
+        return TvContract.buildProgramUri(programId);
+    }
+
+    /**
+     * Builds a URI that points to all programs on a given channel.
+     *
+     * @param channelId The ID of the channel to return programs for.
+     */
+    public static Uri buildProgramsUriForChannel(long channelId) {
+        return TvContract.buildProgramsUriForChannel(channelId);
+    }
+
+    /**
+     * Builds a URI that points to all programs on a given channel.
+     *
+     * @param channelUri The URI of the channel to return programs for.
+     */
+    public static Uri buildProgramsUriForChannel(Uri channelUri) {
+        return TvContract.buildProgramsUriForChannel(channelUri);
+    }
+
+    /**
+     * Builds a URI that points to programs on a specific channel whose schedules overlap with the
+     * given time frame.
+     *
+     * @param channelId The ID of the channel to return programs for.
+     * @param startTime The start time used to filter programs. The returned programs should have
+     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time.
+     * @param endTime The end time used to filter programs. The returned programs should have
+     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
+     */
+    public static Uri buildProgramsUriForChannel(long channelId, long startTime,
+            long endTime) {
+        return TvContract.buildProgramsUriForChannel(channelId, startTime, endTime);
+    }
+
+    /**
+     * Builds a URI that points to programs on a specific channel whose schedules overlap with the
+     * given time frame.
+     *
+     * @param channelUri The URI of the channel to return programs for.
+     * @param startTime The start time used to filter programs. The returned programs should have
+     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time.
+     * @param endTime The end time used to filter programs. The returned programs should have
+     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
+     */
+    public static Uri buildProgramsUriForChannel(Uri channelUri, long startTime,
+            long endTime) {
+        return TvContract.buildProgramsUriForChannel(channelUri, startTime, endTime);
+    }
+
+    /**
+     * Builds a URI that points to a specific recorded program.
+     *
+     * @param recordedProgramId The ID of the recorded program to point to.
+     */
+    public static Uri buildRecordedProgramUri(long recordedProgramId) {
+        if (android.os.Build.VERSION.SDK_INT >= 24) {
+            return TvContract.buildRecordedProgramUri(recordedProgramId);
+        } else {
+            return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, recordedProgramId);
+        }
+    }
+
+    private static boolean isTvUri(Uri uri) {
+        return uri != null && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())
+                && AUTHORITY.equals(uri.getAuthority());
+    }
+
+    private static boolean isTwoSegmentUriStartingWith(Uri uri, String pathSegment) {
+        List<String> pathSegments = uri.getPathSegments();
+        return pathSegments.size() == 2 && pathSegment.equals(pathSegments.get(0));
+    }
+
+    /**
+     * Returns {@code true}, if {@code uri} is a channel URI.
+     */
+    public static boolean isChannelUri(Uri uri) {
+        if (android.os.Build.VERSION.SDK_INT >= 24) {
+            return TvContract.isChannelUri(uri);
+        } else {
+            return isChannelUriForTunerInput(uri) || isChannelUriForPassthroughInput(uri);
+        }
+    }
+
+    /**
+     * Returns {@code true}, if {@code uri} is a channel URI for a tuner input.
+     */
+    public static boolean isChannelUriForTunerInput(Uri uri) {
+        if (android.os.Build.VERSION.SDK_INT >= 24) {
+            return TvContract.isChannelUriForTunerInput(uri);
+        } else {
+            return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_CHANNEL);
+        }
+    }
+
+    /**
+     * Returns {@code true}, if {@code uri} is a channel URI for a pass-through input.
+     */
+    public static boolean isChannelUriForPassthroughInput(Uri uri) {
+        if (android.os.Build.VERSION.SDK_INT >= 24) {
+            return TvContract.isChannelUriForPassthroughInput(uri);
+        } else {
+            return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PASSTHROUGH);
+        }
+    }
+
+    /**
+     * Returns {@code true}, if {@code uri} is a program URI.
+     */
+    public static boolean isProgramUri(Uri uri) {
+        if (android.os.Build.VERSION.SDK_INT >= 24) {
+            return TvContract.isProgramUri(uri);
+        } else {
+            return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PROGRAM);
+        }
+    }
+
+
+    private TvContractCompat() {}
+
+    /**
+     * Common base for the tables of TV channels/programs.
+     */
+    public interface BaseTvColumns extends BaseColumns {
+        /**
+         * The name of the package that owns the current row.
+         *
+         * <p>The TV provider fills in this column with the name of the package that provides the
+         * initial data of the row. If the package is later uninstalled, the rows it owns are
+         * automatically removed from the tables.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_PACKAGE_NAME = "package_name";
+    }
+
+    /** Column definitions for the TV channels table. */
+    public static final class Channels implements BaseTvColumns {
+
+        /** The content:// style URI for this table. */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_CHANNEL);
+
+        /** The MIME type of a directory of TV channels. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/channel";
+
+        /** The MIME type of a single TV channel. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
+
+        /**
+         * A generic channel type.
+         *
+         * Use this if the current channel is streaming-based or its broadcast system type does not
+         * fit under any other types. This is the default channel type.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_OTHER = "TYPE_OTHER";
+
+        /**
+         * The channel type for NTSC.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_NTSC = "TYPE_NTSC";
+
+        /**
+         * The channel type for PAL.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_PAL = "TYPE_PAL";
+
+        /**
+         * The channel type for SECAM.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_SECAM = "TYPE_SECAM";
+
+        /**
+         * The channel type for DVB-T (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_T = "TYPE_DVB_T";
+
+        /**
+         * The channel type for DVB-T2 (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_T2 = "TYPE_DVB_T2";
+
+        /**
+         * The channel type for DVB-S (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_S = "TYPE_DVB_S";
+
+        /**
+         * The channel type for DVB-S2 (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_S2 = "TYPE_DVB_S2";
+
+        /**
+         * The channel type for DVB-C (cable).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_C = "TYPE_DVB_C";
+
+        /**
+         * The channel type for DVB-C2 (cable).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_C2 = "TYPE_DVB_C2";
+
+        /**
+         * The channel type for DVB-H (handheld).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_H = "TYPE_DVB_H";
+
+        /**
+         * The channel type for DVB-SH (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_SH = "TYPE_DVB_SH";
+
+        /**
+         * The channel type for ATSC (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ATSC_T = "TYPE_ATSC_T";
+
+        /**
+         * The channel type for ATSC (cable).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ATSC_C = "TYPE_ATSC_C";
+
+        /**
+         * The channel type for ATSC-M/H (mobile/handheld).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ATSC_M_H = "TYPE_ATSC_M_H";
+
+        /**
+         * The channel type for ISDB-T (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ISDB_T = "TYPE_ISDB_T";
+
+        /**
+         * The channel type for ISDB-Tb (Brazil).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ISDB_TB = "TYPE_ISDB_TB";
+
+        /**
+         * The channel type for ISDB-S (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ISDB_S = "TYPE_ISDB_S";
+
+        /**
+         * The channel type for ISDB-C (cable).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ISDB_C = "TYPE_ISDB_C";
+
+        /**
+         * The channel type for 1seg (handheld).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_1SEG = "TYPE_1SEG";
+
+        /**
+         * The channel type for DTMB (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DTMB = "TYPE_DTMB";
+
+        /**
+         * The channel type for CMMB (handheld).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_CMMB = "TYPE_CMMB";
+
+        /**
+         * The channel type for T-DMB (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_T_DMB = "TYPE_T_DMB";
+
+        /**
+         * The channel type for S-DMB (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_S_DMB = "TYPE_S_DMB";
+
+        /**
+         * The channel type for preview videos.
+         *
+         * <P>Unlike other broadcast TV channel types, the programs in the preview channel usually
+         * are promotional videos. The UI may treat the preview channels differently from the other
+         * broadcast channels.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_PREVIEW = "TYPE_PREVIEW";
+
+        /** A generic service type. */
+        public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
+
+        /** The service type for regular TV channels that have both audio and video. */
+        public static final String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO";
+
+        /** The service type for radio channels that have audio only. */
+        public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
+
+        /** The video format for 240p. */
+        public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P";
+
+        /** The video format for 360p. */
+        public static final String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P";
+
+        /** The video format for 480i. */
+        public static final String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I";
+
+        /** The video format for 480p. */
+        public static final String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P";
+
+        /** The video format for 576i. */
+        public static final String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I";
+
+        /** The video format for 576p. */
+        public static final String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P";
+
+        /** The video format for 720p. */
+        public static final String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P";
+
+        /** The video format for 1080i. */
+        public static final String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I";
+
+        /** The video format for 1080p. */
+        public static final String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P";
+
+        /** The video format for 2160p. */
+        public static final String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P";
+
+        /** The video format for 4320p. */
+        public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P";
+
+        /** The video resolution for standard-definition. */
+        public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD";
+
+        /** The video resolution for enhanced-definition. */
+        public static final String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED";
+
+        /** The video resolution for high-definition. */
+        public static final String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD";
+
+        /** The video resolution for full high-definition. */
+        public static final String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD";
+
+        /** The video resolution for ultra high-definition. */
+        public static final String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD";
+
+        private static final Map<String, String> VIDEO_FORMAT_TO_RESOLUTION_MAP = new HashMap<>();
+
+        static {
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD);
+        }
+
+        /**
+         * Returns the video resolution (definition) for a given video format.
+         *
+         * @param videoFormat The video format defined in {@link Channels}.
+         * @return the corresponding video resolution string. {@code null} if the resolution string
+         *         is not defined for the given video format.
+         * @see #COLUMN_VIDEO_FORMAT
+         */
+        @Nullable
+        public static String getVideoResolution(String videoFormat) {
+            return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat);
+        }
+
+        /**
+         * The ID of the TV input service that provides this TV channel.
+         *
+         * <p>Use {@link #buildInputId} to build the ID.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INPUT_ID = "input_id";
+
+        /**
+         * The broadcast system type of this TV channel.
+         *
+         * <p>This is used to indicate the broadcast standard (e.g. ATSC, DVB or ISDB) the current
+         * channel conforms to. Use {@link #TYPE_OTHER} for streaming-based channels, which is the
+         * default channel type. The value should match to one of the followings:
+         * {@link #TYPE_1SEG},
+         * {@link #TYPE_ATSC_C},
+         * {@link #TYPE_ATSC_M_H},
+         * {@link #TYPE_ATSC_T},
+         * {@link #TYPE_CMMB},
+         * {@link #TYPE_DTMB},
+         * {@link #TYPE_DVB_C},
+         * {@link #TYPE_DVB_C2},
+         * {@link #TYPE_DVB_H},
+         * {@link #TYPE_DVB_S},
+         * {@link #TYPE_DVB_S2},
+         * {@link #TYPE_DVB_SH},
+         * {@link #TYPE_DVB_T},
+         * {@link #TYPE_DVB_T2},
+         * {@link #TYPE_ISDB_C},
+         * {@link #TYPE_ISDB_S},
+         * {@link #TYPE_ISDB_T},
+         * {@link #TYPE_ISDB_TB},
+         * {@link #TYPE_NTSC},
+         * {@link #TYPE_OTHER},
+         * {@link #TYPE_PAL},
+         * {@link #TYPE_SECAM},
+         * {@link #TYPE_S_DMB}, and
+         * {@link #TYPE_T_DMB}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_TYPE = "type";
+
+        /**
+         * The predefined service type of this TV channel.
+         *
+         * <p>This is primarily used to indicate whether the current channel is a regular TV channel
+         * or a radio-like channel. Use the same coding for {@code service_type} in the underlying
+         * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB
+         * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER},
+         * {@link #SERVICE_TYPE_AUDIO_VIDEO}, {@link #SERVICE_TYPE_AUDIO}
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_SERVICE_TYPE = "service_type";
+
+        /**
+         * The original network ID of this TV channel.
+         *
+         * <p>It is used to identify the originating delivery system, if applicable. Use the same
+         * coding for {@code original_network_id} for ETSI EN 300 468/TR 101 211 and ARIB STD-B10.
+         *
+         * <p>This is a required field only if the underlying broadcast standard defines the same
+         * name field. Otherwise, leave empty.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
+
+        /**
+         * The transport stream ID of this channel.
+         *
+         * <p>It is used to identify the Transport Stream that contains the current channel from any
+         * other multiplex within a network, if applicable. Use the same coding for
+         * {@code transport_stream_id} defined in ISO/IEC 13818-1 if the channel is transmitted via
+         * the MPEG Transport Stream.
+         *
+         * <p>This is a required field only if the current channel is transmitted via the MPEG
+         * Transport Stream. Leave empty otherwise.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
+
+        /**
+         * The service ID of this channel.
+         *
+         * <p>It is used to identify the current service, or channel from any other services within
+         * a given Transport Stream, if applicable. Use the same coding for {@code service_id} in
+         * ETSI EN 300 468 and ARIB STD-B10 or {@code program_number} in ISO/IEC 13818-1.
+         *
+         * <p>This is a required field only if the underlying broadcast standard defines the same
+         * name field, or the current channel is transmitted via the MPEG Transport Stream. Leave
+         * empty otherwise.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_SERVICE_ID = "service_id";
+
+        /**
+         * The channel number that is displayed to the user.
+         *
+         * <p>The format can vary depending on broadcast standard and product specification.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_DISPLAY_NUMBER = "display_number";
+
+        /**
+         * The channel name that is displayed to the user.
+         *
+         * <p>A call sign is a good candidate to use for this purpose but any name that helps the
+         * user recognize the current channel will be enough. Can also be empty depending on
+         * broadcast standard.
+         *
+         * <p> Type: TEXT
+         */
+        public static final String COLUMN_DISPLAY_NAME = "display_name";
+
+        /**
+         * The network affiliation for this TV channel.
+         *
+         * <p>This is used to identify a channel that is commonly called by its network affiliation
+         * instead of the display name. Examples include ABC for the channel KGO-HD, FOX for the
+         * channel KTVU-HD and NBC for the channel KNTV-HD. Can be empty if not applicable.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_NETWORK_AFFILIATION = "network_affiliation";
+
+        /**
+         * The description of this TV channel.
+         *
+         * <p>Can be empty initially.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_DESCRIPTION = "description";
+
+        /**
+         * The typical video format for programs from this TV channel.
+         *
+         * <p>This is primarily used to filter out channels based on video format by applications.
+         * The value should match one of the followings: {@link #VIDEO_FORMAT_240P},
+         * {@link #VIDEO_FORMAT_360P}, {@link #VIDEO_FORMAT_480I}, {@link #VIDEO_FORMAT_480P},
+         * {@link #VIDEO_FORMAT_576I}, {@link #VIDEO_FORMAT_576P}, {@link #VIDEO_FORMAT_720P},
+         * {@link #VIDEO_FORMAT_1080I}, {@link #VIDEO_FORMAT_1080P}, {@link #VIDEO_FORMAT_2160P},
+         * {@link #VIDEO_FORMAT_4320P}. Note that the actual video resolution of each program from a
+         * given channel can vary thus one should use {@link Programs#COLUMN_VIDEO_WIDTH} and
+         * {@link Programs#COLUMN_VIDEO_HEIGHT} to get more accurate video resolution.
+         *
+         * <p>Type: TEXT
+         *
+         * @see #getVideoResolution
+         */
+        public static final String COLUMN_VIDEO_FORMAT = "video_format";
+
+        /**
+         * The flag indicating whether this TV channel is browsable or not.
+         *
+         * <p>A value of 1 indicates the channel is included in the channel list that applications
+         * use to browse channels, a value of 0 indicates the channel is not included in the list.
+         * If not specified, this value is set to 0 (not browsable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @hide
+         */
+        @RestrictTo(LIBRARY_GROUP)
+        public static final String COLUMN_BROWSABLE = "browsable";
+
+        /**
+         * The flag indicating whether this TV channel is searchable or not.
+         *
+         * <p>The columns of searchable channels can be read by other applications that have proper
+         * permission. Care must be taken not to open sensitive data.
+         *
+         * <p>A value of 1 indicates that the channel is searchable and its columns can be read by
+         * other applications, a value of 0 indicates that the channel is hidden and its columns can
+         * be read only by the package that owns the channel and the system. If not specified, this
+         * value is set to 1 (searchable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_SEARCHABLE = "searchable";
+
+        /**
+         * The flag indicating whether this TV channel is locked or not.
+         *
+         * <p>This is primarily used for alternative parental control to prevent unauthorized users
+         * from watching the current channel regardless of the content rating. A value of 1
+         * indicates the channel is locked and the user is required to enter passcode to unlock it
+         * in order to watch the current program from the channel, a value of 0 indicates the
+         * channel is not locked thus the user is not prompted to enter passcode If not specified,
+         * this value is set to 0 (not locked) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @hide
+         */
+        @RestrictTo(LIBRARY_GROUP)
+        public static final String COLUMN_LOCKED = "locked";
+
+        /**
+         * The URI for the app badge icon of the app link template for this channel.
+         *
+         * <p>This small icon is overlaid at the bottom of the poster art specified by
+         * {@link #COLUMN_APP_LINK_POSTER_ART_URI}. The data in the column must be a URI in one of
+         * the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_APP_LINK_COLOR
+         * @see #COLUMN_APP_LINK_INTENT_URI
+         * @see #COLUMN_APP_LINK_POSTER_ART_URI
+         * @see #COLUMN_APP_LINK_TEXT
+         */
+        public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri";
+
+        /**
+         * The URI for the poster art used as the background of the app link template for this
+         * channel.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_APP_LINK_COLOR
+         * @see #COLUMN_APP_LINK_ICON_URI
+         * @see #COLUMN_APP_LINK_INTENT_URI
+         * @see #COLUMN_APP_LINK_TEXT
+         */
+        public static final String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
+
+        /**
+         * The link text of the app link template for this channel.
+         *
+         * <p>This provides a short description of the action that happens when the corresponding
+         * app link is clicked.
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_APP_LINK_COLOR
+         * @see #COLUMN_APP_LINK_ICON_URI
+         * @see #COLUMN_APP_LINK_INTENT_URI
+         * @see #COLUMN_APP_LINK_POSTER_ART_URI
+         */
+        public static final String COLUMN_APP_LINK_TEXT = "app_link_text";
+
+        /**
+         * The accent color of the app link template for this channel. This is primarily used for
+         * the background color of the text box in the template.
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: INTEGER (color value)
+         * @see #COLUMN_APP_LINK_ICON_URI
+         * @see #COLUMN_APP_LINK_INTENT_URI
+         * @see #COLUMN_APP_LINK_POSTER_ART_URI
+         * @see #COLUMN_APP_LINK_TEXT
+         */
+        public static final String COLUMN_APP_LINK_COLOR = "app_link_color";
+
+        /**
+         * The intent URI of the app link for this channel.
+         *
+         * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME}
+         * and converted back to the original intent with {@link Intent#parseUri}. The intent is
+         * launched when the user clicks the corresponding app link for the current channel.
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_APP_LINK_COLOR
+         * @see #COLUMN_APP_LINK_ICON_URI
+         * @see #COLUMN_APP_LINK_POSTER_ART_URI
+         * @see #COLUMN_APP_LINK_TEXT
+         */
+        public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+
+        /**
+         * Internal data used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: BLOB
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+
+        /**
+         * The version number of this row entry used by TV input services.
+         *
+         * <p>This is best used by sync adapters to identify the rows to update. The number can be
+         * defined by individual TV input services. One may assign the same value as
+         * {@code version_number} that appears in ETSI EN 300 468 or ATSC A/65, if the data are
+         * coming from a TV broadcast.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_VERSION_NUMBER = "version_number";
+
+        /**
+         * The flag indicating whether this TV channel is transient or not.
+         *
+         * <p>A value of 1 indicates that the channel will be automatically removed by the system on
+         * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not
+         * specified, this value is set to 0 (not transient) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @hide
+         */
+        @RestrictTo(LIBRARY_GROUP)
+        public static final String COLUMN_TRANSIENT = "transient";
+
+        private Channels() {}
+
+        /**
+         * A sub-directory of a single TV channel that represents its primary logo.
+         *
+         * <p>To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw
+         * channel URI.  The resulting URI represents an image file, and should be interacted
+         * using ContentResolver.openAssetFileDescriptor.
+         *
+         * <p>Note that this sub-directory also supports opening the logo as an asset file in write
+         * mode.  Callers can create or replace the primary logo associated with this channel by
+         * opening the asset file and writing the full-size photo contents into it. (Make sure there
+         * is no padding around the logo image.) When the file is closed, the image will be parsed,
+         * sized down if necessary, and stored.
+         *
+         * <p>Usage example:
+         * <pre>
+         * public void writeChannelLogo(long channelId, byte[] logo) {
+         *     Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId);
+         *     try {
+         *         AssetFileDescriptor fd =
+         *             getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw");
+         *         OutputStream os = fd.createOutputStream();
+         *         os.write(logo);
+         *         os.close();
+         *         fd.close();
+         *     } catch (IOException e) {
+         *         // Handle error cases.
+         *     }
+         * }
+         * </pre>
+         */
+        public static final class Logo {
+
+            /**
+             * The directory twig for this sub-table.
+             */
+            public static final String CONTENT_DIRECTORY = "logo";
+
+            private Logo() {}
+        }
+    }
+
+    /**
+     * Column definitions for the TV programs table.
+     *
+     * <p>By default, the query results will be sorted by
+     * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} in ascending order.
+     */
+    public static final class Programs implements BaseTvColumns {
+
+        /** The content:// style URI for this table. */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_PROGRAM);
+
+        /** The MIME type of a directory of TV programs. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/program";
+
+        /** The MIME type of a single TV program. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
+
+        /**
+         * The program type for movie.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_MOVIE = "TYPE_MOVIE";
+
+        /**
+         * The program type for TV series.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+
+        /**
+         * The program type for TV season.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+
+        /**
+         * The program type for TV episode.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+
+        /**
+         * The program type for clip.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_CLIP = "TYPE_CLIP";
+
+        /**
+         * The program type for event.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_EVENT = "TYPE_EVENT";
+
+        /**
+         * The program type for channel.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_CHANNEL = "TYPE_CHANNEL";
+
+        /**
+         * The program type for track.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_TRACK = "TYPE_TRACK";
+
+        /**
+         * The program type for album.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ALBUM = "TYPE_ALBUM";
+
+        /**
+         * The program type for artist.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ARTIST = "TYPE_ARTIST";
+
+        /**
+         * The program type for playlist.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+
+        /**
+         * The program type for station.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_STATION = "TYPE_STATION";
+
+        /**
+         * The watch next type for CONTINUE.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+
+        /**
+         * The watch next type for NEXT.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
+
+        /**
+         * The watch next type for NEW.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+
+        /**
+         * The aspect ratio for 16:9.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        public static final String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+
+        /**
+         * The aspect ratio for 3:2.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        public static final String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+
+        /**
+         * The aspect ratio for 1:1.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        public static final String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+
+        /**
+         * The aspect ratio for 2:3.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        public static final String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+
+        /**
+         * The availability for "available to this user".
+         *
+         * @see #COLUMN_AVAILABILITY
+         */
+        public static final String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+
+        /**
+         * The availability for "free with subscription".
+         *
+         * @see #COLUMN_AVAILABILITY
+         */
+        public static final String AVAILABILITY_FREE_WITH_SUBSCRIPTION =
+                "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+
+        /**
+         * The availability for "paid content, either to-own or rental
+         * (user has not purchased/rented).
+         *
+         * @see #COLUMN_AVAILABILITY
+         */
+        public static final String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+
+        /**
+         * The interaction type for "listens".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
+
+        /**
+         * The interaction type for "followers".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
+
+        /**
+         * The interaction type for "fans".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
+
+        /**
+         * The interaction type for "likes".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
+
+        /**
+         * The interaction type for "thumbs".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
+
+        /**
+         * The interaction type for "views".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
+
+        /**
+         * The interaction type for "viewers".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+
+        /**
+         * The review rating style for five star rating.
+         *
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        public static final String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
+
+        /**
+         * The review rating style for thumbs-up and thumbs-down rating.
+         *
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        public static final String REVIEW_RATING_STYLE_THUMBS_UP_DOWN =
+                "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+
+        /**
+         * The review rating style for 0 to 100 point system.
+         *
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        public static final String REVIEW_RATING_STYLE_PERCENTAGE =
+                "REVIEW_RATING_STYLE_PERCENTAGE";
+
+        /**
+         * The ID of the TV channel that provides this TV program.
+         *
+         * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_CHANNEL_ID = "channel_id";
+
+        /**
+         * The type of this program content.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #TYPE_MOVIE},
+         * {@link #TYPE_TV_SERIES},
+         * {@link #TYPE_TV_SEASON},
+         * {@link #TYPE_TV_EPISODE},
+         * {@link #TYPE_CLIP},
+         * {@link #TYPE_EVENT},
+         * {@link #TYPE_CHANNEL},
+         * {@link #TYPE_TRACK},
+         * {@link #TYPE_ALBUM},
+         * {@link #TYPE_ARTIST},
+         * {@link #TYPE_PLAYLIST}, and
+         * {@link #TYPE_STATION}.
+         *
+         * <p>This is a required field if the program is from a {@link Channels#TYPE_PREVIEW}
+         * channel.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_TYPE = "type";
+
+        /**
+         * The "watch next" type of this program content.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #WATCH_NEXT_TYPE_CONTINUE},
+         * {@link #WATCH_NEXT_TYPE_NEXT}, and
+         * {@link #WATCH_NEXT_TYPE_NEW}.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+
+        /**
+         * The title of this TV program.
+         *
+         * <p>If this program is an episodic TV show, it is recommended that the title is the series
+         * title and its related fields ({@link #COLUMN_SEASON_TITLE} and/or
+         * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, {@link #COLUMN_SEASON_DISPLAY_NUMBER},
+         * {@link #COLUMN_EPISODE_DISPLAY_NUMBER}, and {@link #COLUMN_EPISODE_TITLE}) are filled in.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_TITLE = "title";
+
+        /**
+         * The season number of this TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         *
+         * @deprecated Use {@link #COLUMN_SEASON_DISPLAY_NUMBER} instead.
+         */
+        @Deprecated
+        public static final String COLUMN_SEASON_NUMBER = "season_number";
+
+        /**
+         * The season display number of this TV program for episodic TV shows.
+         *
+         * <p>This is used to indicate the season number. (e.g. 1, 2 or 3) Note that the value
+         * does not necessarily be numeric. (e.g. 12B)
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+
+        /**
+         * The title of the season for this TV program for episodic TV shows.
+         *
+         * <p>This is an optional field supplied only when the season has a special title
+         * (e.g. The Final Season). If provided, the applications should display it instead of
+         * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, and should display it without alterations.
+         * (e.g. for "The Final Season", displayed string should be "The Final Season", not
+         * "Season The Final Season"). When displaying multiple programs, the order should be based
+         * on {@link #COLUMN_SEASON_DISPLAY_NUMBER}, even when {@link #COLUMN_SEASON_TITLE} exists.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_SEASON_TITLE = "season_title";
+
+        /**
+         * The episode number of this TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         *
+         * @deprecated Use {@link #COLUMN_EPISODE_DISPLAY_NUMBER} instead.
+         */
+        @Deprecated
+        public static final String COLUMN_EPISODE_NUMBER = "episode_number";
+
+        /**
+         * The episode display number of this TV program for episodic TV shows.
+         *
+         * <p>This is used to indicate the episode number. (e.g. 1, 2 or 3) Note that the value
+         * does not necessarily be numeric. (e.g. 12B)
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
+
+        /**
+         * The episode title of this TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_EPISODE_TITLE = "episode_title";
+
+        /**
+         * The start time of this TV program, in milliseconds since the epoch.
+         *
+         * <p>The value should be equal to or larger than {@link #COLUMN_END_TIME_UTC_MILLIS} of the
+         * previous program in the same channel. In practice, start time will usually be the end
+         * time of the previous program.
+         *
+         * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+
+        /**
+         * The end time of this TV program, in milliseconds since the epoch.
+         *
+         * <p>The value should be equal to or less than {@link #COLUMN_START_TIME_UTC_MILLIS} of the
+         * next program in the same channel. In practice, end time will usually be the start time of
+         * the next program.
+         *
+         * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+
+        /**
+         * The comma-separated genre string of this TV program.
+         *
+         * <p>Use the same language appeared in the underlying broadcast standard, if applicable.
+         * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or
+         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use
+         * {@link Genres#encode} to create a text that can be stored in this column. Use
+         * {@link Genres#decode} to get the broadcast genre strings from the text stored in the
+         * column.
+         *
+         * <p>Type: TEXT
+         * @see Genres#encode
+         * @see Genres#decode
+         */
+        public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+
+        /**
+         * The comma-separated canonical genre string of this TV program.
+         *
+         * <p>Canonical genres are defined in {@link Genres}. Use {@link Genres#encode} to create a
+         * text that can be stored in this column. Use {@link Genres#decode} to get the canonical
+         * genre strings from the text stored in the column.
+         *
+         * <p>Type: TEXT
+         * @see Genres
+         * @see Genres#encode
+         * @see Genres#decode
+         */
+        public static final String COLUMN_CANONICAL_GENRE = "canonical_genre";
+
+        /**
+         * The short description of this TV program that is displayed to the user by default.
+         *
+         * <p>It is recommended to limit the length of the descriptions to 256 characters.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_SHORT_DESCRIPTION = "short_description";
+
+        /**
+         * The detailed, lengthy description of this TV program that is displayed only when the user
+         * wants to see more information.
+         *
+         * <p>TV input services should leave this field empty if they have no additional details
+         * beyond {@link #COLUMN_SHORT_DESCRIPTION}.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_LONG_DESCRIPTION = "long_description";
+
+        /**
+         * The width of the video for this TV program, in the unit of pixels.
+         *
+         * <p>Together with {@link #COLUMN_VIDEO_HEIGHT} this is used to determine the video
+         * resolution of the current TV program. Can be empty if it is not known initially or the
+         * program does not convey any video such as the programs from type
+         * {@link Channels#SERVICE_TYPE_AUDIO} channels.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_VIDEO_WIDTH = "video_width";
+
+        /**
+         * The height of the video for this TV program, in the unit of pixels.
+         *
+         * <p>Together with {@link #COLUMN_VIDEO_WIDTH} this is used to determine the video
+         * resolution of the current TV program. Can be empty if it is not known initially or the
+         * program does not convey any video such as the programs from type
+         * {@link Channels#SERVICE_TYPE_AUDIO} channels.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_VIDEO_HEIGHT = "video_height";
+
+        /**
+         * The comma-separated audio languages of this TV program.
+         *
+         * <p>This is used to describe available audio languages included in the program. Use either
+         * ISO 639-1 or 639-2/T codes.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_AUDIO_LANGUAGE = "audio_language";
+
+        /**
+         * The comma-separated content ratings of this TV program.
+         *
+         * <p>This is used to describe the content rating(s) of this program. Each comma-separated
+         * content rating sub-string should be generated by calling
+         * {@link TvContentRating#flattenToString}. Note that in most cases the program content is
+         * rated by a single rating system, thus resulting in a corresponding single sub-string that
+         * does not require comma separation and multiple sub-strings appear only when the program
+         * content is rated by two or more content rating systems. If any of those ratings is
+         * specified as "blocked rating" in the user's parental control settings, the TV input
+         * service should block the current content and wait for the signal that it is okay to
+         * unblock.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_CONTENT_RATING = "content_rating";
+
+        /**
+         * The URI for the poster art of this TV program.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_POSTER_ART_URI = "poster_art_uri";
+
+        /**
+         * The aspect ratio of the poster art for this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #ASPECT_RATIO_16_9},
+         * {@link #ASPECT_RATIO_3_2},
+         * {@link #ASPECT_RATIO_1_1}, and
+         * {@link #ASPECT_RATIO_2_3}.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+
+        /**
+         * The URI for the thumbnail of this TV program.
+         *
+         * <p>The system can generate a thumbnail from the poster art if this column is not
+         * specified. Thus it is not necessary for TV input services to include a thumbnail if it is
+         * just a scaled image of the poster art.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+
+        /**
+         * The aspect ratio of the thumbnail for this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #ASPECT_RATIO_16_9},
+         * {@link #ASPECT_RATIO_3_2},
+         * {@link #ASPECT_RATIO_1_1}, and
+         * {@link #ASPECT_RATIO_2_3}.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+
+        /**
+         * The URI for the logo of this TV program.
+         *
+         * <p>This is a small badge shown on top of the poster art or thumbnail representing the
+         * source of the content.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_LOGO_URI = "logo_uri";
+
+        /**
+         * The availability of this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #AVAILABILITY_AVAILABLE},
+         * {@link #AVAILABILITY_FREE_WITH_SUBSCRIPTION}, and
+         * {@link #AVAILABILITY_PAID_CONTENT}.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_AVAILABILITY = "availability";
+
+        /**
+         * The starting price of this TV program.
+         *
+         * <p>This indicates the lowest regular acquisition cost of the content. It is only used
+         * if the availability of the program is {@link #AVAILABILITY_PAID_CONTENT}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_OFFER_PRICE
+         */
+        public static final String COLUMN_STARTING_PRICE = "starting_price";
+
+        /**
+         * The offer price of this TV program.
+         *
+         * <p>This is the promotional cost of the content. It is only used if the availability of
+         * the program is {@link #AVAILABILITY_PAID_CONTENT}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_STARTING_PRICE
+         */
+        public static final String COLUMN_OFFER_PRICE = "offer_price";
+
+        /**
+         * The release date of this TV program.
+         *
+         * <p>The value should be in the form of either "yyyy-MM-dd" or "yyyy".
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_RELEASE_DATE = "release_date";
+
+        /**
+         * The count of the items included in this TV program.
+         *
+         * <p>This is only relevant if the program represents a collection of items such as series,
+         * episodes, or music tracks.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_ITEM_COUNT = "item_count";
+
+        /**
+         * The flag indicating whether this TV program is live or not.
+         *
+         * <p>A value of 1 indicates that the content is airing and should be consumed now, a value
+         * of 0 indicates that the content is off the air and does not need to be consumed at the
+         * present time. If not specified, the value is set to 0 (not live) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_LIVE = "live";
+
+        /**
+         * The flag indicating whether this TV program is searchable or not.
+         *
+         * <p>The columns of searchable programs can be read by other applications that have proper
+         * permission. Care must be taken not to open sensitive data.
+         *
+         * <p>A value of 1 indicates that the program is searchable and its columns can be read by
+         * other applications, a value of 0 indicates that the program is hidden and its columns can
+         * be read only by the package that owns the program and the system. If not specified, this
+         * value is set to 1 (searchable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_SEARCHABLE = "searchable";
+
+        /**
+         * The flag indicating whether recording of this program is prohibited.
+         *
+         * <p>A value of 1 indicates that recording of this program is prohibited and application
+         * will not schedule any recording for this program. A value of 0 indicates that the
+         * recording is not prohibited. If not specified, this value is set to 0 (not prohibited) by
+         * default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+
+        /**
+         * Internal data used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: BLOB
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+
+        /**
+         * The version number of this row entry used by TV input services.
+         *
+         * <p>This is best used by sync adapters to identify the rows to update. The number can be
+         * defined by individual TV input services. One may assign the same value as
+         * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV
+         * broadcast.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_VERSION_NUMBER = "version_number";
+
+        /**
+         * The internal ID used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+
+        /**
+         * The URI for the preview video.
+         *
+         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}. The data in the column must be
+         * a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+
+        /**
+         * The last playback position (in milliseconds) of the preview video.
+         *
+         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
+                "last_playback_position_millis";
+
+        /**
+         * The duration (in milliseconds) of the preview video.
+         *
+         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_DURATION_MILLIS = "duration_millis";
+
+        /**
+         * The intent URI which is launched when the preview video is selected.
+         *
+         * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME}
+         * and converted back to the original intent with {@link Intent#parseUri}. The intent is
+         * launched when the user selects the preview video item.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+
+        /**
+         * The weight of the preview program within the channel.
+         *
+         * <p>The UI may choose to show this item in a different position in the channel row.
+         * A larger weight value means the program is more important than other programs having
+         * smaller weight values. The value is relevant for the preview programs in the same
+         * channel. This is only relevant to {@link Channels#TYPE_PREVIEW}.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_WEIGHT = "weight";
+
+        /**
+         * The flag indicating whether this program is transient or not.
+         *
+         * <p>A value of 1 indicates that the channel will be automatically removed by the system on
+         * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not
+         * specified, this value is set to 0 (not transient) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @see Channels#COLUMN_TRANSIENT
+         * @hide
+         */
+        @RestrictTo(LIBRARY_GROUP)
+        public static final String COLUMN_TRANSIENT = "transient";
+
+        /**
+         * The type of interaction for this TV program.
+         *
+         * <p> The value should match one of the followings:
+         * {@link #INTERACTION_TYPE_LISTENS},
+         * {@link #INTERACTION_TYPE_FOLLOWERS},
+         * {@link #INTERACTION_TYPE_FANS},
+         * {@link #INTERACTION_TYPE_LIKES},
+         * {@link #INTERACTION_TYPE_THUMBS},
+         * {@link #INTERACTION_TYPE_VIEWS}, and
+         * {@link #INTERACTION_TYPE_VIEWERS}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_INTERACTION_COUNT
+         */
+        public static final String COLUMN_INTERACTION_TYPE = "interaction_type";
+
+        /**
+         * The interaction count for this program.
+         *
+         * <p>This indicates the number of times interaction has happened.
+         *
+         * <p>Type: INTEGER
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String COLUMN_INTERACTION_COUNT = "interaction_count";
+
+        /**
+         * The author or artist of this content.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_AUTHOR = "author";
+
+        /**
+         * The review rating score style used for {@link #COLUMN_REVIEW_RATING}.
+         *
+         * <p> The value should match one of the followings: {@link #REVIEW_RATING_STYLE_STARS},
+         * {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, and {@link #REVIEW_RATING_STYLE_PERCENTAGE}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_REVIEW_RATING
+         */
+        public static final String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+
+        /**
+         * The review rating score for this program.
+         *
+         * <p>The format of the value is dependent on {@link #COLUMN_REVIEW_RATING_STYLE}. If the
+         * style is {@link #REVIEW_RATING_STYLE_STARS}, the value should be a real number between
+         * 0.0 and 5.0. (e.g. "4.5") If the style is {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN},
+         * the value should be two integers, one for thumbs-up count and the other for thumbs-down
+         * count, with a comma between them. (e.g. "200,40") If the style is
+         * {@link #REVIEW_RATING_STYLE_PERCENTAGE}, the value shoule be a real number between 0 and
+         * 100. (e.g. "99.9")
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        public static final String COLUMN_REVIEW_RATING = "review_rating";
+
+        private Programs() {}
+
+        /** Canonical genres for TV programs. */
+        public static final class Genres {
+            /** The genre for Family/Kids. */
+            public static final String FAMILY_KIDS = "FAMILY_KIDS";
+
+            /** The genre for Sports. */
+            public static final String SPORTS = "SPORTS";
+
+            /** The genre for Shopping. */
+            public static final String SHOPPING = "SHOPPING";
+
+            /** The genre for Movies. */
+            public static final String MOVIES = "MOVIES";
+
+            /** The genre for Comedy. */
+            public static final String COMEDY = "COMEDY";
+
+            /** The genre for Travel. */
+            public static final String TRAVEL = "TRAVEL";
+
+            /** The genre for Drama. */
+            public static final String DRAMA = "DRAMA";
+
+            /** The genre for Education. */
+            public static final String EDUCATION = "EDUCATION";
+
+            /** The genre for Animal/Wildlife. */
+            public static final String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE";
+
+            /** The genre for News. */
+            public static final String NEWS = "NEWS";
+
+            /** The genre for Gaming. */
+            public static final String GAMING = "GAMING";
+
+            /** The genre for Arts. */
+            public static final String ARTS = "ARTS";
+
+            /** The genre for Entertainment. */
+            public static final String ENTERTAINMENT = "ENTERTAINMENT";
+
+            /** The genre for Life Style. */
+            public static final String LIFE_STYLE = "LIFE_STYLE";
+
+            /** The genre for Music. */
+            public static final String MUSIC = "MUSIC";
+
+            /** The genre for Premier. */
+            public static final String PREMIER = "PREMIER";
+
+            /** The genre for Tech/Science. */
+            public static final String TECH_SCIENCE = "TECH_SCIENCE";
+
+            private static final HashSet<String> CANONICAL_GENRES = new HashSet<>();
+            static {
+                CANONICAL_GENRES.add(FAMILY_KIDS);
+                CANONICAL_GENRES.add(SPORTS);
+                CANONICAL_GENRES.add(SHOPPING);
+                CANONICAL_GENRES.add(MOVIES);
+                CANONICAL_GENRES.add(COMEDY);
+                CANONICAL_GENRES.add(TRAVEL);
+                CANONICAL_GENRES.add(DRAMA);
+                CANONICAL_GENRES.add(EDUCATION);
+                CANONICAL_GENRES.add(ANIMAL_WILDLIFE);
+                CANONICAL_GENRES.add(NEWS);
+                CANONICAL_GENRES.add(GAMING);
+                CANONICAL_GENRES.add(ARTS);
+                CANONICAL_GENRES.add(ENTERTAINMENT);
+                CANONICAL_GENRES.add(LIFE_STYLE);
+                CANONICAL_GENRES.add(MUSIC);
+                CANONICAL_GENRES.add(PREMIER);
+                CANONICAL_GENRES.add(TECH_SCIENCE);
+            }
+
+            private static final char DOUBLE_QUOTE = '"';
+            private static final char COMMA = ',';
+            private static final String DELIMITER = ",";
+
+            private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+            private Genres() {}
+
+            /**
+             * Encodes genre strings to a text that can be put into the database.
+             *
+             * @param genres Genre strings.
+             * @return an encoded genre string that can be inserted into the
+             *         {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
+             */
+            public static String encode(@NonNull String... genres) {
+                if (genres == null) {
+                    // MNC and before will throw a NPE.
+                    return null;
+                }
+                StringBuilder sb = new StringBuilder();
+                String separator = "";
+                for (String genre : genres) {
+                    sb.append(separator).append(encodeToCsv(genre));
+                    separator = DELIMITER;
+                }
+                return sb.toString();
+            }
+
+            private static String encodeToCsv(String genre) {
+                StringBuilder sb = new StringBuilder();
+                int length = genre.length();
+                for (int i = 0; i < length; ++i) {
+                    char c = genre.charAt(i);
+                    switch (c) {
+                        case DOUBLE_QUOTE:
+                            sb.append(DOUBLE_QUOTE);
+                            break;
+                        case COMMA:
+                            sb.append(DOUBLE_QUOTE);
+                            break;
+                    }
+                    sb.append(c);
+                }
+                return sb.toString();
+            }
+
+            /**
+             * Decodes the genre strings from the text stored in the database.
+             *
+             * @param genres The encoded genre string retrieved from the
+             *            {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
+             * @return genre strings.
+             */
+            public static String[] decode(@NonNull String genres) {
+                if (TextUtils.isEmpty(genres)) {
+                    // MNC and before will throw a NPE for {@code null} genres.
+                    return EMPTY_STRING_ARRAY;
+                }
+                if (genres.indexOf(COMMA) == -1 && genres.indexOf(DOUBLE_QUOTE) == -1) {
+                    return new String[] {genres.trim()};
+                }
+                StringBuilder sb = new StringBuilder();
+                List<String> results = new ArrayList<>();
+                int length = genres.length();
+                boolean escape = false;
+                for (int i = 0; i < length; ++i) {
+                    char c = genres.charAt(i);
+                    switch (c) {
+                        case DOUBLE_QUOTE:
+                            if (!escape) {
+                                escape = true;
+                                continue;
+                            }
+                            break;
+                        case COMMA:
+                            if (!escape) {
+                                String string = sb.toString().trim();
+                                if (string.length() > 0) {
+                                    results.add(string);
+                                }
+                                sb = new StringBuilder();
+                                continue;
+                            }
+                            break;
+                    }
+                    sb.append(c);
+                    escape = false;
+                }
+                String string = sb.toString().trim();
+                if (string.length() > 0) {
+                    results.add(string);
+                }
+                return results.toArray(new String[results.size()]);
+            }
+
+            /**
+             * Returns whether a given text is a canonical genre defined in {@link Genres}.
+             *
+             * @param genre The name of genre to be checked.
+             * @return {@code true} if the genre is canonical, otherwise {@code false}.
+             */
+            public static boolean isCanonical(String genre) {
+                return CANONICAL_GENRES.contains(genre);
+            }
+        }
+    }
+
+    /**
+     * Column definitions for the recorded TV programs table.
+     *
+     * <p>By default, the query results will be sorted by {@link #COLUMN_START_TIME_UTC_MILLIS} in
+     * ascending order.
+     */
+    public static final class RecordedPrograms implements BaseTvColumns {
+
+        /** The content:// style URI for this table. */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_RECORDED_PROGRAM);
+
+        /** The MIME type of a directory of recorded TV programs. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
+
+        /** The MIME type of a single recorded TV program. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
+
+        /**
+         * The ID of the TV input service that is associated with this recorded program.
+         *
+         * <p>Use {@link #buildInputId} to build the ID.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INPUT_ID = "input_id";
+
+        /**
+         * The ID of the TV channel that provided this recorded TV program.
+         *
+         * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
+         * @see Programs#COLUMN_CHANNEL_ID
+         */
+        public static final String COLUMN_CHANNEL_ID = Programs.COLUMN_CHANNEL_ID;
+
+        /**
+         * The title of this recorded TV program.
+         *
+         * <p>If this recorded program is an episodic TV show, it is recommended that the title is
+         * the series title and its related fields ({@link #COLUMN_SEASON_TITLE} and/or
+         * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, {@link #COLUMN_EPISODE_DISPLAY_NUMBER},
+         * and {@link #COLUMN_EPISODE_TITLE}) are filled in.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_TITLE
+         */
+        public static final String COLUMN_TITLE = Programs.COLUMN_TITLE;
+
+        /**
+         * The season display number of this recorded TV program for episodic TV shows.
+         *
+         * <p>This is used to indicate the season number. (e.g. 1, 2 or 3) Note that the value
+         * does not necessarily be numeric. (e.g. 12B)
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_SEASON_DISPLAY_NUMBER =
+                Programs.COLUMN_SEASON_DISPLAY_NUMBER;
+
+        /**
+         * The title of the season for this recorded TV program for episodic TV shows.
+         *
+         * <p>This is an optional field supplied only when the season has a special title
+         * (e.g. The Final Season). If provided, the applications should display it instead of
+         * {@link #COLUMN_SEASON_DISPLAY_NUMBER} without alterations.
+         * (e.g. for "The Final Season", displayed string should be "The Final Season", not
+         * "Season The Final Season"). When displaying multiple programs, the order should be based
+         * on {@link #COLUMN_SEASON_DISPLAY_NUMBER}, even when {@link #COLUMN_SEASON_TITLE} exists.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_SEASON_TITLE = Programs.COLUMN_SEASON_TITLE;
+
+        /**
+         * The episode display number of this recorded TV program for episodic TV shows.
+         *
+         * <p>This is used to indicate the episode number. (e.g. 1, 2 or 3) Note that the value
+         * does not necessarily be numeric. (e.g. 12B)
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_EPISODE_DISPLAY_NUMBER =
+                Programs.COLUMN_EPISODE_DISPLAY_NUMBER;
+
+        /**
+         * The episode title of this recorded TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_EPISODE_TITLE
+         */
+        public static final String COLUMN_EPISODE_TITLE = Programs.COLUMN_EPISODE_TITLE;
+
+        /**
+         * The start time of the original TV program, in milliseconds since the epoch.
+         *
+         * <p>Type: INTEGER (long)
+         * @see Programs#COLUMN_START_TIME_UTC_MILLIS
+         */
+        public static final String COLUMN_START_TIME_UTC_MILLIS =
+                Programs.COLUMN_START_TIME_UTC_MILLIS;
+
+        /**
+         * The end time of the original TV program, in milliseconds since the epoch.
+         *
+         * <p>Type: INTEGER (long)
+         * @see Programs#COLUMN_END_TIME_UTC_MILLIS
+         */
+        public static final String COLUMN_END_TIME_UTC_MILLIS = Programs.COLUMN_END_TIME_UTC_MILLIS;
+
+        /**
+         * The comma-separated genre string of this recorded TV program.
+         *
+         * <p>Use the same language appeared in the underlying broadcast standard, if applicable.
+         * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or
+         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use
+         * {@link Programs.Genres#encode Genres.encode()} to create a text that can be stored in
+         * this column. Use {@link Programs.Genres#decode Genres.decode()} to get the broadcast
+         * genre strings from the text stored in the column.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_BROADCAST_GENRE
+         */
+        public static final String COLUMN_BROADCAST_GENRE = Programs.COLUMN_BROADCAST_GENRE;
+
+        /**
+         * The comma-separated canonical genre string of this recorded TV program.
+         *
+         * <p>Canonical genres are defined in {@link Programs.Genres}. Use
+         * {@link Programs.Genres#encode Genres.encode()} to create a text that can be stored in
+         * this column. Use {@link Programs.Genres#decode Genres.decode()} to get the canonical
+         * genre strings from the text stored in the column.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_CANONICAL_GENRE
+         * @see Programs.Genres
+         */
+        public static final String COLUMN_CANONICAL_GENRE = Programs.COLUMN_CANONICAL_GENRE;
+
+        /**
+         * The short description of this recorded TV program that is displayed to the user by
+         * default.
+         *
+         * <p>It is recommended to limit the length of the descriptions to 256 characters.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_SHORT_DESCRIPTION
+         */
+        public static final String COLUMN_SHORT_DESCRIPTION = Programs.COLUMN_SHORT_DESCRIPTION;
+
+        /**
+         * The detailed, lengthy description of this recorded TV program that is displayed only when
+         * the user wants to see more information.
+         *
+         * <p>TV input services should leave this field empty if they have no additional details
+         * beyond {@link #COLUMN_SHORT_DESCRIPTION}.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_LONG_DESCRIPTION
+         */
+        public static final String COLUMN_LONG_DESCRIPTION = Programs.COLUMN_LONG_DESCRIPTION;
+
+        /**
+         * The width of the video for this recorded TV program, in the unit of pixels.
+         *
+         * <p>Together with {@link #COLUMN_VIDEO_HEIGHT} this is used to determine the video
+         * resolution of the current recorded TV program. Can be empty if it is not known or the
+         * recorded program does not convey any video.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_VIDEO_WIDTH
+         */
+        public static final String COLUMN_VIDEO_WIDTH = Programs.COLUMN_VIDEO_WIDTH;
+
+        /**
+         * The height of the video for this recorded TV program, in the unit of pixels.
+         *
+         * <p>Together with {@link #COLUMN_VIDEO_WIDTH} this is used to determine the video
+         * resolution of the current recorded TV program. Can be empty if it is not known or the
+         * recorded program does not convey any video.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_VIDEO_HEIGHT
+         */
+        public static final String COLUMN_VIDEO_HEIGHT = Programs.COLUMN_VIDEO_HEIGHT;
+
+        /**
+         * The comma-separated audio languages of this recorded TV program.
+         *
+         * <p>This is used to describe available audio languages included in the recorded program.
+         * Use either ISO 639-1 or 639-2/T codes.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_AUDIO_LANGUAGE
+         */
+        public static final String COLUMN_AUDIO_LANGUAGE = Programs.COLUMN_AUDIO_LANGUAGE;
+
+        /**
+         * The comma-separated content ratings of this recorded TV program.
+         *
+         * <p>This is used to describe the content rating(s) of this recorded program. Each
+         * comma-separated content rating sub-string should be generated by calling
+         * {@link TvContentRating#flattenToString}. Note that in most cases the recorded program
+         * content is rated by a single rating system, thus resulting in a corresponding single
+         * sub-string that does not require comma separation and multiple sub-strings appear only
+         * when the recorded program content is rated by two or more content rating systems. If any
+         * of those ratings is specified as "blocked rating" in the user's parental control
+         * settings, the TV input service should block the current content and wait for the signal
+         * that it is okay to unblock.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_CONTENT_RATING
+         */
+        public static final String COLUMN_CONTENT_RATING = Programs.COLUMN_CONTENT_RATING;
+
+        /**
+         * The URI for the poster art of this recorded TV program.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_POSTER_ART_URI
+         */
+        public static final String COLUMN_POSTER_ART_URI = Programs.COLUMN_POSTER_ART_URI;
+
+        /**
+         * The URI for the thumbnail of this recorded TV program.
+         *
+         * <p>The system can generate a thumbnail from the poster art if this column is not
+         * specified. Thus it is not necessary for TV input services to include a thumbnail if it is
+         * just a scaled image of the poster art.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_THUMBNAIL_URI
+         */
+        public static final String COLUMN_THUMBNAIL_URI = Programs.COLUMN_THUMBNAIL_URI;
+
+        /**
+         * The flag indicating whether this recorded TV program is searchable or not.
+         *
+         * <p>The columns of searchable recorded programs can be read by other applications that
+         * have proper permission. Care must be taken not to open sensitive data.
+         *
+         * <p>A value of 1 indicates that the recorded program is searchable and its columns can be
+         * read by other applications, a value of 0 indicates that the recorded program is hidden
+         * and its columns can be read only by the package that owns the recorded program and the
+         * system. If not specified, this value is set to 1 (searchable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @see Programs#COLUMN_SEARCHABLE
+         */
+        public static final String COLUMN_SEARCHABLE = Programs.COLUMN_SEARCHABLE;
+
+        /**
+         * The URI of the recording data for this recorded program.
+         *
+         * <p>Together with {@link #COLUMN_RECORDING_DATA_BYTES}, applications can use this
+         * information to manage recording storage. The URI should indicate a file or directory with
+         * the scheme {@link android.content.ContentResolver#SCHEME_FILE}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_RECORDING_DATA_BYTES
+         */
+        public static final String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
+
+        /**
+         * The data size (in bytes) for this recorded program.
+         *
+         * <p>Together with {@link #COLUMN_RECORDING_DATA_URI}, applications can use this
+         * information to manage recording storage.
+         *
+         * <p>Type: INTEGER (long)
+         * @see #COLUMN_RECORDING_DATA_URI
+         */
+        public static final String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
+
+        /**
+         * The duration (in milliseconds) of this recorded program.
+         *
+         * <p>The actual duration of the recorded program can differ from the one calculated by
+         * {@link #COLUMN_END_TIME_UTC_MILLIS} - {@link #COLUMN_START_TIME_UTC_MILLIS} as program
+         * recording can be interrupted in the middle for some reason, resulting in a partially
+         * recorded program, which is still playable.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
+
+        /**
+         * The expiration time for this recorded program, in milliseconds since the epoch.
+         *
+         * <p>Recorded TV programs do not expire by default unless explicitly requested by the user
+         * or the user allows applications to delete them in order to free up disk space for future
+         * recording. However, some TV content can have expiration date set by the content provider
+         * when recorded. This field is used to indicate such a restriction.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS =
+                "recording_expire_time_utc_millis";
+
+
+        /**
+         * Internal data used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: BLOB
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_DATA
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_DATA =
+                Programs.COLUMN_INTERNAL_PROVIDER_DATA;
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG1
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 =
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG1;
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG2
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 =
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG2;
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG3
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 =
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG3;
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG4
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 =
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG4;
+
+        /**
+         * The version number of this row entry used by TV input services.
+         *
+         * <p>This is best used by sync adapters to identify the rows to update. The number can be
+         * defined by individual TV input services. One may assign the same value as
+         * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV
+         * broadcast.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_VERSION_NUMBER
+         */
+        public static final String COLUMN_VERSION_NUMBER = Programs.COLUMN_VERSION_NUMBER;
+
+        private RecordedPrograms() {}
+    }
+}
diff --git a/tv-provider/src/android/support/media/tv/TvContractUtils.java b/tv-provider/src/android/support/media/tv/TvContractUtils.java
new file mode 100644
index 0000000..2638e34
--- /dev/null
+++ b/tv-provider/src/android/support/media/tv/TvContractUtils.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.tv;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.media.tv.TvContentRating;
+import android.support.annotation.RestrictTo;
+import android.text.TextUtils;
+
+/**
+ * Static helper methods for working with {@link android.media.tv.TvContract}.
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+public class TvContractUtils {
+
+    private static final String TAG = "TvContractUtils";
+    private static final boolean DEBUG = false;
+    private static final String DELIMITER = ",";
+
+    /**
+     * Parses a string of comma-separated ratings into an array of {@link TvContentRating}.
+     *
+     * @param commaSeparatedRatings String containing various ratings, separated by commas.
+     * @return An array of TvContentRatings.
+     */
+    public static TvContentRating[] stringToContentRatings(String commaSeparatedRatings) {
+        if (TextUtils.isEmpty(commaSeparatedRatings)) {
+            return null;
+        }
+        String[] ratings = commaSeparatedRatings.split("\\s*,\\s*");
+        TvContentRating[] contentRatings = new TvContentRating[ratings.length];
+        for (int i = 0; i < contentRatings.length; ++i) {
+            contentRatings[i] = TvContentRating.unflattenFromString(ratings[i]);
+        }
+        return contentRatings;
+    }
+
+    /**
+     * Flattens an array of {@link TvContentRating} into a String to be inserted into a database.
+     *
+     * @param contentRatings An array of TvContentRatings.
+     * @return A comma-separated String of ratings.
+     */
+    public static String contentRatingsToString(TvContentRating[] contentRatings) {
+        if (contentRatings == null || contentRatings.length == 0) {
+            return null;
+        }
+        StringBuilder ratings = new StringBuilder(contentRatings[0].flattenToString());
+        for (int i = 1; i < contentRatings.length; ++i) {
+            ratings.append(DELIMITER);
+            ratings.append(contentRatings[i].flattenToString());
+        }
+        return ratings.toString();
+    }
+
+    /**
+     * Parses a string of comma-separated audio languages into an array of audio language strings.
+     *
+     * @param commaSeparatedString String containing audio languages, separated by commas.
+     * @return An array of audio language.
+     */
+    public static String[] stringToAudioLanguages(String commaSeparatedString) {
+        if (TextUtils.isEmpty(commaSeparatedString)) {
+            return null;
+        }
+        return commaSeparatedString.split("\\s*,\\s*");
+    }
+
+    /**
+     * Concatenate an array of audio languages into a String to be inserted into a database.
+     *
+     * @param audioLanguages An array of audio languages.
+     * @return A comma-separated String of audio languages.
+     */
+    public static String audioLanguagesToString(String[] audioLanguages) {
+        if (audioLanguages == null || audioLanguages.length == 0) {
+            return null;
+        }
+        StringBuilder ratings = new StringBuilder(audioLanguages[0]);
+        for (int i = 1; i < audioLanguages.length; ++i) {
+            ratings.append(DELIMITER);
+            ratings.append(audioLanguages[i]);
+        }
+        return ratings.toString();
+    }
+
+    private TvContractUtils() {
+    }
+}
diff --git a/tv-provider/tests/AndroidManifest.xml b/tv-provider/tests/AndroidManifest.xml
new file mode 100644
index 0000000..58257a7
--- /dev/null
+++ b/tv-provider/tests/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+   Copyright (C) 2016 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:tools="http://schemas.android.com/tools"
+          package="android.support.media.tv.test">
+
+    <uses-sdk
+            android:minSdkVersion="21"
+            android:targetSdkVersion="24"
+            tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
+                      android.support.test.espresso, android.support.test.espresso.idling"/>
+
+    <application>
+        <uses-library android:name="android.test.runner"/>
+    </application>
+
+    <instrumentation
+            android:name="android.test.InstrumentationTestRunner"
+            android:targetPackage="android.support.media.tv.test"/>
+
+</manifest>
diff --git a/v8/Android.mk b/tv-provider/tests/NO_DOCS
similarity index 69%
copy from v8/Android.mk
copy to tv-provider/tests/NO_DOCS
index 14ff0aa..092a39c 100644
--- a/v8/Android.mk
+++ b/tv-provider/tests/NO_DOCS
@@ -1,4 +1,4 @@
-# Copyright (C) 2014 The Android Open Source Project
+# Copyright (C) 2016 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.
@@ -12,5 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH:= $(call my-dir)
-include $(call all-makefiles-under,$(LOCAL_PATH))
+Having this file, named NO_DOCS, in a directory will prevent
+Android javadocs from being generated for java files under
+the directory. This is especially useful for test projects.
diff --git a/tv-provider/tests/src/android/support/media/tv/ChannelTest.java b/tv-provider/tests/src/android/support/media/tv/ChannelTest.java
new file mode 100644
index 0000000..514f6d2
--- /dev/null
+++ b/tv-provider/tests/src/android/support/media/tv/ChannelTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.tv;
+
+import android.content.ContentValues;
+import android.content.Intent;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+/**
+ * Tests that channels can be created using the Builder pattern and correctly obtain
+ * values from them
+ */
+@RequiresApi(api = Build.VERSION_CODES.M)
+public class ChannelTest extends TestCase {
+    private static final String KEY_SPLASHSCREEN = "splashscreen";
+    private static final String KEY_PREMIUM_CHANNEL = "premium";
+    private static final String SPLASHSCREEN_URL = "http://example.com/splashscreen.jpg";
+
+    @Test
+    public void testEmptyChannel() {
+        Channel emptyChannel = new Channel.Builder()
+                .build();
+        ContentValues contentValues = emptyChannel.toContentValues();
+        compareChannel(emptyChannel, Channel.fromCursor(getChannelCursor(contentValues)));
+    }
+
+    @Test
+    public void testSampleChannel() {
+        // Tests cloning and database I/O of a channel with some defined and some undefined
+        // values.
+        Channel sampleChannel = new Channel.Builder()
+                .setDisplayName("Google")
+                .setDisplayNumber("3")
+                .setDescription("This is a sample channel")
+                .setOriginalNetworkId(1)
+                .setAppLinkIntentUri(Uri.parse(new Intent(Intent.ACTION_VIEW).toUri(
+                        Intent.URI_INTENT_SCHEME)))
+                .setOriginalNetworkId(0)
+                .build();
+        ContentValues contentValues = sampleChannel.toContentValues();
+        compareChannel(sampleChannel, Channel.fromCursor(getChannelCursor(contentValues)));
+
+        Channel clonedSampleChannel = new Channel.Builder(sampleChannel).build();
+        compareChannel(sampleChannel, clonedSampleChannel);
+    }
+
+    @Test
+    public void testFullyPopulatedChannel() {
+        Channel fullyPopulatedChannel = new Channel.Builder()
+                .setAppLinkColor(0x00FF0000)
+                .setAppLinkIconUri(Uri.parse("http://example.com/icon.png"))
+                .setAppLinkIntent(new Intent())
+                .setAppLinkPosterArtUri(Uri.parse("http://example.com/poster.png"))
+                .setAppLinkText("Open an intent")
+                .setDescription("Channel description")
+                .setDisplayName("Display Name")
+                .setDisplayNumber("100")
+                .setInputId("TestInputService")
+                .setNetworkAffiliation("Network Affiliation")
+                .setOriginalNetworkId(2)
+                .setPackageName("com.example.android.sampletvinput")
+                .setSearchable(false)
+                .setServiceId(3)
+                .setTransportStreamId(4)
+                .setType(TvContractCompat.Channels.TYPE_PREVIEW)
+                .setServiceType(TvContractCompat.Channels.SERVICE_TYPE_AUDIO_VIDEO)
+                .setVideoFormat(TvContractCompat.Channels.VIDEO_FORMAT_240P)
+                .setInternalProviderFlag1(0x4)
+                .setInternalProviderFlag2(0x3)
+                .setInternalProviderFlag3(0x2)
+                .setInternalProviderFlag4(0x1)
+                .build();
+        ContentValues contentValues = fullyPopulatedChannel.toContentValues();
+        compareChannel(fullyPopulatedChannel, Channel.fromCursor(getChannelCursor(contentValues)));
+
+        Channel clonedFullyPopulatedChannel = new Channel.Builder(fullyPopulatedChannel).build();
+        compareChannel(fullyPopulatedChannel, clonedFullyPopulatedChannel);
+    }
+
+    private static void compareChannel(Channel channelA, Channel channelB) {
+        assertEquals(channelA.getAppLinkColor(), channelB.getAppLinkColor());
+        assertEquals(channelA.getAppLinkIconUri(), channelB.getAppLinkIconUri());
+        assertEquals(channelA.getAppLinkIntentUri(), channelB.getAppLinkIntentUri());
+        assertEquals(channelA.getAppLinkPosterArtUri(), channelB.getAppLinkPosterArtUri());
+        assertEquals(channelA.getAppLinkText(), channelB.getAppLinkText());
+        assertEquals(channelA.isSearchable(), channelB.isSearchable());
+        assertEquals(channelA.getDescription(), channelB.getDescription());
+        assertEquals(channelA.getDisplayName(), channelB.getDisplayName());
+        assertEquals(channelA.getDisplayNumber(), channelB.getDisplayNumber());
+        assertEquals(channelA.getId(), channelB.getId());
+        assertEquals(channelA.getInputId(), channelB.getInputId());
+        assertEquals(channelA.getNetworkAffiliation(), channelB.getNetworkAffiliation());
+        assertEquals(channelA.getOriginalNetworkId(), channelB.getOriginalNetworkId());
+        assertEquals(channelA.getPackageName(), channelB.getPackageName());
+        assertEquals(channelA.getServiceId(), channelB.getServiceId());
+        assertEquals(channelA.getServiceType(), channelB.getServiceType());
+        assertEquals(channelA.getTransportStreamId(), channelB.getTransportStreamId());
+        assertEquals(channelA.getType(), channelB.getType());
+        assertEquals(channelA.getVideoFormat(), channelB.getVideoFormat());
+        assertEquals(channelA.toContentValues(), channelB.toContentValues());
+        assertEquals(channelA.toString(), channelB.toString());
+    }
+
+    private static MatrixCursor getChannelCursor(ContentValues contentValues) {
+        String[] rows = Channel.PROJECTION;
+        MatrixCursor cursor = new MatrixCursor(rows);
+        MatrixCursor.RowBuilder builder = cursor.newRow();
+        for (String row: rows) {
+            if (row != null) {
+                builder.add(row, contentValues.get(row));
+            }
+        }
+        cursor.moveToFirst();
+        return cursor;
+    }
+}
diff --git a/tv-provider/tests/src/android/support/media/tv/ProgramTest.java b/tv-provider/tests/src/android/support/media/tv/ProgramTest.java
new file mode 100644
index 0000000..5d894eb
--- /dev/null
+++ b/tv-provider/tests/src/android/support/media/tv/ProgramTest.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.media.tv;
+
+import android.content.ContentValues;
+import android.content.Intent;
+import android.database.MatrixCursor;
+import android.media.tv.TvContentRating;
+import android.net.Uri;
+import android.os.Build;
+import android.support.v4.os.BuildCompat;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * Tests that programs can be created using the Builder pattern and correctly obtain
+ * values from them.
+ */
+public class ProgramTest extends TestCase {
+    @Test
+    public void testEmptyProgram() {
+        Program emptyProgram = new Program.Builder()
+                .build();
+        ContentValues contentValues = emptyProgram.toContentValues();
+        compareProgram(emptyProgram,
+                Program.fromCursor(getProgramCursor(Program.PROJECTION, contentValues)));
+    }
+
+    @Test
+    public void testSampleProgram() {
+        Program sampleProgram = new Program.Builder()
+                .setTitle("Program Title")
+                .setDescription("This is a sample program")
+                .setChannelId(3)
+                .setEpisodeNumber(5)
+                .setSeasonNumber("The Final Season", 7)
+                .setThumbnailUri(Uri.parse("http://www.example.com/programs/poster.png"))
+                .setStartTimeUtcMillis(0)
+                .setEndTimeUtcMillis(1000)
+                .build();
+        ContentValues contentValues = sampleProgram.toContentValues();
+        compareProgram(sampleProgram,
+                Program.fromCursor(getProgramCursor(Program.PROJECTION, contentValues)));
+
+        Program clonedSampleProgram = new Program.Builder(sampleProgram).build();
+        compareProgram(sampleProgram, clonedSampleProgram);
+    }
+
+    @Test
+    public void testFullyPopulatedProgram() {
+        Program fullyPopulatedProgram = new Program.Builder()
+                .setSearchable(false)
+                .setChannelId(3)
+                .setThumbnailUri(Uri.parse("http://example.com/thumbnail.png"))
+                .setAudioLanguages(new String [] {"eng", "kor"})
+                .setBroadcastGenres(new String[] {"Music", "Family"})
+                .setCanonicalGenres(new String[] {TvContractCompat.Programs.Genres.MOVIES})
+                .setContentRatings(new TvContentRating[] {
+                        TvContentRating.createRating("com.android.tv", "US_TV", "US_TV_Y7")})
+                .setDescription("This is a sample program")
+                .setEndTimeUtcMillis(1000)
+                .setEpisodeNumber("Pilot", 0)
+                .setEpisodeTitle("Hello World")
+                .setLongDescription("This is a longer description than the previous description")
+                .setPosterArtUri(Uri.parse("http://example.com/poster.png"))
+                .setRecordingProhibited(false)
+                .setSeasonNumber("The Final Season", 7)
+                .setSeasonTitle("The Final Season")
+                .setStartTimeUtcMillis(0)
+                .setTitle("Google")
+                .setVideoHeight(1080)
+                .setVideoWidth(1920)
+                .setInternalProviderId("ID-4321")
+                .setPreviewVideoUri(Uri.parse("http://example.com/preview-video.mpg"))
+                .setLastPlaybackPositionMillis(0)
+                .setDurationMillis(60 * 1000)
+                .setAppLinkIntentUri(Uri.parse(new Intent(Intent.ACTION_VIEW).toUri(
+                        Intent.URI_INTENT_SCHEME)))
+                .setWeight(100)
+                .setInternalProviderFlag1(0x4)
+                .setInternalProviderFlag2(0x3)
+                .setInternalProviderFlag3(0x2)
+                .setInternalProviderFlag4(0x1)
+                .setTransient(false)
+                .setType(TvContractCompat.Programs.TYPE_MOVIE)
+                .setWatchNextType(TvContractCompat.Programs.WATCH_NEXT_TYPE_NEW)
+                .setPosterArtAspectRatio(TvContractCompat.Programs.ASPECT_RATIO_2_3)
+                .setThumbnailAspectRatio(TvContractCompat.Programs.ASPECT_RATIO_16_9)
+                .setLogoUri(Uri.parse("http://example.com/program-logo.mpg"))
+                .setAvailability(TvContractCompat.Programs.AVAILABILITY_AVAILABLE)
+                .setStartingPrice("12.99 USD")
+                .setOfferPrice("4.99 USD")
+                .setReleaseDate("1997")
+                .setItemCount(3)
+                .setLive(false)
+                .setInteractionType(TvContractCompat.Programs.INTERACTION_TYPE_LIKES)
+                .setInteractionCount(10200)
+                .setAuthor("author_name")
+                .setReviewRatingStyle(TvContractCompat.Programs.REVIEW_RATING_STYLE_STARS)
+                .setReviewRating("4.5")
+                .build();
+
+        ContentValues contentValues = fullyPopulatedProgram.toContentValues();
+        compareProgram(fullyPopulatedProgram,
+                Program.fromCursor(getProgramCursor(Program.PROJECTION, contentValues)));
+
+        Program clonedFullyPopulatedProgram = new Program.Builder(fullyPopulatedProgram).build();
+        compareProgram(fullyPopulatedProgram, clonedFullyPopulatedProgram);
+    }
+
+    @Test
+    public void testPreviewProgram() {
+        Program previewProgram = new Program.Builder()
+                .setId(10)
+                .setChannelId(3)
+                .setTitle("Recommended Video 1")
+                .setDescription("You should watch this!")
+                .setPosterArtUri(Uri.parse("http://example.com/poster.png"))
+                .setInternalProviderFlag2(0x0010010084108410L)
+                .setInternalProviderId("ID-4321")
+                .setPreviewVideoUri(Uri.parse("http://example.com/preview-video.mpg"))
+                .setLastPlaybackPositionMillis(0)
+                .setDurationMillis(60 * 1000)
+                .setAppLinkIntentUri(Uri.parse(new Intent(Intent.ACTION_VIEW).toUri(
+                        Intent.URI_INTENT_SCHEME)))
+                .setWeight(100)
+                .setTransient(false)
+                .setType(TvContractCompat.Programs.TYPE_TV_EPISODE)
+                .setWatchNextType(TvContractCompat.Programs.WATCH_NEXT_TYPE_CONTINUE)
+                .setPosterArtAspectRatio(TvContractCompat.Programs.ASPECT_RATIO_3_2)
+                .setThumbnailAspectRatio(TvContractCompat.Programs.ASPECT_RATIO_16_9)
+                .setLogoUri(Uri.parse("http://example.com/program-logo.mpg"))
+                .setAvailability(TvContractCompat.Programs.AVAILABILITY_FREE_WITH_SUBSCRIPTION)
+                .setStartingPrice("9.99 USD")
+                .setOfferPrice("3.99 USD")
+                .setReleaseDate(new Date(97, 2, 8))
+                .setLive(false)
+                .setInteractionType(TvContractCompat.Programs.INTERACTION_TYPE_VIEWS)
+                .setInteractionCount(99200)
+                .setAuthor("author_name")
+                .setReviewRatingStyle(TvContractCompat.Programs.REVIEW_RATING_STYLE_PERCENTAGE)
+                .setReviewRating("83.9")
+                .build();
+
+        String[] partialProjection = {
+                TvContractCompat.Programs._ID,
+                TvContractCompat.Programs.COLUMN_CHANNEL_ID,
+                TvContractCompat.Programs.COLUMN_TITLE,
+                TvContractCompat.Programs.COLUMN_SHORT_DESCRIPTION,
+                TvContractCompat.Programs.COLUMN_POSTER_ART_URI,
+                TvContractCompat.Programs.COLUMN_INTERNAL_PROVIDER_FLAG2,
+                TvContractCompat.Programs.COLUMN_INTERNAL_PROVIDER_ID,
+                TvContractCompat.Programs.COLUMN_PREVIEW_VIDEO_URI,
+                TvContractCompat.Programs.COLUMN_LAST_PLAYBACK_POSITION_MILLIS,
+                TvContractCompat.Programs.COLUMN_DURATION_MILLIS,
+                TvContractCompat.Programs.COLUMN_APP_LINK_INTENT_URI,
+                TvContractCompat.Programs.COLUMN_WEIGHT,
+                TvContractCompat.Programs.COLUMN_TRANSIENT,
+                TvContractCompat.Programs.COLUMN_TYPE,
+                TvContractCompat.Programs.COLUMN_WATCH_NEXT_TYPE,
+                TvContractCompat.Programs.COLUMN_POSTER_ART_ASPECT_RATIO,
+                TvContractCompat.Programs.COLUMN_THUMBNAIL_ASPECT_RATIO,
+                TvContractCompat.Programs.COLUMN_LOGO_URI,
+                TvContractCompat.Programs.COLUMN_AVAILABILITY,
+                TvContractCompat.Programs.COLUMN_STARTING_PRICE,
+                TvContractCompat.Programs.COLUMN_OFFER_PRICE,
+                TvContractCompat.Programs.COLUMN_RELEASE_DATE,
+                TvContractCompat.Programs.COLUMN_ITEM_COUNT,
+                TvContractCompat.Programs.COLUMN_LIVE,
+                TvContractCompat.Programs.COLUMN_INTERACTION_TYPE,
+                TvContractCompat.Programs.COLUMN_INTERACTION_COUNT,
+                TvContractCompat.Programs.COLUMN_AUTHOR,
+                TvContractCompat.Programs.COLUMN_REVIEW_RATING_STYLE,
+                TvContractCompat.Programs.COLUMN_REVIEW_RATING,
+        };
+
+        ContentValues contentValues = previewProgram.toContentValues();
+        compareProgram(previewProgram,
+                Program.fromCursor(getProgramCursor(partialProjection, contentValues)));
+
+        Program clonedFullyPopulatedProgram = new Program.Builder(previewProgram).build();
+        compareProgram(previewProgram, clonedFullyPopulatedProgram);
+    }
+
+    private static void compareProgram(Program programA, Program programB) {
+        assertTrue(Arrays.equals(programA.getAudioLanguages(), programB.getAudioLanguages()));
+        assertTrue(Arrays.deepEquals(programA.getBroadcastGenres(), programB.getBroadcastGenres()));
+        assertTrue(Arrays.deepEquals(programA.getCanonicalGenres(), programB.getCanonicalGenres()));
+        assertEquals(programA.getChannelId(), programB.getChannelId());
+        assertTrue(Arrays.deepEquals(programA.getContentRatings(), programB.getContentRatings()));
+        assertEquals(programA.getDescription(), programB.getDescription());
+        assertEquals(programA.getEndTimeUtcMillis(), programB.getEndTimeUtcMillis());
+        assertEquals(programA.getEpisodeNumber(), programB.getEpisodeNumber());
+        assertEquals(programA.getEpisodeTitle(), programB.getEpisodeTitle());
+        assertEquals(programA.getLongDescription(), programB.getLongDescription());
+        assertEquals(programA.getPosterArtUri(), programB.getPosterArtUri());
+        assertEquals(programA.getId(), programB.getId());
+        assertEquals(programA.getSeasonNumber(), programB.getSeasonNumber());
+        assertEquals(programA.getStartTimeUtcMillis(), programB.getStartTimeUtcMillis());
+        assertEquals(programA.getThumbnailUri(), programB.getThumbnailUri());
+        assertEquals(programA.getTitle(), programB.getTitle());
+        assertEquals(programA.getVideoHeight(), programB.getVideoHeight());
+        assertEquals(programA.getVideoWidth(), programB.getVideoWidth());
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            assertEquals(programA.isSearchable(), programB.isSearchable());
+            assertEquals(programA.getInternalProviderFlag1(), programB.getInternalProviderFlag1());
+            assertEquals(programA.getInternalProviderFlag2(), programB.getInternalProviderFlag2());
+            assertEquals(programA.getInternalProviderFlag3(), programB.getInternalProviderFlag3());
+            assertEquals(programA.getInternalProviderFlag4(), programB.getInternalProviderFlag4());
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            assertTrue(Objects.equals(programA.getSeasonTitle(), programB.getSeasonTitle()));
+            assertTrue(Objects.equals(programA.isRecordingProhibited(),
+                    programB.isRecordingProhibited()));
+        }
+        if (BuildCompat.isAtLeastO()) {
+            assertEquals(programA.getInternalProviderId(), programB.getInternalProviderId());
+            assertEquals(programA.getPreviewVideoUri(), programB.getPreviewVideoUri());
+            assertEquals(programA.getLastPlaybackPositionMillis(),
+                    programB.getLastPlaybackPositionMillis());
+            assertEquals(programA.getDurationMillis(), programB.getDurationMillis());
+            assertEquals(programA.getAppLinkIntentUri(), programB.getAppLinkIntentUri());
+            assertEquals(programA.getWeight(), programB.getWeight());
+            assertEquals(programA.isTransient(), programB.isTransient());
+            assertEquals(programA.getType(), programB.getType());
+            assertEquals(programA.getWatchNextType(), programB.getWatchNextType());
+            assertEquals(programA.getPosterArtAspectRatio(), programB.getPosterArtAspectRatio());
+            assertEquals(programA.getThumbnailAspectRatio(), programB.getThumbnailAspectRatio());
+            assertEquals(programA.getLogoUri(), programB.getLogoUri());
+            assertEquals(programA.getAvailability(), programB.getAvailability());
+            assertEquals(programA.getStartingPrice(), programB.getStartingPrice());
+            assertEquals(programA.getOfferPrice(), programB.getOfferPrice());
+            assertEquals(programA.getReleaseDate(), programB.getReleaseDate());
+            assertEquals(programA.getItemCount(), programB.getItemCount());
+            assertEquals(programA.isLive(), programB.isLive());
+            assertEquals(programA.getInteractionType(), programB.getInteractionType());
+            assertEquals(programA.getInteractionCount(), programB.getInteractionCount());
+            assertEquals(programA.getAuthor(), programB.getAuthor());
+            assertEquals(programA.getReviewRatingStyle(), programB.getReviewRatingStyle());
+            assertEquals(programA.getReviewRating(), programB.getReviewRating());
+        }
+        assertEquals(programA.toContentValues(), programB.toContentValues());
+        assertEquals(programA.toString(), programB.toString());
+        assertEquals(programA, programB);
+    }
+
+    private static MatrixCursor getProgramCursor(String[] projection, ContentValues contentValues) {
+        MatrixCursor cursor = new MatrixCursor(projection);
+        MatrixCursor.RowBuilder builder = cursor.newRow();
+        for (String row: projection) {
+            if (row != null) {
+                builder.add(row, contentValues.get(row));
+            }
+        }
+        cursor.moveToFirst();
+        return cursor;
+    }
+}
diff --git a/v13/Android.mk b/v13/Android.mk
index 9411930..1b30d99 100644
--- a/v13/Android.mk
+++ b/v13/Android.mk
@@ -34,7 +34,6 @@
         $(call all-java-files-under, api25) \
         $(call all-java-files-under, java)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 # Some projects expect to inherit android-support-v4 from
 # android-support-v13, so we need to keep it static until they can be fixed.
 LOCAL_STATIC_ANDROID_LIBRARIES := \
diff --git a/v13/AndroidManifest-make.xml b/v13/AndroidManifest-make.xml
deleted file mode 100644
index ea25a74..0000000
--- a/v13/AndroidManifest-make.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.support.v13">
-    <uses-sdk android:minSdkVersion="13" tools:overrideLibrary="android.support.v13"/>
-    <application />
-</manifest>
diff --git a/v13/AndroidManifest.xml b/v13/AndroidManifest.xml
index 7449688..65ef182 100644
--- a/v13/AndroidManifest.xml
+++ b/v13/AndroidManifest.xml
@@ -16,7 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.v13">
-    <uses-sdk android:minSdkVersion="13" tools:overrideLibrary="android.support.v13"/>
+    <uses-sdk android:minSdkVersion="14" tools:overrideLibrary="android.support.v13"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}"/>
     <application />
 </manifest>
diff --git a/v13/api23/android/support/v13/app/FragmentCompat23.java b/v13/api23/android/support/v13/app/FragmentCompat23.java
index 1364e84..aa59bf5 100644
--- a/v13/api23/android/support/v13/app/FragmentCompat23.java
+++ b/v13/api23/android/support/v13/app/FragmentCompat23.java
@@ -16,12 +16,10 @@
 
 package android.support.v13.app;
 
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(23)
-@TargetApi(23)
 class FragmentCompat23 {
     public static void requestPermissions(Fragment fragment, String[] permissions,
             int requestCode) {
diff --git a/v13/api24/android/support/v13/app/FragmentCompatApi24.java b/v13/api24/android/support/v13/app/FragmentCompatApi24.java
index 2b41d25..caa34b0 100644
--- a/v13/api24/android/support/v13/app/FragmentCompatApi24.java
+++ b/v13/api24/android/support/v13/app/FragmentCompatApi24.java
@@ -17,12 +17,10 @@
 
 package android.support.v13.app;
 
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(24)
-@TargetApi(24)
 class FragmentCompatApi24 {
     public static void setUserVisibleHint(Fragment f, boolean isVisible) {
         f.setUserVisibleHint(isVisible);
diff --git a/v13/api24/android/support/v13/view/DragAndDropPermissionsCompatApi24.java b/v13/api24/android/support/v13/view/DragAndDropPermissionsCompatApi24.java
index fd38b79..1894f69 100644
--- a/v13/api24/android/support/v13/view/DragAndDropPermissionsCompatApi24.java
+++ b/v13/api24/android/support/v13/view/DragAndDropPermissionsCompatApi24.java
@@ -16,14 +16,12 @@
 
 package android.support.v13.view;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.support.annotation.RequiresApi;
 import android.view.DragAndDropPermissions;
 import android.view.DragEvent;
 
 @RequiresApi(24)
-@TargetApi(24)
 class DragAndDropPermissionsCompatApi24 {
     public static Object request(Activity activity, DragEvent dragEvent) {
         return activity.requestDragAndDropPermissions(dragEvent);
diff --git a/v13/api24/android/support/v13/view/ViewCompatApi24.java b/v13/api24/android/support/v13/view/ViewCompatApi24.java
index 422dbb9..905ea71 100644
--- a/v13/api24/android/support/v13/view/ViewCompatApi24.java
+++ b/v13/api24/android/support/v13/view/ViewCompatApi24.java
@@ -16,13 +16,11 @@
 
 package android.support.v13.view;
 
-import android.annotation.TargetApi;
 import android.content.ClipData;
 import android.support.annotation.RequiresApi;
 import android.view.View;
 
 @RequiresApi(24)
-@TargetApi(24)
 class ViewCompatApi24 {
     public static boolean startDragAndDrop(View v, ClipData data,
            View.DragShadowBuilder shadowBuilder, Object localState, int flags) {
diff --git a/v13/api25/android/support/v13/view/inputmethod/EditorInfoCompatApi25.java b/v13/api25/android/support/v13/view/inputmethod/EditorInfoCompatApi25.java
index 3eef2ba..321f642 100644
--- a/v13/api25/android/support/v13/view/inputmethod/EditorInfoCompatApi25.java
+++ b/v13/api25/android/support/v13/view/inputmethod/EditorInfoCompatApi25.java
@@ -16,12 +16,10 @@
 
 package android.support.v13.view.inputmethod;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.view.inputmethod.EditorInfo;
 
 @RequiresApi(25)
-@TargetApi(25)
 final class EditorInfoCompatApi25 {
     public static void setContentMimeTypes(EditorInfo editorInfo, String[] contentMimeTypes) {
         editorInfo.contentMimeTypes = contentMimeTypes;
diff --git a/v13/api25/android/support/v13/view/inputmethod/InputConnectionCompatApi25.java b/v13/api25/android/support/v13/view/inputmethod/InputConnectionCompatApi25.java
index 41de756..4f0fb70 100644
--- a/v13/api25/android/support/v13/view/inputmethod/InputConnectionCompatApi25.java
+++ b/v13/api25/android/support/v13/view/inputmethod/InputConnectionCompatApi25.java
@@ -16,7 +16,6 @@
 
 package android.support.v13.view.inputmethod;
 
-import android.annotation.TargetApi;
 import android.os.Bundle;
 import android.support.annotation.RequiresApi;
 import android.view.inputmethod.InputConnection;
@@ -24,7 +23,6 @@
 import android.view.inputmethod.InputContentInfo;
 
 @RequiresApi(25)
-@TargetApi(25)
 final class InputConnectionCompatApi25 {
 
     public static boolean commitContent(InputConnection ic, Object inputContentInfo, int flags,
diff --git a/v13/api25/android/support/v13/view/inputmethod/InputContentInfoCompatApi25.java b/v13/api25/android/support/v13/view/inputmethod/InputContentInfoCompatApi25.java
index e9b7a01..9295f08 100644
--- a/v13/api25/android/support/v13/view/inputmethod/InputContentInfoCompatApi25.java
+++ b/v13/api25/android/support/v13/view/inputmethod/InputContentInfoCompatApi25.java
@@ -16,14 +16,12 @@
 
 package android.support.v13.view.inputmethod;
 
-import android.annotation.TargetApi;
 import android.content.ClipDescription;
 import android.net.Uri;
 import android.support.annotation.RequiresApi;
 import android.view.inputmethod.InputContentInfo;
 
 @RequiresApi(25)
-@TargetApi(25)
 final class InputContentInfoCompatApi25 {
 
     public static Object create(Uri contentUri, ClipDescription description, Uri linkUri) {
diff --git a/v13/build.gradle b/v13/build.gradle
index fb1c25d..eab93ba 100644
--- a/v13/build.gradle
+++ b/v13/build.gradle
@@ -1,31 +1,27 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'support-v13'
 
 dependencies {
     compile project(':support-annotations')
     compile project(':support-v4')
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile "org.mockito:mockito-core:1.9.5"
-    androidTestCompile "com.google.dexmaker:dexmaker:1.2"
-    androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 13
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'ics',
                 'ics-mr1',
@@ -34,66 +30,11 @@
                 'api25',
                 'java'
         ]
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/java'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Library v13'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 13 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support Library v13'
+    inceptionYear '2011'
+    description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
 }
diff --git a/v13/ics-mr1/android/support/v13/app/FragmentCompatICSMR1.java b/v13/ics-mr1/android/support/v13/app/FragmentCompatICSMR1.java
index 2da10ae..655dcdc 100644
--- a/v13/ics-mr1/android/support/v13/app/FragmentCompatICSMR1.java
+++ b/v13/ics-mr1/android/support/v13/app/FragmentCompatICSMR1.java
@@ -16,12 +16,10 @@
 
 package android.support.v13.app;
 
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(15)
-@TargetApi(15)
 class FragmentCompatICSMR1 {
     public static void setUserVisibleHint(Fragment f, boolean isVisible) {
         if (f.getFragmentManager() != null) {
diff --git a/v13/ics/android/support/v13/app/FragmentCompatICS.java b/v13/ics/android/support/v13/app/FragmentCompatICS.java
index ff40337..dfb5e30 100644
--- a/v13/ics/android/support/v13/app/FragmentCompatICS.java
+++ b/v13/ics/android/support/v13/app/FragmentCompatICS.java
@@ -16,12 +16,10 @@
 
 package android.support.v13.app;
 
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(14)
-@TargetApi(14)
 class FragmentCompatICS {
     public static void setMenuVisibility(Fragment f, boolean visible) {
         f.setMenuVisibility(visible);
diff --git a/v13/java/android/support/v13/app/ActivityCompat.java b/v13/java/android/support/v13/app/ActivityCompat.java
index 8f9a767..caa1c92 100644
--- a/v13/java/android/support/v13/app/ActivityCompat.java
+++ b/v13/java/android/support/v13/app/ActivityCompat.java
@@ -16,7 +16,6 @@
 
 package android.support.v13.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.support.annotation.RequiresApi;
 import android.support.v13.view.DragAndDropPermissionsCompat;
@@ -27,7 +26,6 @@
  * introduced after API level 13 in a backwards compatible fashion.
  */
 @RequiresApi(13)
-@TargetApi(13)
 public class ActivityCompat extends android.support.v4.app.ActivityCompat {
 
     /**
diff --git a/v13/java/android/support/v13/app/FragmentCompat.java b/v13/java/android/support/v13/app/FragmentCompat.java
index 99e4a80..c2ef88e 100644
--- a/v13/java/android/support/v13/app/FragmentCompat.java
+++ b/v13/java/android/support/v13/app/FragmentCompat.java
@@ -16,7 +16,6 @@
 
 package android.support.v13.app;
 
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -34,7 +33,6 @@
  * API level 13 in a backwards compatible fashion.
  */
 @RequiresApi(13)
-@TargetApi(13)
 public class FragmentCompat {
     interface FragmentCompatImpl {
         void setMenuVisibility(Fragment f, boolean visible);
diff --git a/v13/java/android/support/v13/app/FragmentPagerAdapter.java b/v13/java/android/support/v13/app/FragmentPagerAdapter.java
index 78d8b89..49f5222 100644
--- a/v13/java/android/support/v13/app/FragmentPagerAdapter.java
+++ b/v13/java/android/support/v13/app/FragmentPagerAdapter.java
@@ -16,7 +16,6 @@
 
 package android.support.v13.app;
 
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
@@ -65,7 +64,6 @@
  *      complete}
  */
 @RequiresApi(13)
-@TargetApi(13)
 public abstract class FragmentPagerAdapter extends PagerAdapter {
     private static final String TAG = "FragmentPagerAdapter";
     private static final boolean DEBUG = false;
diff --git a/v13/java/android/support/v13/app/FragmentStatePagerAdapter.java b/v13/java/android/support/v13/app/FragmentStatePagerAdapter.java
index 2579688..6d4904e 100644
--- a/v13/java/android/support/v13/app/FragmentStatePagerAdapter.java
+++ b/v13/java/android/support/v13/app/FragmentStatePagerAdapter.java
@@ -16,7 +16,6 @@
 
 package android.support.v13.app;
 
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
@@ -68,7 +67,6 @@
  *      complete}
  */
 @RequiresApi(13)
-@TargetApi(13)
 public abstract class FragmentStatePagerAdapter extends PagerAdapter {
     private static final String TAG = "FragmentStatePagerAdapter";
     private static final boolean DEBUG = false;
diff --git a/v13/java/android/support/v13/app/FragmentTabHost.java b/v13/java/android/support/v13/app/FragmentTabHost.java
index ba5d659..0743d59 100644
--- a/v13/java/android/support/v13/app/FragmentTabHost.java
+++ b/v13/java/android/support/v13/app/FragmentTabHost.java
@@ -16,7 +16,6 @@
 
 package android.support.v13.app;
 
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
@@ -42,7 +41,6 @@
  * normally use this, instead using action bar tabs.
  */
 @RequiresApi(13)
-@TargetApi(13)
 public class FragmentTabHost extends TabHost
         implements TabHost.OnTabChangeListener {
     private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
diff --git a/v13/java/android/support/v13/view/DragAndDropPermissionsCompat.java b/v13/java/android/support/v13/view/DragAndDropPermissionsCompat.java
index 46484da..0a6ac06 100644
--- a/v13/java/android/support/v13/view/DragAndDropPermissionsCompat.java
+++ b/v13/java/android/support/v13/view/DragAndDropPermissionsCompat.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
@@ -30,7 +29,6 @@
  * introduced after API level 13 in a backwards compatible fashion.
  */
 @RequiresApi(13)
-@TargetApi(13)
 public final class DragAndDropPermissionsCompat {
 
     interface DragAndDropPermissionsCompatImpl {
diff --git a/v13/java/android/support/v13/view/DragStartHelper.java b/v13/java/android/support/v13/view/DragStartHelper.java
index 16c54b9..d32f9f7 100644
--- a/v13/java/android/support/v13/view/DragStartHelper.java
+++ b/v13/java/android/support/v13/view/DragStartHelper.java
@@ -17,7 +17,6 @@
 package android.support.v13.view;
 
 
-import android.annotation.TargetApi;
 import android.graphics.Point;
 import android.support.annotation.RequiresApi;
 import android.support.v4.view.InputDeviceCompat;
@@ -71,7 +70,6 @@
  * </pre>
  */
 @RequiresApi(13)
-@TargetApi(13)
 public class DragStartHelper {
     final private View mView;
     final private OnDragStartListener mListener;
diff --git a/v13/java/android/support/v13/view/ViewCompat.java b/v13/java/android/support/v13/view/ViewCompat.java
index 0fd3234..d66f964 100644
--- a/v13/java/android/support/v13/view/ViewCompat.java
+++ b/v13/java/android/support/v13/view/ViewCompat.java
@@ -16,7 +16,6 @@
 
 package android.support.v13.view;
 
-import android.annotation.TargetApi;
 import android.content.ClipData;
 import android.support.annotation.RequiresApi;
 import android.support.v4.os.BuildCompat;
@@ -27,7 +26,6 @@
  * level 13 in a backwards compatible fashion.
  */
 @RequiresApi(13)
-@TargetApi(13)
 public class ViewCompat extends android.support.v4.view.ViewCompat {
     interface ViewCompatImpl {
         boolean startDragAndDrop(View v, ClipData data, View.DragShadowBuilder shadowBuilder,
diff --git a/v13/java/android/support/v13/view/inputmethod/EditorInfoCompat.java b/v13/java/android/support/v13/view/inputmethod/EditorInfoCompat.java
index b1358d0..e195e4e 100644
--- a/v13/java/android/support/v13/view/inputmethod/EditorInfoCompat.java
+++ b/v13/java/android/support/v13/view/inputmethod/EditorInfoCompat.java
@@ -16,23 +16,60 @@
 
 package android.support.v13.view.inputmethod;
 
-import android.annotation.TargetApi;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
 import android.support.v4.os.BuildCompat;
 import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
 
 /**
  * Helper for accessing features in {@link EditorInfo} introduced after API level 13 in a backwards
  * compatible fashion.
  */
 @RequiresApi(13)
-@TargetApi(13)
 public final class EditorInfoCompat {
 
+    /**
+     * Flag of {@link EditorInfo#imeOptions}: used to request that the IME does not update any
+     * personalized data such as typing history and personalized language model based on what the
+     * user typed on this text editing object.  Typical use cases are:
+     * <ul>
+     *     <li>When the application is in a special mode, where user's activities are expected to be
+     *     not recorded in the application's history.  Some web browsers and chat applications may
+     *     have this kind of modes.</li>
+     *     <li>When storing typing history does not make much sense.  Specifying this flag in typing
+     *     games may help to avoid typing history from being filled up with words that the user is
+     *     less likely to type in their daily life.  Another example is that when the application
+     *     already knows that the expected input is not a valid word (e.g. a promotion code that is
+     *     not a valid word in any natural language).</li>
+     * </ul>
+     *
+     * <p>Applications need to be aware that the flag is not a guarantee, and some IMEs may not
+     * respect it.</p>
+     */
+    public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 0x1000000;
+
+    /**
+     * Flag of {@link EditorInfo#imeOptions}: used to request an IME that is capable of inputting
+     * ASCII characters.
+     *
+     * <p>The intention of this flag is to ensure that the user can type Roman alphabet characters
+     * in a {@link android.widget.TextView}. It is typically used for an account ID or password
+     * input.</p>
+     *
+     * <p>In many cases, IMEs are already able to input ASCII even without being told so (such IMEs
+     * already respect this flag in a sense), but there are cases when this is not the default. For
+     * instance, users of languages using a different script like Arabic, Greek, Hebrew or Russian
+     * typically have a keyboard that can't input ASCII characters by default.</p>
+     *
+     * <p>Applications need to be aware that the flag is not a guarantee, and some IMEs may not
+     * respect it. However, it is strongly recommended for IME authors to respect this flag
+     * especially when their IME could end up with a state where only languages using non-ASCII are
+     * enabled.</p>
+     */
+    public static final int IME_FLAG_FORCE_ASCII = 0x80000000;
+
     private interface EditorInfoCompatImpl {
         void setContentMimeTypes(@NonNull EditorInfo editorInfo,
                 @Nullable String[] contentMimeTypes);
diff --git a/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java b/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java
index 5f7b012..ac50a25 100644
--- a/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java
+++ b/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java
@@ -16,7 +16,6 @@
 
 package android.support.v13.view.inputmethod;
 
-import android.annotation.TargetApi;
 import android.content.ClipDescription;
 import android.net.Uri;
 import android.os.Bundle;
@@ -35,7 +34,6 @@
  * backwards compatible fashion.
  */
 @RequiresApi(13)
-@TargetApi(13)
 public final class InputConnectionCompat {
 
     private interface InputConnectionCompatImpl {
diff --git a/v13/java/android/support/v13/view/inputmethod/InputContentInfoCompat.java b/v13/java/android/support/v13/view/inputmethod/InputContentInfoCompat.java
index 9379020..b1a44ce 100644
--- a/v13/java/android/support/v13/view/inputmethod/InputContentInfoCompat.java
+++ b/v13/java/android/support/v13/view/inputmethod/InputContentInfoCompat.java
@@ -16,7 +16,6 @@
 
 package android.support.v13.view.inputmethod;
 
-import android.annotation.TargetApi;
 import android.content.ClipDescription;
 import android.net.Uri;
 import android.support.annotation.NonNull;
@@ -29,7 +28,6 @@
  * compatible fashion.
  */
 @RequiresApi(13)
-@TargetApi(13)
 public final class InputContentInfoCompat {
 
     private interface InputContentInfoCompatImpl {
diff --git a/v13/tests/AndroidManifest.xml b/v13/tests/AndroidManifest.xml
index 4ce99ee..5fe72ce 100644
--- a/v13/tests/AndroidManifest.xml
+++ b/v13/tests/AndroidManifest.xml
@@ -19,7 +19,7 @@
     package="android.support.v13.test">
 
     <uses-sdk
-        android:minSdkVersion="13"
+        android:minSdkVersion="14"
         android:targetSdkVersion="24"
         tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                       android.support.test.espresso, android.support.test.espresso.idling"/>
diff --git a/v13/tests/java/android/support/v13/view/DragStartHelperTest.java b/v13/tests/java/android/support/v13/view/DragStartHelperTest.java
index ad6625f..21cd71e 100644
--- a/v13/tests/java/android/support/v13/view/DragStartHelperTest.java
+++ b/v13/tests/java/android/support/v13/view/DragStartHelperTest.java
@@ -26,7 +26,6 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
-import android.annotation.TargetApi;
 import android.app.Instrumentation;
 import android.graphics.Point;
 import android.os.Build;
@@ -34,6 +33,7 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.ActivityTestRule;
@@ -53,8 +53,6 @@
 import org.mockito.InOrder;
 
 @RequiresApi(13)
-@TargetApi(13)
-@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DragStartHelperTest {
 
@@ -168,6 +166,7 @@
         mDragSource = mActivityRule.getActivity().findViewById(R.id.drag_source);
     }
 
+    @SmallTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     @Test
     public void mouseClick() throws Throwable {
@@ -182,6 +181,7 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @SmallTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     @Test
     public void mousePressWithSecondaryButton() throws Throwable {
@@ -198,6 +198,7 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @SmallTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     @Test
     public void mouseDrag() throws Throwable {
@@ -216,6 +217,7 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @SmallTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     @Test
     public void mouseDragWithNonprimaryButton() throws Throwable {
@@ -235,6 +237,7 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @SmallTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     @Test
     public void mouseDragUsingTouchListener() throws Throwable {
@@ -260,6 +263,7 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @SmallTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     @Test
     public void mouseDragWhenListenerReturnsFalse() throws Throwable {
@@ -283,6 +287,7 @@
         inOrder.verifyNoMoreInteractions();
     }
 
+    @LargeTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     @Test
     public void mouseLongPress() throws Throwable {
@@ -299,6 +304,7 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @SmallTest
     @Test
     public void touchDrag() throws Throwable {
         final DragStartListener listener = createListener(false);
@@ -314,6 +320,7 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @SmallTest
     @Test
     public void touchTap() throws Throwable {
         final DragStartListener listener = createListener(false);
@@ -327,6 +334,7 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @LargeTest
     @Test
     public void touchLongPress() throws Throwable {
         final DragStartListener listener = createListener(true);
@@ -342,6 +350,7 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @LargeTest
     @Test
     public void touchLongPressUsingLongClickListener() throws Throwable {
         final DragStartListener listener = createListener(true);
diff --git a/v14/preference/Android.mk b/v14/preference/Android.mk
index 195e8a3..7a0b846 100644
--- a/v14/preference/Android.mk
+++ b/v14/preference/Android.mk
@@ -31,7 +31,6 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-v7-preference \
     android-support-v7-appcompat \
diff --git a/v14/preference/AndroidManifest-make.xml b/v14/preference/AndroidManifest-make.xml
deleted file mode 100644
index b917bb4..0000000
--- a/v14/preference/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.support.v14.preference">
-    <uses-sdk android:minSdkVersion="14" />
-    <application />
-</manifest>
diff --git a/v14/preference/build.gradle b/v14/preference/build.gradle
index 5583e93..e36ab82 100644
--- a/v14/preference/build.gradle
+++ b/v14/preference/build.gradle
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'preference-v14'
 
 dependencies {
@@ -25,78 +25,20 @@
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
         minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDir 'src'
         main.res.srcDir 'res'
         main.assets.srcDir 'assets'
         main.resources.srcDir 'src'
-
-        // this moves src/instrumentTest to tests so all folders follow:
-        // tests/java, tests/res, tests/assets, ...
-        // This is a *reset* so it replaces the default paths
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Preference v14'
-                description "Android Support Preference v14"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2015'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support Preference v14'
+    inceptionYear '2015'
+    description 'Android Support Preference v14'
 }
diff --git a/v14/preference/res/layout/preference_widget_seekbar_material.xml b/v14/preference/res/layout/preference_widget_seekbar_material.xml
new file mode 100644
index 0000000..f54108a
--- /dev/null
+++ b/v14/preference/res/layout/preference_widget_seekbar_material.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<!-- Layout used by SeekBarPreference for the seekbar widget style. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:minHeight="?android:attr/listPreferredItemHeight"
+              android:gravity="center_vertical"
+              android:paddingEnd="?android:attr/scrollbarSize"
+              android:clipChildren="false"
+              android:clipToPadding="false">
+
+    <ImageView
+            android:id="@+android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:minWidth="@dimen/preference_icon_minWidth"/>
+
+    <RelativeLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dip"
+            android:layout_marginEnd="8dip"
+            android:layout_marginTop="6dip"
+            android:layout_marginBottom="6dip"
+            android:layout_weight="1"
+            android:clipChildren="false"
+            android:clipToPadding="false">
+
+        <TextView android:id="@+android:id/title"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:textAppearance="@style/Preference_TextAppearanceMaterialSubhead"
+                  android:ellipsize="marquee"
+                  android:fadingEdge="horizontal"/>
+
+        <TextView android:id="@+android:id/summary"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:layout_below="@android:id/title"
+                  android:layout_alignStart="@android:id/title"
+                  android:textAppearance="?android:attr/textAppearanceSmall"
+                  android:textColor="?android:attr/textColorSecondary"
+                  android:maxLines="4"/>
+
+        <!-- Using UnPressableLinearLayout as a workaround to disable the pressed state propagation
+        to the children of this container layout. Otherwise, the animated pressed state will also
+        play for the thumb in the AbsSeekBar in addition to the preference's ripple background.
+        The background of the SeekBar is also set to null to disable the ripple background -->
+        <android.support.v7.preference.UnPressableLinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@android:id/summary"
+                android:layout_alignStart="@android:id/title"
+                android:clipChildren="false"
+                android:clipToPadding="false">
+            <SeekBar
+                    android:id="@+id/seekbar"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="wrap_content"
+                    android:paddingStart="@dimen/preference_seekbar_padding_start"
+                    android:paddingEnd="@dimen/preference_seekbar_padding_end"
+                    android:focusable="false"
+                    android:clickable="false"
+                    android:background="@null" />
+
+            <TextView android:id="@+id/seekbar_value"
+                      android:layout_width="@dimen/preference_seekbar_value_width"
+                      android:layout_height="match_parent"
+                      android:gravity="right|center_vertical"
+                      android:fontFamily="sans-serif-condensed"
+                      android:singleLine="true"
+                      android:textAppearance="@style/Preference_TextAppearanceMaterialSubhead"
+                      android:ellipsize="marquee"
+                      android:fadingEdge="horizontal"/>
+        </android.support.v7.preference.UnPressableLinearLayout>
+
+    </RelativeLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/v14/preference/res/values/styles.xml b/v14/preference/res/values/styles.xml
index baef67f..26b1544 100644
--- a/v14/preference/res/values/styles.xml
+++ b/v14/preference/res/values/styles.xml
@@ -48,6 +48,12 @@
         <item name="android:layout">@layout/preference_material</item>
     </style>
 
+    <style name="Preference.SeekBarPreference.Material">
+        <item name="android:layout">@layout/preference_widget_seekbar_material</item>
+        <item name="adjustable">true</item>
+        <item name="showSeekBarValue">true</item>
+    </style>
+
     <style name="Preference.PreferenceScreen.Material">
         <item name="android:layout">@layout/preference_material</item>
     </style>
diff --git a/v14/preference/res/values/themes.xml b/v14/preference/res/values/themes.xml
index 026d2d8..a69126f 100644
--- a/v14/preference/res/values/themes.xml
+++ b/v14/preference/res/values/themes.xml
@@ -31,6 +31,7 @@
         <item name="checkBoxPreferenceStyle">@style/Preference.CheckBoxPreference.Material</item>
         <item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat.Material</item>
         <item name="switchPreferenceStyle">@style/Preference.SwitchPreference.Material</item>
+        <item name="seekBarPreferenceStyle">@style/Preference.SeekBarPreference.Material</item>
         <item name="dialogPreferenceStyle">@style/Preference.DialogPreference.Material</item>
         <item name="editTextPreferenceStyle">@style/Preference.DialogPreference.EditTextPreference.Material</item>
         <item name="dropdownPreferenceStyle">@style/Preference.DropDown.Material</item>
diff --git a/v14/preference/src/android/support/v14/preference/PreferenceFragment.java b/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
index d2519d1..ad790d4 100644
--- a/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
+++ b/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
@@ -32,7 +32,6 @@
 import android.support.annotation.RestrictTo;
 import android.support.annotation.XmlRes;
 import android.support.v4.content.res.TypedArrayUtils;
-import android.support.v4.view.ViewCompat;
 import android.support.v7.preference.AndroidResources;
 import android.support.v7.preference.DialogPreference;
 import android.support.v7.preference.EditTextPreference;
@@ -790,7 +789,7 @@
             for (int childViewIndex = 0; childViewIndex < childCount; childViewIndex++) {
                 final View view = parent.getChildAt(childViewIndex);
                 if (shouldDrawDividerBelow(view, parent)) {
-                    int top = (int) ViewCompat.getY(view) + view.getHeight();
+                    int top = (int) view.getY() + view.getHeight();
                     mDivider.setBounds(0, top, width, top + mDividerHeight);
                     mDivider.draw(c);
                 }
diff --git a/v17/leanback/Android.mk b/v17/leanback/Android.mk
index d91436e..c6a50b4 100644
--- a/v17/leanback/Android.mk
+++ b/v17/leanback/Android.mk
@@ -35,7 +35,6 @@
     $(call all-java-files-under, api23) \
     $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-v7-recyclerview \
     android-support-compat \
diff --git a/v17/leanback/AndroidManifest-make.xml b/v17/leanback/AndroidManifest-make.xml
deleted file mode 100644
index 20ef094..0000000
--- a/v17/leanback/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.v17.leanback">
-    <uses-sdk android:minSdkVersion="17"/>
-    <application />
-</manifest>
diff --git a/v17/leanback/api21/android/support/v17/leanback/transition/FadeAndShortSlide.java b/v17/leanback/api21/android/support/v17/leanback/transition/FadeAndShortSlide.java
index 76e237b..0e135a9 100644
--- a/v17/leanback/api21/android/support/v17/leanback/transition/FadeAndShortSlide.java
+++ b/v17/leanback/api21/android/support/v17/leanback/transition/FadeAndShortSlide.java
@@ -20,7 +20,6 @@
 import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.TimeInterpolator;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
@@ -42,7 +41,6 @@
  * @hide
  */
 @RequiresApi(21)
-@TargetApi(21)
 @RestrictTo(LIBRARY_GROUP)
 public class FadeAndShortSlide extends Visibility {
 
diff --git a/v17/leanback/api21/android/support/v17/leanback/transition/SlideNoPropagation.java b/v17/leanback/api21/android/support/v17/leanback/transition/SlideNoPropagation.java
index 5158992..46c67ac 100644
--- a/v17/leanback/api21/android/support/v17/leanback/transition/SlideNoPropagation.java
+++ b/v17/leanback/api21/android/support/v17/leanback/transition/SlideNoPropagation.java
@@ -15,7 +15,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
@@ -26,7 +25,6 @@
  * @hide
  */
 @RequiresApi(21)
-@TargetApi(21)
 @RestrictTo(LIBRARY_GROUP)
 public class SlideNoPropagation extends Slide {
 
diff --git a/v17/leanback/api21/android/support/v17/leanback/transition/TransitionHelperApi21.java b/v17/leanback/api21/android/support/v17/leanback/transition/TransitionHelperApi21.java
index 1fe0874..4734c26 100644
--- a/v17/leanback/api21/android/support/v17/leanback/transition/TransitionHelperApi21.java
+++ b/v17/leanback/api21/android/support/v17/leanback/transition/TransitionHelperApi21.java
@@ -14,7 +14,6 @@
 package android.support.v17.leanback.transition;
 
 import android.R;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Rect;
 import android.support.annotation.RequiresApi;
@@ -27,7 +26,6 @@
 import android.view.animation.AnimationUtils;
 
 @RequiresApi(21)
-@TargetApi(21)
 final class TransitionHelperApi21 {
 
     TransitionHelperApi21() {
diff --git a/v17/leanback/api21/android/support/v17/leanback/transition/TranslationAnimationCreator.java b/v17/leanback/api21/android/support/v17/leanback/transition/TranslationAnimationCreator.java
index 15b9081..157118e 100644
--- a/v17/leanback/api21/android/support/v17/leanback/transition/TranslationAnimationCreator.java
+++ b/v17/leanback/api21/android/support/v17/leanback/transition/TranslationAnimationCreator.java
@@ -6,7 +6,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
-import android.annotation.TargetApi;
 import android.graphics.Path;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
@@ -23,7 +22,6 @@
  * @hide
  */
 @RequiresApi(21)
-@TargetApi(21)
 @RestrictTo(LIBRARY_GROUP)
 class TranslationAnimationCreator {
 
diff --git a/v17/leanback/api21/android/support/v17/leanback/widget/RoundedRectHelperApi21.java b/v17/leanback/api21/android/support/v17/leanback/widget/RoundedRectHelperApi21.java
index c0ba7dd..df1f0f3 100644
--- a/v17/leanback/api21/android/support/v17/leanback/widget/RoundedRectHelperApi21.java
+++ b/v17/leanback/api21/android/support/v17/leanback/widget/RoundedRectHelperApi21.java
@@ -13,7 +13,6 @@
  */
 package android.support.v17.leanback.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.Outline;
 import android.support.annotation.RequiresApi;
 import android.util.SparseArray;
@@ -21,7 +20,6 @@
 import android.view.ViewOutlineProvider;
 
 @RequiresApi(21)
-@TargetApi(21)
 class RoundedRectHelperApi21 {
 
     private static SparseArray<ViewOutlineProvider> sRoundedRectProvider;
diff --git a/v17/leanback/api21/android/support/v17/leanback/widget/ShadowHelperApi21.java b/v17/leanback/api21/android/support/v17/leanback/widget/ShadowHelperApi21.java
index 35f2c51..4e03d8a 100644
--- a/v17/leanback/api21/android/support/v17/leanback/widget/ShadowHelperApi21.java
+++ b/v17/leanback/api21/android/support/v17/leanback/widget/ShadowHelperApi21.java
@@ -13,14 +13,12 @@
  */
 package android.support.v17.leanback.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.Outline;
 import android.support.annotation.RequiresApi;
 import android.view.View;
 import android.view.ViewOutlineProvider;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ShadowHelperApi21 {
 
     static class ShadowImpl {
diff --git a/v17/leanback/api23/android/support/v17/leanback/app/PermissionHelper23.java b/v17/leanback/api23/android/support/v17/leanback/app/PermissionHelper23.java
index 82ba369..4d5d5ad 100644
--- a/v17/leanback/api23/android/support/v17/leanback/app/PermissionHelper23.java
+++ b/v17/leanback/api23/android/support/v17/leanback/app/PermissionHelper23.java
@@ -13,11 +13,9 @@
  */
 package android.support.v17.leanback.app;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(23)
-@TargetApi(23)
 class PermissionHelper23 {
 
     public static void requestPermissions(android.app.Fragment fragment, String[] permissions,
diff --git a/v17/leanback/api23/android/support/v17/leanback/widget/ForegroundHelperApi23.java b/v17/leanback/api23/android/support/v17/leanback/widget/ForegroundHelperApi23.java
index f00f43d..e02eea9 100644
--- a/v17/leanback/api23/android/support/v17/leanback/widget/ForegroundHelperApi23.java
+++ b/v17/leanback/api23/android/support/v17/leanback/widget/ForegroundHelperApi23.java
@@ -13,13 +13,11 @@
  */
 package android.support.v17.leanback.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
 import android.view.View;
 
 @RequiresApi(23)
-@TargetApi(23)
 class ForegroundHelperApi23 {
 
     public static Drawable getForeground(View view) {
diff --git a/v17/leanback/build.gradle b/v17/leanback/build.gradle
index 9ed65a8..d0c1832 100644
--- a/v17/leanback/build.gradle
+++ b/v17/leanback/build.gradle
@@ -1,4 +1,4 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'leanback-v17'
 
 dependencies {
@@ -7,28 +7,24 @@
     compile project(':support-media-compat')
     compile project(':support-fragment')
     compile project(':support-recyclerview-v7')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    testCompile 'junit:junit:4.12'
-    androidTestCompile "org.mockito:mockito-core:1.9.5"
-    androidTestCompile "com.google.dexmaker:dexmaker:1.2"
-    androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
         minSdkVersion 17
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'common',
                 'jbmr2',
@@ -38,70 +34,16 @@
                 'src'
         ]
         main.res.srcDir 'res'
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/java'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
     }
 
     lintOptions {
         // Remove this once all NewApi breakages have been fixed.
         disable "NewApi"
     }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Leanback v17'
-                description "Android Support Leanback v17"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support Leanback v17'
+    inceptionYear '2014'
+    description 'Android Support Leanback v17'
 }
diff --git a/v17/leanback/jbmr2/android/support/v17/leanback/widget/ShadowHelperJbmr2.java b/v17/leanback/jbmr2/android/support/v17/leanback/widget/ShadowHelperJbmr2.java
index 4ee6b29..8cd0054 100644
--- a/v17/leanback/jbmr2/android/support/v17/leanback/widget/ShadowHelperJbmr2.java
+++ b/v17/leanback/jbmr2/android/support/v17/leanback/widget/ShadowHelperJbmr2.java
@@ -13,7 +13,6 @@
  */
 package android.support.v17.leanback.widget;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.support.v17.leanback.R;
 import android.view.LayoutInflater;
@@ -21,7 +20,6 @@
 import android.view.ViewGroup;
 
 @RequiresApi(18)
-@TargetApi(18)
 class ShadowHelperJbmr2 {
 
     static class ShadowImpl {
diff --git a/v17/leanback/kitkat/android/support/v17/leanback/transition/LeanbackTransitionHelperKitKat.java b/v17/leanback/kitkat/android/support/v17/leanback/transition/LeanbackTransitionHelperKitKat.java
index b6a82b7..872e836 100644
--- a/v17/leanback/kitkat/android/support/v17/leanback/transition/LeanbackTransitionHelperKitKat.java
+++ b/v17/leanback/kitkat/android/support/v17/leanback/transition/LeanbackTransitionHelperKitKat.java
@@ -13,7 +13,6 @@
  */
 package android.support.v17.leanback.transition;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 import android.support.v17.leanback.R;
@@ -21,7 +20,6 @@
 import android.view.animation.AnimationUtils;
 
 @RequiresApi(19)
-@TargetApi(19)
 class LeanbackTransitionHelperKitKat {
 
     static public Object loadTitleInTransition(Context context) {
diff --git a/v17/leanback/kitkat/android/support/v17/leanback/transition/Scale.java b/v17/leanback/kitkat/android/support/v17/leanback/transition/Scale.java
index 5fbf414..2fe4c9a 100644
--- a/v17/leanback/kitkat/android/support/v17/leanback/transition/Scale.java
+++ b/v17/leanback/kitkat/android/support/v17/leanback/transition/Scale.java
@@ -17,7 +17,6 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.view.View;
 import android.view.ViewGroup;
@@ -25,7 +24,6 @@
 import android.transition.TransitionValues;
 
 @RequiresApi(19)
-@TargetApi(19)
 class Scale extends Transition {
     private static final String PROPNAME_SCALE = "android:leanback:scale";
 
diff --git a/v17/leanback/kitkat/android/support/v17/leanback/transition/SlideKitkat.java b/v17/leanback/kitkat/android/support/v17/leanback/transition/SlideKitkat.java
index e8e4c10..2d74958 100644
--- a/v17/leanback/kitkat/android/support/v17/leanback/transition/SlideKitkat.java
+++ b/v17/leanback/kitkat/android/support/v17/leanback/transition/SlideKitkat.java
@@ -19,7 +19,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.support.annotation.RequiresApi;
@@ -40,7 +39,6 @@
  * This is a limited Slide implementation for KitKat without propagation support.
  */
 @RequiresApi(19)
-@TargetApi(19)
 class SlideKitkat extends Visibility {
     private static final String TAG = "SlideKitkat";
 
diff --git a/v17/leanback/kitkat/android/support/v17/leanback/transition/TransitionHelperKitkat.java b/v17/leanback/kitkat/android/support/v17/leanback/transition/TransitionHelperKitkat.java
index 777b34b..38a80f2 100644
--- a/v17/leanback/kitkat/android/support/v17/leanback/transition/TransitionHelperKitkat.java
+++ b/v17/leanback/kitkat/android/support/v17/leanback/transition/TransitionHelperKitkat.java
@@ -15,7 +15,6 @@
 
 import android.animation.Animator;
 import android.animation.TimeInterpolator;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 import android.transition.AutoTransition;
@@ -36,7 +35,6 @@
 import java.util.HashMap;
 
 @RequiresApi(19)
-@TargetApi(19)
 final class TransitionHelperKitkat {
 
     TransitionHelperKitkat() {
diff --git a/v17/leanback/kitkat/android/support/v17/leanback/widget/BackgroundHelperKitkat.java b/v17/leanback/kitkat/android/support/v17/leanback/widget/BackgroundHelperKitkat.java
index 49cb35e..64c02a7 100644
--- a/v17/leanback/kitkat/android/support/v17/leanback/widget/BackgroundHelperKitkat.java
+++ b/v17/leanback/kitkat/android/support/v17/leanback/widget/BackgroundHelperKitkat.java
@@ -15,13 +15,11 @@
  */
 package android.support.v17.leanback.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
 import android.view.View;
 
 @RequiresApi(19)
-@TargetApi(19)
 class BackgroundHelperKitkat {
 
     public static void setBackgroundPreservingAlpha(View view, Drawable drawable) {
diff --git a/v17/leanback/res/animator/lb_onboarding_description_enter.xml b/v17/leanback/res/animator/lb_onboarding_description_enter.xml
index 5f26cdd..3cb5843 100644
--- a/v17/leanback/res/animator/lb_onboarding_description_enter.xml
+++ b/v17/leanback/res/animator/lb_onboarding_description_enter.xml
@@ -21,11 +21,13 @@
         android:valueFrom="0.0"
         android:valueTo="1.0"
         android:duration="533"
+        android:startOffset="@integer/lb_onboarding_header_description_delay"
         android:interpolator="@android:interpolator/fast_out_slow_in" />
     <objectAnimator
         android:propertyName="translationY"
         android:valueFrom="60dp"
         android:valueTo="0dp"
         android:duration="533"
+        android:startOffset="@integer/lb_onboarding_header_description_delay"
         android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/v17/leanback/res/animator/lb_onboarding_title_enter.xml b/v17/leanback/res/animator/lb_onboarding_title_enter.xml
index 5f26cdd..9b65b48 100644
--- a/v17/leanback/res/animator/lb_onboarding_title_enter.xml
+++ b/v17/leanback/res/animator/lb_onboarding_title_enter.xml
@@ -21,11 +21,13 @@
         android:valueFrom="0.0"
         android:valueTo="1.0"
         android:duration="533"
+        android:startOffset="@integer/lb_onboarding_header_title_delay"
         android:interpolator="@android:interpolator/fast_out_slow_in" />
     <objectAnimator
         android:propertyName="translationY"
         android:valueFrom="60dp"
         android:valueTo="0dp"
         android:duration="533"
+        android:startOffset="@integer/lb_onboarding_header_title_delay"
         android:interpolator="@android:interpolator/fast_out_slow_in" />
 </set>
diff --git a/v17/leanback/res/layout/lb_onboarding_fragment.xml b/v17/leanback/res/layout/lb_onboarding_fragment.xml
index 04bd0ea..823fe74 100644
--- a/v17/leanback/res/layout/lb_onboarding_fragment.xml
+++ b/v17/leanback/res/layout/lb_onboarding_fragment.xml
@@ -28,10 +28,15 @@
         android:layout_height="match_parent"
         android:visibility="gone" />
 
+    <ImageView
+        android:id="@+id/main_icon"
+        style="?attr/onboardingMainIconStyle"/>
+
     <LinearLayout
         android:id="@+id/page_container"
         style="?attr/onboardingHeaderStyle"
         android:visibility="gone">
+
         <TextView
             android:id="@+id/title"
             style="?attr/onboardingTitleStyle"/>
diff --git a/v17/leanback/res/values-az-rAZ/strings.xml b/v17/leanback/res/values-az/strings.xml
similarity index 100%
rename from v17/leanback/res/values-az-rAZ/strings.xml
rename to v17/leanback/res/values-az/strings.xml
diff --git a/v17/leanback/res/values-be-rBY/strings.xml b/v17/leanback/res/values-be/strings.xml
similarity index 100%
rename from v17/leanback/res/values-be-rBY/strings.xml
rename to v17/leanback/res/values-be/strings.xml
diff --git a/v17/leanback/res/values-bn-rBD/strings.xml b/v17/leanback/res/values-bn/strings.xml
similarity index 100%
rename from v17/leanback/res/values-bn-rBD/strings.xml
rename to v17/leanback/res/values-bn/strings.xml
diff --git a/v17/leanback/res/values-bs-rBA/strings.xml b/v17/leanback/res/values-bs/strings.xml
similarity index 100%
rename from v17/leanback/res/values-bs-rBA/strings.xml
rename to v17/leanback/res/values-bs/strings.xml
diff --git a/v17/leanback/res/values-et-rEE/strings.xml b/v17/leanback/res/values-et/strings.xml
similarity index 100%
rename from v17/leanback/res/values-et-rEE/strings.xml
rename to v17/leanback/res/values-et/strings.xml
diff --git a/v17/leanback/res/values-eu-rES/strings.xml b/v17/leanback/res/values-eu/strings.xml
similarity index 100%
rename from v17/leanback/res/values-eu-rES/strings.xml
rename to v17/leanback/res/values-eu/strings.xml
diff --git a/v17/leanback/res/values-gl-rES/strings.xml b/v17/leanback/res/values-gl/strings.xml
similarity index 100%
rename from v17/leanback/res/values-gl-rES/strings.xml
rename to v17/leanback/res/values-gl/strings.xml
diff --git a/v17/leanback/res/values-gu-rIN/strings.xml b/v17/leanback/res/values-gu/strings.xml
similarity index 100%
rename from v17/leanback/res/values-gu-rIN/strings.xml
rename to v17/leanback/res/values-gu/strings.xml
diff --git a/v17/leanback/res/values-hy-rAM/strings.xml b/v17/leanback/res/values-hy/strings.xml
similarity index 100%
rename from v17/leanback/res/values-hy-rAM/strings.xml
rename to v17/leanback/res/values-hy/strings.xml
diff --git a/v17/leanback/res/values-is-rIS/strings.xml b/v17/leanback/res/values-is/strings.xml
similarity index 100%
rename from v17/leanback/res/values-is-rIS/strings.xml
rename to v17/leanback/res/values-is/strings.xml
diff --git a/v17/leanback/res/values-ka-rGE/strings.xml b/v17/leanback/res/values-ka/strings.xml
similarity index 100%
rename from v17/leanback/res/values-ka-rGE/strings.xml
rename to v17/leanback/res/values-ka/strings.xml
diff --git a/v17/leanback/res/values-kk-rKZ/strings.xml b/v17/leanback/res/values-kk/strings.xml
similarity index 100%
rename from v17/leanback/res/values-kk-rKZ/strings.xml
rename to v17/leanback/res/values-kk/strings.xml
diff --git a/v17/leanback/res/values-km-rKH/strings.xml b/v17/leanback/res/values-km/strings.xml
similarity index 100%
rename from v17/leanback/res/values-km-rKH/strings.xml
rename to v17/leanback/res/values-km/strings.xml
diff --git a/v17/leanback/res/values-kn-rIN/strings.xml b/v17/leanback/res/values-kn/strings.xml
similarity index 100%
rename from v17/leanback/res/values-kn-rIN/strings.xml
rename to v17/leanback/res/values-kn/strings.xml
diff --git a/v17/leanback/res/values-ky-rKG/strings.xml b/v17/leanback/res/values-ky/strings.xml
similarity index 100%
rename from v17/leanback/res/values-ky-rKG/strings.xml
rename to v17/leanback/res/values-ky/strings.xml
diff --git a/v17/leanback/res/values-lo-rLA/strings.xml b/v17/leanback/res/values-lo/strings.xml
similarity index 100%
rename from v17/leanback/res/values-lo-rLA/strings.xml
rename to v17/leanback/res/values-lo/strings.xml
diff --git a/v17/leanback/res/values-mk-rMK/strings.xml b/v17/leanback/res/values-mk/strings.xml
similarity index 100%
rename from v17/leanback/res/values-mk-rMK/strings.xml
rename to v17/leanback/res/values-mk/strings.xml
diff --git a/v17/leanback/res/values-ml-rIN/strings.xml b/v17/leanback/res/values-ml/strings.xml
similarity index 100%
rename from v17/leanback/res/values-ml-rIN/strings.xml
rename to v17/leanback/res/values-ml/strings.xml
diff --git a/v17/leanback/res/values-mn-rMN/strings.xml b/v17/leanback/res/values-mn/strings.xml
similarity index 100%
rename from v17/leanback/res/values-mn-rMN/strings.xml
rename to v17/leanback/res/values-mn/strings.xml
diff --git a/v17/leanback/res/values-mr-rIN/strings.xml b/v17/leanback/res/values-mr/strings.xml
similarity index 100%
rename from v17/leanback/res/values-mr-rIN/strings.xml
rename to v17/leanback/res/values-mr/strings.xml
diff --git a/v17/leanback/res/values-ms-rMY/strings.xml b/v17/leanback/res/values-ms/strings.xml
similarity index 100%
rename from v17/leanback/res/values-ms-rMY/strings.xml
rename to v17/leanback/res/values-ms/strings.xml
diff --git a/v17/leanback/res/values-my-rMM/strings.xml b/v17/leanback/res/values-my/strings.xml
similarity index 100%
rename from v17/leanback/res/values-my-rMM/strings.xml
rename to v17/leanback/res/values-my/strings.xml
diff --git a/v17/leanback/res/values-ne-rNP/strings.xml b/v17/leanback/res/values-ne/strings.xml
similarity index 100%
rename from v17/leanback/res/values-ne-rNP/strings.xml
rename to v17/leanback/res/values-ne/strings.xml
diff --git a/v17/leanback/res/values-pa-rIN/strings.xml b/v17/leanback/res/values-pa/strings.xml
similarity index 100%
rename from v17/leanback/res/values-pa-rIN/strings.xml
rename to v17/leanback/res/values-pa/strings.xml
diff --git a/v17/leanback/res/values-si-rLK/strings.xml b/v17/leanback/res/values-si/strings.xml
similarity index 100%
rename from v17/leanback/res/values-si-rLK/strings.xml
rename to v17/leanback/res/values-si/strings.xml
diff --git a/v17/leanback/res/values-sq-rAL/strings.xml b/v17/leanback/res/values-sq/strings.xml
similarity index 100%
rename from v17/leanback/res/values-sq-rAL/strings.xml
rename to v17/leanback/res/values-sq/strings.xml
diff --git a/v17/leanback/res/values-ta-rIN/strings.xml b/v17/leanback/res/values-ta/strings.xml
similarity index 100%
rename from v17/leanback/res/values-ta-rIN/strings.xml
rename to v17/leanback/res/values-ta/strings.xml
diff --git a/v17/leanback/res/values-te-rIN/strings.xml b/v17/leanback/res/values-te/strings.xml
similarity index 100%
rename from v17/leanback/res/values-te-rIN/strings.xml
rename to v17/leanback/res/values-te/strings.xml
diff --git a/v17/leanback/res/values-ur-rPK/strings.xml b/v17/leanback/res/values-ur/strings.xml
similarity index 100%
rename from v17/leanback/res/values-ur-rPK/strings.xml
rename to v17/leanback/res/values-ur/strings.xml
diff --git a/v17/leanback/res/values-uz-rUZ/strings.xml b/v17/leanback/res/values-uz/strings.xml
similarity index 100%
rename from v17/leanback/res/values-uz-rUZ/strings.xml
rename to v17/leanback/res/values-uz/strings.xml
diff --git a/v17/leanback/res/values/attrs.xml b/v17/leanback/res/values/attrs.xml
index 870d958..26c5ef7 100644
--- a/v17/leanback/res/values/attrs.xml
+++ b/v17/leanback/res/values/attrs.xml
@@ -559,6 +559,10 @@
         <!-- Theme attribute for the style of the logo in onboarding screen. Default is
              {@link android.support.v17.leanback.R.style#Widget_Leanback_OnboardingLogoStyle}.-->
         <attr name="onboardingLogoStyle" format="reference" />
+
+        <!-- Theme attribute for the style of the main icon in onboarding fragment. Default is
+             {@link android.support.v17.leanback.R.style#Widget_Leanback_OnboardingMainIconStyle}.-->
+        <attr name="onboardingMainIconStyle" format="reference" />
     </declare-styleable>
 
     <declare-styleable name="PagingIndicator">
diff --git a/v17/leanback/res/values/integers.xml b/v17/leanback/res/values/integers.xml
index c9f3384..b8bdb18 100644
--- a/v17/leanback/res/values/integers.xml
+++ b/v17/leanback/res/values/integers.xml
@@ -29,6 +29,8 @@
     <integer name="lb_playback_rows_fade_out_ms">250</integer>
     <integer name="lb_playback_rows_fade_delay_ms">100</integer>
     <integer name="lb_playback_controls_show_time_ms">3000</integer>
+    <integer name="lb_onboarding_header_title_delay">33</integer>
+    <integer name="lb_onboarding_header_description_delay">33</integer>
 
     <!-- Gravity.LEFT -->
     <integer name="slideEdgeStart">3</integer>
diff --git a/v17/leanback/res/values/styles.xml b/v17/leanback/res/values/styles.xml
index dbe090a..d10260d 100644
--- a/v17/leanback/res/values/styles.xml
+++ b/v17/leanback/res/values/styles.xml
@@ -778,4 +778,15 @@
         <item name="android:contentDescription">@null</item>
     </style>
 
+    <!-- Styles for the main icon in OnboardingFragment. -->
+    <style name="Widget.Leanback.OnboardingMainIconStyle">
+        <item name="android:layout_width">64dp</item>
+        <item name="android:layout_height">64dp</item>
+        <item name="android:layout_above">@id/page_container</item>
+        <item name="android:layout_centerHorizontal">true</item>
+        <item name="android:layout_marginBottom">16dp</item>
+        <item name="android:contentDescription">@null</item>
+        <item name="android:visibility">gone</item>
+    </style>
+
 </resources>
diff --git a/v17/leanback/res/values/themes.xml b/v17/leanback/res/values/themes.xml
index c6d6baa..e5b98f6 100644
--- a/v17/leanback/res/values/themes.xml
+++ b/v17/leanback/res/values/themes.xml
@@ -213,6 +213,7 @@
         <item name="onboardingPageIndicatorStyle">@style/Widget.Leanback.OnboardingPageIndicatorStyle</item>
         <item name="onboardingStartButtonStyle">@style/Widget.Leanback.OnboardingStartButtonStyle</item>
         <item name="onboardingLogoStyle">@style/Widget.Leanback.OnboardingLogoStyle</item>
+        <item name="onboardingMainIconStyle">@style/Widget.Leanback.OnboardingMainIconStyle</item>
     </style>
 
 </resources>
diff --git a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
index 1baffb4..564c3c7 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
@@ -53,8 +53,8 @@
  * <p>
  * <h3>Building the screen</h3>
  * The view structure of onboarding screen is composed of the common parts and custom parts. The
- * common parts are composed of title, description and page navigator and the custom parts are
- * composed of background, contents and foreground.
+ * common parts are composed of icon, title, description and page navigator and the custom parts
+ * are composed of background, contents and foreground.
  * <p>
  * To build the screen views, the inherited class should override:
  * <ul>
@@ -102,8 +102,12 @@
  * If the inherited class provides neither the logo image nor the animation, the logo animation will
  * be omitted.
  * <h4>Page enter animation</h4>
- * After logo animation finishes, page enter animation starts. The application can provide the
- * animations of custom views by overriding {@link #onCreateEnterAnimation}.
+ * After logo animation finishes, page enter animation starts, which causes the header section -
+ * title and description views to fade and slide in. Users can override the default
+ * fade + slide animation by overriding {@link #onCreateTitleAnimator()} &
+ * {@link #onCreateDescriptionAnimator()}. By default we don't animate the custom views but users
+ * can provide animation by overriding {@link #onCreateEnterAnimation}.
+ *
  * <h4>Page change animation</h4>
  * When the page changes, the default animations of the title and description are played. The
  * inherited class can override {@link #onPageChanged} to start the custom animations.
@@ -149,8 +153,6 @@
     private static final boolean DEBUG = false;
 
     private static final long LOGO_SPLASH_PAUSE_DURATION_MS = 1333;
-    private static final long START_DELAY_TITLE_MS = 33;
-    private static final long START_DELAY_DESCRIPTION_MS = 33;
 
     private static final long HEADER_ANIMATION_DURATION_MS = 417;
     private static final long DESCRIPTION_START_DELAY_MS = 33;
@@ -171,6 +173,10 @@
     PagingIndicator mPageIndicator;
     View mStartButton;
     private ImageView mLogoView;
+    // Optional icon that can be displayed on top of the header section.
+    private ImageView mMainIconView;
+    private int mIconResourceId;
+
     TextView mTitleView;
     TextView mDescriptionView;
 
@@ -264,6 +270,7 @@
         mStartButton = view.findViewById(R.id.button_start);
         mStartButton.setOnClickListener(mOnClickListener);
         mStartButton.setOnKeyListener(mOnKeyListener);
+        mMainIconView = (ImageView) view.findViewById(R.id.main_icon);
         mLogoView = (ImageView) view.findViewById(R.id.logo);
         mTitleView = (TextView) view.findViewById(R.id.title);
         mDescriptionView = (TextView) view.findViewById(R.id.description);
@@ -412,6 +419,12 @@
 
     private void initializeViews(View container) {
         mLogoView.setVisibility(View.GONE);
+
+        if (mIconResourceId != 0) {
+            mMainIconView.setImageResource(mIconResourceId);
+            mMainIconView.setVisibility(View.VISIBLE);
+        }
+
         // Create custom views.
         LayoutInflater inflater = getThemeInflater(LayoutInflater.from(
                 FragmentUtil.getContext(this)));
@@ -461,27 +474,31 @@
                 R.animator.lb_onboarding_page_indicator_enter);
         animator.setTarget(getPageCount() <= 1 ? mStartButton : mPageIndicator);
         animators.add(animator);
-        // Header title
-        View view = getView().findViewById(R.id.title);
-        view.setAlpha(0);
-        animator = AnimatorInflater.loadAnimator(context,
-                R.animator.lb_onboarding_title_enter);
-        animator.setStartDelay(START_DELAY_TITLE_MS);
-        animator.setTarget(view);
-        animators.add(animator);
-        // Header description
-        view = getView().findViewById(R.id.description);
-        view.setAlpha(0);
-        animator = AnimatorInflater.loadAnimator(context,
-                R.animator.lb_onboarding_description_enter);
-        animator.setStartDelay(START_DELAY_DESCRIPTION_MS);
-        animator.setTarget(view);
-        animators.add(animator);
+
+        animator = onCreateTitleAnimator();
+        if (animator != null) {
+            // Header title.
+            animator.setTarget(mTitleView);
+            animators.add(animator);
+        }
+
+        animator = onCreateDescriptionAnimator();
+        if (animator != null) {
+            // Header description.
+            animator.setTarget(mDescriptionView);
+            animators.add(animator);
+        }
+
         // Customized animation by the inherited class.
         Animator customAnimator = onCreateEnterAnimation();
         if (customAnimator != null) {
             animators.add(customAnimator);
         }
+
+        // Return if we don't have any animations.
+        if (animators.isEmpty()) {
+            return;
+        }
         mAnimator = new AnimatorSet();
         mAnimator.playTogether(animators);
         mAnimator.start();
@@ -490,6 +507,24 @@
     }
 
     /**
+     * Provides the entry animation for description view. This allows users to override the
+     * default fade and slide animation. Returning null will disable the animation.
+     */
+    protected Animator onCreateDescriptionAnimator() {
+        return AnimatorInflater.loadAnimator(FragmentUtil.getContext(this),
+                R.animator.lb_onboarding_description_enter);
+    }
+
+    /**
+     * Provides the entry animation for title view. This allows users to override the
+     * default fade and slide animation. Returning null will disable the animation.
+     */
+    protected Animator onCreateTitleAnimator() {
+        return AnimatorInflater.loadAnimator(FragmentUtil.getContext(this),
+                R.animator.lb_onboarding_title_enter);
+    }
+
+    /**
      * Returns the page count.
      *
      * @return The page count.
@@ -695,4 +730,22 @@
         }
         return animator;
     }
+
+    /**
+     * Sets the resource id for the main icon.
+     */
+    public final void setIconResouceId(int resourceId) {
+        this.mIconResourceId = resourceId;
+        if (mMainIconView != null) {
+            mMainIconView.setImageResource(resourceId);
+            mMainIconView.setVisibility(View.VISIBLE);
+        }
+    }
+
+    /**
+     * Returns the resource id of the main icon.
+     */
+    public final int getIconResourceId() {
+        return mIconResourceId;
+    }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
index 8523a27..5df8f41 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
@@ -56,8 +56,8 @@
  * <p>
  * <h3>Building the screen</h3>
  * The view structure of onboarding screen is composed of the common parts and custom parts. The
- * common parts are composed of title, description and page navigator and the custom parts are
- * composed of background, contents and foreground.
+ * common parts are composed of icon, title, description and page navigator and the custom parts
+ * are composed of background, contents and foreground.
  * <p>
  * To build the screen views, the inherited class should override:
  * <ul>
@@ -105,8 +105,12 @@
  * If the inherited class provides neither the logo image nor the animation, the logo animation will
  * be omitted.
  * <h4>Page enter animation</h4>
- * After logo animation finishes, page enter animation starts. The application can provide the
- * animations of custom views by overriding {@link #onCreateEnterAnimation}.
+ * After logo animation finishes, page enter animation starts, which causes the header section -
+ * title and description views to fade and slide in. Users can override the default
+ * fade + slide animation by overriding {@link #onCreateTitleAnimator()} &
+ * {@link #onCreateDescriptionAnimator()}. By default we don't animate the custom views but users
+ * can provide animation by overriding {@link #onCreateEnterAnimation}.
+ *
  * <h4>Page change animation</h4>
  * When the page changes, the default animations of the title and description are played. The
  * inherited class can override {@link #onPageChanged} to start the custom animations.
@@ -152,8 +156,6 @@
     private static final boolean DEBUG = false;
 
     private static final long LOGO_SPLASH_PAUSE_DURATION_MS = 1333;
-    private static final long START_DELAY_TITLE_MS = 33;
-    private static final long START_DELAY_DESCRIPTION_MS = 33;
 
     private static final long HEADER_ANIMATION_DURATION_MS = 417;
     private static final long DESCRIPTION_START_DELAY_MS = 33;
@@ -174,6 +176,10 @@
     PagingIndicator mPageIndicator;
     View mStartButton;
     private ImageView mLogoView;
+    // Optional icon that can be displayed on top of the header section.
+    private ImageView mMainIconView;
+    private int mIconResourceId;
+
     TextView mTitleView;
     TextView mDescriptionView;
 
@@ -267,6 +273,7 @@
         mStartButton = view.findViewById(R.id.button_start);
         mStartButton.setOnClickListener(mOnClickListener);
         mStartButton.setOnKeyListener(mOnKeyListener);
+        mMainIconView = (ImageView) view.findViewById(R.id.main_icon);
         mLogoView = (ImageView) view.findViewById(R.id.logo);
         mTitleView = (TextView) view.findViewById(R.id.title);
         mDescriptionView = (TextView) view.findViewById(R.id.description);
@@ -415,6 +422,12 @@
 
     private void initializeViews(View container) {
         mLogoView.setVisibility(View.GONE);
+
+        if (mIconResourceId != 0) {
+            mMainIconView.setImageResource(mIconResourceId);
+            mMainIconView.setVisibility(View.VISIBLE);
+        }
+
         // Create custom views.
         LayoutInflater inflater = getThemeInflater(LayoutInflater.from(
                 getContext()));
@@ -464,27 +477,31 @@
                 R.animator.lb_onboarding_page_indicator_enter);
         animator.setTarget(getPageCount() <= 1 ? mStartButton : mPageIndicator);
         animators.add(animator);
-        // Header title
-        View view = getView().findViewById(R.id.title);
-        view.setAlpha(0);
-        animator = AnimatorInflater.loadAnimator(context,
-                R.animator.lb_onboarding_title_enter);
-        animator.setStartDelay(START_DELAY_TITLE_MS);
-        animator.setTarget(view);
-        animators.add(animator);
-        // Header description
-        view = getView().findViewById(R.id.description);
-        view.setAlpha(0);
-        animator = AnimatorInflater.loadAnimator(context,
-                R.animator.lb_onboarding_description_enter);
-        animator.setStartDelay(START_DELAY_DESCRIPTION_MS);
-        animator.setTarget(view);
-        animators.add(animator);
+
+        animator = onCreateTitleAnimator();
+        if (animator != null) {
+            // Header title.
+            animator.setTarget(mTitleView);
+            animators.add(animator);
+        }
+
+        animator = onCreateDescriptionAnimator();
+        if (animator != null) {
+            // Header description.
+            animator.setTarget(mDescriptionView);
+            animators.add(animator);
+        }
+
         // Customized animation by the inherited class.
         Animator customAnimator = onCreateEnterAnimation();
         if (customAnimator != null) {
             animators.add(customAnimator);
         }
+
+        // Return if we don't have any animations.
+        if (animators.isEmpty()) {
+            return;
+        }
         mAnimator = new AnimatorSet();
         mAnimator.playTogether(animators);
         mAnimator.start();
@@ -493,6 +510,24 @@
     }
 
     /**
+     * Provides the entry animation for description view. This allows users to override the
+     * default fade and slide animation. Returning null will disable the animation.
+     */
+    protected Animator onCreateDescriptionAnimator() {
+        return AnimatorInflater.loadAnimator(getContext(),
+                R.animator.lb_onboarding_description_enter);
+    }
+
+    /**
+     * Provides the entry animation for title view. This allows users to override the
+     * default fade and slide animation. Returning null will disable the animation.
+     */
+    protected Animator onCreateTitleAnimator() {
+        return AnimatorInflater.loadAnimator(getContext(),
+                R.animator.lb_onboarding_title_enter);
+    }
+
+    /**
      * Returns the page count.
      *
      * @return The page count.
@@ -698,4 +733,22 @@
         }
         return animator;
     }
+
+    /**
+     * Sets the resource id for the main icon.
+     */
+    public final void setIconResouceId(int resourceId) {
+        this.mIconResourceId = resourceId;
+        if (mMainIconView != null) {
+            mMainIconView.setImageResource(resourceId);
+            mMainIconView.setVisibility(View.VISIBLE);
+        }
+    }
+
+    /**
+     * Returns the resource id of the main icon.
+     */
+    public final int getIconResourceId() {
+        return mIconResourceId;
+    }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java b/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java
index 9341314..e8f7a21 100644
--- a/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java
+++ b/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java
@@ -15,7 +15,6 @@
  */
 package android.support.v17.leanback.graphics;
 
-import android.annotation.TargetApi;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
@@ -240,7 +239,6 @@
      * Wrapper class holding a drawable object and {@link BoundsRule} to update drawable bounds
      * when parent bound changes.
      */
-    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     public static final class ChildDrawable {
         private final BoundsRule mBoundsRule;
         private final Drawable mDrawable;
diff --git a/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java b/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java
index 25be4c6..dfba1c0 100644
--- a/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java
+++ b/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java
@@ -20,7 +20,6 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
@@ -43,7 +42,6 @@
  * @hide
  */
 @RequiresApi(21)
-@TargetApi(21)
 @RestrictTo(LIBRARY_GROUP)
 public class ParallaxTransition extends Visibility {
 
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
index a2f99e2..9290c35 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
@@ -1334,7 +1334,7 @@
             if (DEBUG) Log.v(getTag(), "request Layout from runnable");
             requestLayout();
         }
-     };
+    };
 
     @Override
     public void onMeasure(Recycler recycler, State state, int widthSpec, int heightSpec) {
@@ -1374,18 +1374,18 @@
             processRowSizeSecondary(true);
 
             switch (modeSecondary) {
-            case MeasureSpec.UNSPECIFIED:
-                measuredSizeSecondary = getSizeSecondary() + paddingSecondary;
-                break;
-            case MeasureSpec.AT_MOST:
-                measuredSizeSecondary = Math.min(getSizeSecondary() + paddingSecondary,
-                        mMaxSizeSecondary);
-                break;
-            case MeasureSpec.EXACTLY:
-                measuredSizeSecondary = mMaxSizeSecondary;
-                break;
-            default:
-                throw new IllegalStateException("wrong spec");
+                case MeasureSpec.UNSPECIFIED:
+                    measuredSizeSecondary = getSizeSecondary() + paddingSecondary;
+                    break;
+                case MeasureSpec.AT_MOST:
+                    measuredSizeSecondary = Math.min(getSizeSecondary() + paddingSecondary,
+                            mMaxSizeSecondary);
+                    break;
+                case MeasureSpec.EXACTLY:
+                    measuredSizeSecondary = mMaxSizeSecondary;
+                    break;
+                default:
+                    throw new IllegalStateException("wrong spec");
             }
 
         } else {
@@ -1395,7 +1395,7 @@
                             ? sizeSecondary - paddingSecondary : mRowSizeSecondaryRequested;
                     mNumRows = mNumRowsRequested == 0 ? 1 : mNumRowsRequested;
                     measuredSizeSecondary = mFixedRowSizeSecondary * mNumRows + mSpacingSecondary
-                        * (mNumRows - 1) + paddingSecondary;
+                            * (mNumRows - 1) + paddingSecondary;
                     break;
                 case MeasureSpec.AT_MOST:
                 case MeasureSpec.EXACTLY:
@@ -1405,7 +1405,7 @@
                     } else if (mNumRowsRequested == 0) {
                         mFixedRowSizeSecondary = mRowSizeSecondaryRequested;
                         mNumRows = (sizeSecondary + mSpacingSecondary)
-                            / (mRowSizeSecondaryRequested + mSpacingSecondary);
+                                / (mRowSizeSecondaryRequested + mSpacingSecondary);
                     } else if (mRowSizeSecondaryRequested == 0) {
                         mNumRows = mNumRowsRequested;
                         mFixedRowSizeSecondary = (sizeSecondary - paddingSecondary
@@ -1646,7 +1646,7 @@
         final int verticalGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
         final int horizontalGravity = (mReverseFlowPrimary || mReverseFlowSecondary)
                 ? Gravity.getAbsoluteGravity(mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK,
-                        View.LAYOUT_DIRECTION_RTL)
+                View.LAYOUT_DIRECTION_RTL)
                 : mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
         if (mOrientation == HORIZONTAL && verticalGravity == Gravity.TOP
                 || mOrientation == VERTICAL && horizontalGravity == Gravity.LEFT) {
@@ -2442,7 +2442,7 @@
         if (DEBUG) Log.v(getTag(), "onItemsRemoved positionStart "
                 + positionStart + " itemCount " + itemCount);
         if (mFocusPosition != NO_POSITION  && mGrid != null && mGrid.getFirstVisibleIndex() >= 0
-            && mFocusPositionOffset != Integer.MIN_VALUE) {
+                && mFocusPositionOffset != Integer.MIN_VALUE) {
             int pos = mFocusPosition + mFocusPositionOffset;
             if (positionStart <= pos) {
                 if (positionStart + itemCount > pos) {
@@ -2638,12 +2638,12 @@
 
     boolean getScrollPosition(View view, View childView, int[] deltas) {
         switch (mFocusScrollStrategy) {
-        case BaseGridView.FOCUS_SCROLL_ALIGNED:
-        default:
-            return getAlignedPosition(view, childView, deltas);
-        case BaseGridView.FOCUS_SCROLL_ITEM:
-        case BaseGridView.FOCUS_SCROLL_PAGE:
-            return getNoneAlignedPosition(view, deltas);
+            case BaseGridView.FOCUS_SCROLL_ALIGNED:
+            default:
+                return getAlignedPosition(view, childView, deltas);
+            case BaseGridView.FOCUS_SCROLL_ITEM:
+            case BaseGridView.FOCUS_SCROLL_PAGE:
+                return getNoneAlignedPosition(view, deltas);
         }
     }
 
@@ -3079,14 +3079,14 @@
     boolean gridOnRequestFocusInDescendants(RecyclerView recyclerView, int direction,
             Rect previouslyFocusedRect) {
         switch (mFocusScrollStrategy) {
-        case BaseGridView.FOCUS_SCROLL_ALIGNED:
-        default:
-            return gridOnRequestFocusInDescendantsAligned(recyclerView,
-                    direction, previouslyFocusedRect);
-        case BaseGridView.FOCUS_SCROLL_PAGE:
-        case BaseGridView.FOCUS_SCROLL_ITEM:
-            return gridOnRequestFocusInDescendantsUnaligned(recyclerView,
-                    direction, previouslyFocusedRect);
+            case BaseGridView.FOCUS_SCROLL_ALIGNED:
+            default:
+                return gridOnRequestFocusInDescendantsAligned(recyclerView,
+                        direction, previouslyFocusedRect);
+            case BaseGridView.FOCUS_SCROLL_PAGE:
+            case BaseGridView.FOCUS_SCROLL_ITEM:
+                return gridOnRequestFocusInDescendantsUnaligned(recyclerView,
+                        direction, previouslyFocusedRect);
         }
     }
 
@@ -3157,22 +3157,22 @@
                     movement = NEXT_ROW;
                     break;
             }
-         } else if (mOrientation == VERTICAL) {
-             switch(direction) {
-                 case View.FOCUS_LEFT:
-                     movement = (!mReverseFlowSecondary) ? PREV_ROW : NEXT_ROW;
-                     break;
-                 case View.FOCUS_RIGHT:
-                     movement = (!mReverseFlowSecondary) ? NEXT_ROW : PREV_ROW;
-                     break;
-                 case View.FOCUS_UP:
-                     movement = PREV_ITEM;
-                     break;
-                 case View.FOCUS_DOWN:
-                     movement = NEXT_ITEM;
-                     break;
-             }
-         }
+        } else if (mOrientation == VERTICAL) {
+            switch(direction) {
+                case View.FOCUS_LEFT:
+                    movement = (!mReverseFlowSecondary) ? PREV_ROW : NEXT_ROW;
+                    break;
+                case View.FOCUS_RIGHT:
+                    movement = (!mReverseFlowSecondary) ? NEXT_ROW : PREV_ROW;
+                    break;
+                case View.FOCUS_UP:
+                    movement = PREV_ITEM;
+                    break;
+                case View.FOCUS_DOWN:
+                    movement = NEXT_ITEM;
+                    break;
+            }
+        }
 
         return movement;
     }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BackgroundManagerTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BackgroundManagerTest.java
index 3ccfbf7..1c22d52 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BackgroundManagerTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BackgroundManagerTest.java
@@ -29,7 +29,7 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v17.leanback.testutils.PollingCheck;
 
@@ -38,10 +38,7 @@
 import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
 
-/**
- * @hide from javadoc
- */
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class BackgroundManagerTest {
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
index 07e2d5e..3a53ddc 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
@@ -22,6 +22,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.support.test.filters.MediumTest;
+import android.support.test.filters.Suppress;
 import android.support.test.rule.ActivityTestRule;
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
@@ -47,6 +48,7 @@
             new ActivityTestRule<>(DetailsFragmentTestActivity.class, false, false);
     private DetailsFragmentTestActivity mActivity;
 
+    @Suppress // Disabled due to flakiness.
     @Test
     public void parallaxTest() throws Throwable {
         final int mDefaultVerticalOffset = -300;
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsParallaxTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsParallaxTest.java
index 367e888..2760e4c 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsParallaxTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsParallaxTest.java
@@ -17,7 +17,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.support.test.filters.SmallTest;
+import android.support.test.filters.MediumTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.v17.leanback.widget.DetailsParallax;
 import android.support.v17.leanback.widget.RecyclerViewParallax;
@@ -32,7 +32,7 @@
  * Unit tests for {@link DetailsParallax}.
  */
 @RunWith(JUnit4.class)
-@SmallTest
+@MediumTest
 public class DetailsParallaxTest {
 
     @Rule
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/GuidedStepFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/GuidedStepFragmentTest.java
index 50aaa62..80ca4eb 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/GuidedStepFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/GuidedStepFragmentTest.java
@@ -25,7 +25,7 @@
 import static org.mockito.Mockito.verify;
 
 import android.os.Bundle;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v17.leanback.testutils.PollingCheck;
 import android.support.v17.leanback.widget.GuidedAction;
@@ -44,10 +44,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * @hide from javadoc
- */
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class GuidedStepFragmentTest extends GuidedStepFragmentTestBase {
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/GuidedStepSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/GuidedStepSupportFragmentTest.java
index 7d6b54f..880236e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/GuidedStepSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/GuidedStepSupportFragmentTest.java
@@ -28,7 +28,7 @@
 import static org.mockito.Mockito.verify;
 
 import android.os.Bundle;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v17.leanback.testutils.PollingCheck;
 import android.support.v17.leanback.widget.GuidedAction;
@@ -47,10 +47,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * @hide from javadoc
- */
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class GuidedStepSupportFragmentTest extends GuidedStepSupportFragmentTestBase {
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/ListRowDataAdapterTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/ListRowDataAdapterTest.java
index 0b40920..c118b4e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/ListRowDataAdapterTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/ListRowDataAdapterTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.support.test.filters.MediumTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
@@ -44,7 +45,6 @@
  * Unit test for {@link ListRowDataAdapter} class.
  */
 @RunWith(AndroidJUnit4.class)
-@SmallTest
 public class ListRowDataAdapterTest {
     @Mock
     private PresenterSelector presenterSelector;
@@ -56,6 +56,7 @@
         MockitoAnnotations.initMocks(this);
     }
 
+    @SmallTest
     @Test
     public void itemRangeChangedTest() {
         int itemCount = 4;
@@ -75,6 +76,7 @@
         assertEquals(5, listRowDataAdapter.size());
     }
 
+    @SmallTest
     @Test
     public void adapterSize_nonVisibleRowPresent() {
         int itemCount = 4;
@@ -96,6 +98,7 @@
         assertEquals(5, listRowDataAdapter.size());
     }
 
+    @SmallTest
     @Test
     public void adapterSize_visibleRowInserted() {
         int itemCount = 4;
@@ -119,6 +122,7 @@
         assertEquals(8, listRowDataAdapter.size());
     }
 
+    @SmallTest
     @Test
     public void adapterSize_nonVisibleRowInserted() {
         int itemCount = 4;
@@ -150,6 +154,7 @@
         assertEquals(9, listRowDataAdapter.size());
     }
 
+    @SmallTest
     @Test
     public void adapterSize_visibleRowRemoved() {
         int itemCount = 4;
@@ -171,6 +176,7 @@
         assertEquals(3, listRowDataAdapter.size());
     }
 
+    @MediumTest
     @Test
     public void adapterSize_nonVisibleRowRemoved() {
         int itemCount = 4;
@@ -196,6 +202,7 @@
         assertEquals(4, listRowDataAdapter.size());
     }
 
+    @SmallTest
     @Test
     public void adapterSize_rowsRemoveAll() {
         ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector);
@@ -216,6 +223,7 @@
         assertEquals(1, listRowDataAdapter.size());
     }
 
+    @SmallTest
     @Test
     public void changeRemove_revealInvisibleItems() {
         ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector);
@@ -238,6 +246,7 @@
         assertEquals(4, listRowDataAdapter.size());
     }
 
+    @SmallTest
     @Test
     public void adapterSize_rowsRemoved() {
         int itemCount = 4;
@@ -260,6 +269,7 @@
         assertEquals(3, listRowDataAdapter.size());
     }
 
+    @SmallTest
     @Test
     public void customObjectAdapterTest() {
         int itemCount = 4;
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedDatePickerTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedDatePickerTest.java
index ce11551..7d878fe 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedDatePickerTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedDatePickerTest.java
@@ -20,7 +20,7 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v17.leanback.app.GuidedStepFragment;
@@ -45,7 +45,7 @@
 import java.util.Date;
 import java.util.List;
 
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class GuidedDatePickerTest {
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTest.java
index 0283687..9575d39 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTest.java
@@ -20,7 +20,7 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v17.leanback.app.GuidedStepFragment;
@@ -39,7 +39,7 @@
 import java.util.Collections;
 import java.util.List;
 
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class GuidedStepAttributesTest {
     static final long TRANSITION_LENGTH = 1000;
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/graphics/FitWidthBitmapDrawableTest.java b/v17/leanback/tests/java/android/support/v17/leanback/graphics/FitWidthBitmapDrawableTest.java
index a91c221..fb68a51 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/graphics/FitWidthBitmapDrawableTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/graphics/FitWidthBitmapDrawableTest.java
@@ -25,6 +25,7 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.os.Build;
+import android.support.test.filters.MediumTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -37,7 +38,6 @@
  * Unit test for {@link FitWidthBitmapDrawable}
  */
 @RunWith(AndroidJUnit4.class)
-@SmallTest
 public class FitWidthBitmapDrawableTest {
     private final static int SCREEN_WIDTH = 1600;
     private final static int SCREEN_HEIGHT = 1080;
@@ -45,6 +45,7 @@
     private final static int HEIGHT = 600;
     private Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888);
 
+    @MediumTest
     @Test
     public void draw_withOffset() {
         int offset = 600;
@@ -66,6 +67,7 @@
         verify(canvas).drawBitmap(eq(bitmap), eq(bitmapBounds), eq(expectedDest), any(Paint.class));
     }
 
+    @SmallTest
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     @Test
     public void constantState() {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
index 8a38894..dc93f1d 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
-
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.timeout;
@@ -35,7 +34,7 @@
 import android.os.Build;
 import android.os.Parcelable;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
@@ -63,7 +62,7 @@
 import java.util.Comparator;
 import java.util.HashMap;
 
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class GridWidgetTest {
 
diff --git a/v17/leanback/tests/res/layout/vertical_linear_with_button_onleft.xml b/v17/leanback/tests/res/layout/vertical_linear_with_button_onleft.xml
index 02b027c..374dc47 100644
--- a/v17/leanback/tests/res/layout/vertical_linear_with_button_onleft.xml
+++ b/v17/leanback/tests/res/layout/vertical_linear_with_button_onleft.xml
@@ -20,7 +20,7 @@
       android:focusable="true"
       android:focusableInTouchMode="true"
       android:background="#00ffff"
-      android_horizontalSpacing="12dip"
+      android:horizontalSpacing="12dip"
       android:verticalSpacing="4dip"
       lb:numberOfColumns="1"
       android:paddingBottom="12dip"
diff --git a/v17/preference-leanback/Android.mk b/v17/preference-leanback/Android.mk
index 8c0488f..263d334 100644
--- a/v17/preference-leanback/Android.mk
+++ b/v17/preference-leanback/Android.mk
@@ -35,7 +35,6 @@
     $(call all-java-files-under,api21) \
     $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-v17-leanback \
     android-support-v14-preference \
diff --git a/v17/preference-leanback/api21/android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout.java b/v17/preference-leanback/api21/android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout.java
index 893af77..0396469 100644
--- a/v17/preference-leanback/api21/android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout.java
+++ b/v17/preference-leanback/api21/android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Outline;
 import android.support.annotation.RequiresApi;
@@ -35,7 +34,6 @@
  * @hide
  */
 @RequiresApi(21)
-@TargetApi(21)
 @RestrictTo(LIBRARY_GROUP)
 public class OutlineOnlyWithChildrenFrameLayout extends FrameLayout {
 
diff --git a/v17/preference-leanback/api21/android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21.java b/v17/preference-leanback/api21/android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21.java
index e258686..955ab9e 100644
--- a/v17/preference-leanback/api21/android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21.java
+++ b/v17/preference-leanback/api21/android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
@@ -30,7 +29,6 @@
  * @hide
  */
 @RequiresApi(21)
-@TargetApi(21)
 @RestrictTo(LIBRARY_GROUP)
 public class LeanbackPreferenceFragmentTransitionHelperApi21 {
 
diff --git a/v17/preference-leanback/build.gradle b/v17/preference-leanback/build.gradle
index e58fa8b..8de4c00 100644
--- a/v17/preference-leanback/build.gradle
+++ b/v17/preference-leanback/build.gradle
@@ -1,4 +1,4 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'preference-leanback-v17'
 
 dependencies {
@@ -11,69 +11,21 @@
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
+    defaultConfig {
+        minSdkVersion 17
+    }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'api21',
                 'src'
         ]
         main.res.srcDir 'res'
     }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Leanback Preference v17'
-                description "Android Support Leanback Preference v17"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2015'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
-}
+supportLibrary {
+    name 'Android Support Leanback Preference v17'
+    inceptionYear '2015'
+    description 'Android Support Leanback Preference v17'
+}
\ No newline at end of file
diff --git a/v17/preference-leanback/res/layout/leanback_list_preference_fragment.xml b/v17/preference-leanback/res/layout/leanback_list_preference_fragment.xml
index f073f3e..ab299de 100644
--- a/v17/preference-leanback/res/layout/leanback_list_preference_fragment.xml
+++ b/v17/preference-leanback/res/layout/leanback_list_preference_fragment.xml
@@ -59,8 +59,10 @@
         android:paddingEnd="56dp"
         android:visibility="gone" />
 
-    <android.support.v17.leanback.widget.VerticalGridView android:id="@android:id/list"
+    <android.support.v17.leanback.widget.VerticalGridView
+        android:id="@android:id/list"
         android:layout_width="match_parent"
-        android:layout_height="match_parent" />
+        android:layout_height="match_parent"
+        android:transitionGroup="true"/>
 
 </LinearLayout>
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java
index 2273fb6..6ab3999 100644
--- a/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java
@@ -25,19 +25,41 @@
 import android.support.v7.preference.ListPreference;
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Checkable;
 import android.widget.TextView;
 
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
 public class LeanbackListPreferenceDialogFragment extends LeanbackPreferenceDialogFragment {
 
+    private static final String SAVE_STATE_IS_MULTI =
+            "LeanbackListPreferenceDialogFragment.isMulti";
+    private static final String SAVE_STATE_ENTRIES = "LeanbackListPreferenceDialogFragment.entries";
+    private static final String SAVE_STATE_ENTRY_VALUES =
+            "LeanbackListPreferenceDialogFragment.entryValues";
+    private static final String SAVE_STATE_TITLE = "LeanbackListPreferenceDialogFragment.title";
+    private static final String SAVE_STATE_MESSAGE = "LeanbackListPreferenceDialogFragment.message";
+    private static final String SAVE_STATE_INITIAL_SELECTIONS =
+            "LeanbackListPreferenceDialogFragment.initialSelections";
+    private static final String SAVE_STATE_INITIAL_SELECTION =
+            "LeanbackListPreferenceDialogFragment.initialSelection";
+
+    private boolean mMulti;
+    private CharSequence[] mEntries;
+    private CharSequence[] mEntryValues;
+    private CharSequence mDialogTitle;
+    private CharSequence mDialogMessage;
+    private Set<String> mInitialSelections;
+    private String mInitialSelection;
+
     public static LeanbackListPreferenceDialogFragment newInstanceSingle(String key) {
-        final Bundle args = new Bundle(5);
+        final Bundle args = new Bundle(1);
         args.putString(ARG_KEY, key);
 
         final LeanbackListPreferenceDialogFragment
@@ -48,7 +70,7 @@
     }
 
     public static LeanbackListPreferenceDialogFragment newInstanceMulti(String key) {
-        final Bundle args = new Bundle(5);
+        final Bundle args = new Bundle(1);
         args.putString(ARG_KEY, key);
 
         final LeanbackListPreferenceDialogFragment
@@ -62,11 +84,58 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        final DialogPreference preference = getPreference();
-        if (!(preference instanceof ListPreference) &&
-                !(preference instanceof MultiSelectListPreference)) {
-            throw new IllegalArgumentException("Preference must be a ListPreference or " +
-                    "MultiSelectListPreference");
+        if (savedInstanceState == null) {
+            final DialogPreference preference = getPreference();
+            mDialogTitle = preference.getDialogTitle();
+            mDialogMessage = preference.getDialogMessage();
+
+            if (preference instanceof ListPreference) {
+                mMulti = false;
+                mEntries = ((ListPreference) preference).getEntries();
+                mEntryValues = ((ListPreference) preference).getEntryValues();
+                mInitialSelection = ((ListPreference) preference).getValue();
+            } else if (preference instanceof MultiSelectListPreference) {
+                mMulti = true;
+                mEntries = ((MultiSelectListPreference) preference).getEntries();
+                mEntryValues = ((MultiSelectListPreference) preference).getEntryValues();
+                mInitialSelections = ((MultiSelectListPreference) preference).getValues();
+            } else {
+                throw new IllegalArgumentException("Preference must be a ListPreference or "
+                        + "MultiSelectListPreference");
+            }
+        } else {
+            mDialogTitle = savedInstanceState.getCharSequence(SAVE_STATE_TITLE);
+            mDialogMessage = savedInstanceState.getCharSequence(SAVE_STATE_MESSAGE);
+            mMulti = savedInstanceState.getBoolean(SAVE_STATE_IS_MULTI);
+            mEntries = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRIES);
+            mEntryValues = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
+            if (mMulti) {
+                final String[] initialSelections = savedInstanceState.getStringArray(
+                        SAVE_STATE_INITIAL_SELECTIONS);
+                mInitialSelections = new ArraySet<>(
+                        initialSelections != null ? initialSelections.length : 0);
+                if (initialSelections != null) {
+                    Collections.addAll(mInitialSelections, initialSelections);
+                }
+            } else {
+                mInitialSelection = savedInstanceState.getString(SAVE_STATE_INITIAL_SELECTION);
+            }
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putCharSequence(SAVE_STATE_TITLE, mDialogTitle);
+        outState.putCharSequence(SAVE_STATE_MESSAGE, mDialogMessage);
+        outState.putBoolean(SAVE_STATE_IS_MULTI, mMulti);
+        outState.putCharSequenceArray(SAVE_STATE_ENTRIES, mEntries);
+        outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
+        if (mMulti) {
+            outState.putStringArray(SAVE_STATE_INITIAL_SELECTIONS,
+                    mInitialSelections.toArray(new String[mInitialSelections.size()]));
+        } else {
+            outState.putString(SAVE_STATE_INITIAL_SELECTION, mInitialSelection);
         }
     }
 
@@ -83,14 +152,13 @@
         verticalGridView.setAdapter(onCreateAdapter());
         verticalGridView.requestFocus();
 
-        final DialogPreference preference = getPreference();
-        final CharSequence title = preference.getDialogTitle();
+        final CharSequence title = mDialogTitle;
         if (!TextUtils.isEmpty(title)) {
             final TextView titleView = (TextView) view.findViewById(R.id.decor_title);
             titleView.setText(title);
         }
 
-        final CharSequence message = preference.getDialogMessage();
+        final CharSequence message = mDialogMessage;
         if (!TextUtils.isEmpty(message)) {
             final TextView messageView = (TextView) view.findViewById(android.R.id.message);
             messageView.setVisibility(View.VISIBLE);
@@ -101,21 +169,11 @@
     }
 
     public RecyclerView.Adapter onCreateAdapter() {
-        final DialogPreference preference = getPreference();
-        if (preference instanceof MultiSelectListPreference) {
-            final MultiSelectListPreference pref = (MultiSelectListPreference) preference;
-            final CharSequence[] entries = pref.getEntries();
-            final CharSequence[] entryValues = pref.getEntryValues();
-            final Set<String> initialSelections = pref.getValues();
-            return new AdapterMulti(entries, entryValues, initialSelections);
-        } else if (preference instanceof ListPreference) {
-            final ListPreference pref = (ListPreference) preference;
-            final CharSequence[] entries = pref.getEntries();
-            final CharSequence[] entryValues = pref.getEntryValues();
-            final String initialSelection = pref.getValue();
-            return new AdapterSingle(entries, entryValues, initialSelection);
+        //final DialogPreference preference = getPreference();
+        if (mMulti) {
+            return new AdapterMulti(mEntries, mEntryValues, mInitialSelections);
         } else {
-            throw new IllegalStateException("Unknown preference type");
+            return new AdapterSingle(mEntries, mEntryValues, mInitialSelection);
         }
     }
 
@@ -224,6 +282,7 @@
             // Pass copies of the set to callChangeListener and setValues to avoid mutations
             if (multiSelectListPreference.callChangeListener(new HashSet<>(mSelections))) {
                 multiSelectListPreference.setValues(new HashSet<>(mSelections));
+                mInitialSelections = mSelections;
             } else {
                 // Change refused, back it out
                 if (mSelections.contains(entry)) {
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceDialogFragment.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceDialogFragment.java
index 614bc32..20b36ca 100644
--- a/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceDialogFragment.java
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackPreferenceDialogFragment.java
@@ -42,15 +42,15 @@
             throw new IllegalStateException("Target fragment must implement TargetFragment" +
                     " interface");
         }
-
-        final DialogPreference.TargetFragment fragment =
-                (DialogPreference.TargetFragment) rawFragment;
-
-        final String key = getArguments().getString(LeanbackListPreferenceDialogFragment.ARG_KEY);
-        mPreference = (DialogPreference) fragment.findPreference(key);
     }
 
     public DialogPreference getPreference() {
+        if (mPreference == null) {
+            final String key = getArguments().getString(ARG_KEY);
+            final DialogPreference.TargetFragment fragment =
+                    (DialogPreference.TargetFragment) getTargetFragment();
+            mPreference = (DialogPreference) fragment.findPreference(key);
+        }
         return mPreference;
     }
 }
diff --git a/v4/Android.mk b/v4/Android.mk
index c7e35aa..a9c9145 100644
--- a/v4/Android.mk
+++ b/v4/Android.mk
@@ -35,7 +35,6 @@
     android-support-fragment \
     android-support-annotations
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_JAR_EXCLUDE_FILES := none
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
diff --git a/v4/AndroidManifest-make.xml b/v4/AndroidManifest-make.xml
deleted file mode 100644
index d76c581..0000000
--- a/v4/AndroidManifest-make.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.support.v4">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.v4"/>
-    <application />
-</manifest>
diff --git a/v4/AndroidManifest.xml b/v4/AndroidManifest.xml
index cecc743..642a916 100644
--- a/v4/AndroidManifest.xml
+++ b/v4/AndroidManifest.xml
@@ -16,7 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.v4">
-    <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.v4"/>
+    <uses-sdk android:minSdkVersion="14" tools:overrideLibrary="android.support.v4"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/v4/build.gradle b/v4/build.gradle
index f226a87..47778fe 100644
--- a/v4/build.gradle
+++ b/v4/build.gradle
@@ -1,4 +1,4 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'support-v4'
 
 dependencies {
@@ -10,55 +10,15 @@
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
-
-    sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
 }
 
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Library v4'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support Library v4'
+    inceptionYear '2011'
+    description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
 }
diff --git a/v7/appcompat/Android.mk b/v7/appcompat/Android.mk
index 3c5b44c..93baa95 100644
--- a/v7/appcompat/Android.mk
+++ b/v7/appcompat/Android.mk
@@ -28,7 +28,6 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-vectordrawable \
     android-support-animatedvectordrawable
diff --git a/v7/appcompat/AndroidManifest-make.xml b/v7/appcompat/AndroidManifest-make.xml
deleted file mode 100644
index 99b77ee..0000000
--- a/v7/appcompat/AndroidManifest-make.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.support.v7.appcompat">
-    <uses-sdk android:minSdkVersion="9"
-              tools:overrideLibrary="android.support.graphics.drawable.animated"/>
-    <application/>
-</manifest>
diff --git a/v7/appcompat/AndroidManifest.xml b/v7/appcompat/AndroidManifest.xml
index d5858d1..c1ff659 100644
--- a/v7/appcompat/AndroidManifest.xml
+++ b/v7/appcompat/AndroidManifest.xml
@@ -16,7 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.v7.appcompat">
-    <uses-sdk android:minSdkVersion="9"
+    <uses-sdk android:minSdkVersion="14"
               tools:overrideLibrary="android.support.graphics.drawable.animated"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application/>
diff --git a/v7/appcompat/build.gradle b/v7/appcompat/build.gradle
index 4935085..437456b 100644
--- a/v7/appcompat/build.gradle
+++ b/v7/appcompat/build.gradle
@@ -1,4 +1,4 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'appcompat-v7'
 
 dependencies {
@@ -7,44 +7,29 @@
     compile project(':support-vector-drawable')
     compile project(':support-animated-vector-drawable')
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile 'org.mockito:mockito-core:1.9.5'
-    androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
-    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
-    testCompile 'junit:junit:4.12'
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDir 'src'
         main.res.srcDirs 'res', 'res-public'
         main.assets.srcDir 'assets'
         main.resources.srcDir 'src'
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 
     aaptOptions {
@@ -52,52 +37,8 @@
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
+supportLibrary {
+    name 'Android AppCompat Library v7'
+    inceptionYear '2011'
+    description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 4 or later."
 }
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android AppCompat Library v7'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/v7/appcompat/res/values-az-rAZ/strings.xml b/v7/appcompat/res/values-az/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-az-rAZ/strings.xml
rename to v7/appcompat/res/values-az/strings.xml
diff --git a/v7/appcompat/res/values-be-rBY/strings.xml b/v7/appcompat/res/values-be/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-be-rBY/strings.xml
rename to v7/appcompat/res/values-be/strings.xml
diff --git a/v7/appcompat/res/values-bn-rBD/strings.xml b/v7/appcompat/res/values-bn/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-bn-rBD/strings.xml
rename to v7/appcompat/res/values-bn/strings.xml
diff --git a/v7/appcompat/res/values-bs-rBA/strings.xml b/v7/appcompat/res/values-bs/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-bs-rBA/strings.xml
rename to v7/appcompat/res/values-bs/strings.xml
diff --git a/v7/appcompat/res/values-es-rUS/strings.xml b/v7/appcompat/res/values-es-rUS/strings.xml
index 9bc27a9..804941c 100644
--- a/v7/appcompat/res/values-es-rUS/strings.xml
+++ b/v7/appcompat/res/values-es-rUS/strings.xml
@@ -25,7 +25,7 @@
     <string name="abc_action_bar_home_subtitle_description_format" msgid="6623331958280229229">"%1$s, %2$s, %3$s"</string>
     <string name="abc_searchview_description_search" msgid="8264924765203268293">"Búsqueda"</string>
     <string name="abc_search_hint" msgid="7723749260725869598">"Buscar…"</string>
-    <string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de búsqueda"</string>
+    <string name="abc_searchview_description_query" msgid="2550479030709304392">"Búsqueda"</string>
     <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Eliminar la consulta"</string>
     <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
     <string name="abc_searchview_description_voice" msgid="893419373245838918">"Búsqueda por voz"</string>
diff --git a/v7/appcompat/res/values-et-rEE/strings.xml b/v7/appcompat/res/values-et/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-et-rEE/strings.xml
rename to v7/appcompat/res/values-et/strings.xml
diff --git a/v7/appcompat/res/values-eu-rES/strings.xml b/v7/appcompat/res/values-eu/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-eu-rES/strings.xml
rename to v7/appcompat/res/values-eu/strings.xml
diff --git a/v7/appcompat/res/values-gl-rES/strings.xml b/v7/appcompat/res/values-gl/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-gl-rES/strings.xml
rename to v7/appcompat/res/values-gl/strings.xml
diff --git a/v7/appcompat/res/values-gu-rIN/strings.xml b/v7/appcompat/res/values-gu/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-gu-rIN/strings.xml
rename to v7/appcompat/res/values-gu/strings.xml
diff --git a/v7/appcompat/res/values-hy-rAM/strings.xml b/v7/appcompat/res/values-hy/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-hy-rAM/strings.xml
rename to v7/appcompat/res/values-hy/strings.xml
diff --git a/v7/appcompat/res/values-is-rIS/strings.xml b/v7/appcompat/res/values-is/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-is-rIS/strings.xml
rename to v7/appcompat/res/values-is/strings.xml
diff --git a/v7/appcompat/res/values-ka-rGE/strings.xml b/v7/appcompat/res/values-ka/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-ka-rGE/strings.xml
rename to v7/appcompat/res/values-ka/strings.xml
diff --git a/v7/appcompat/res/values-kk-rKZ/strings.xml b/v7/appcompat/res/values-kk/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-kk-rKZ/strings.xml
rename to v7/appcompat/res/values-kk/strings.xml
diff --git a/v7/appcompat/res/values-km-rKH/strings.xml b/v7/appcompat/res/values-km/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-km-rKH/strings.xml
rename to v7/appcompat/res/values-km/strings.xml
diff --git a/v7/appcompat/res/values-kn-rIN/strings.xml b/v7/appcompat/res/values-kn/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-kn-rIN/strings.xml
rename to v7/appcompat/res/values-kn/strings.xml
diff --git a/v7/appcompat/res/values-ky-rKG/strings.xml b/v7/appcompat/res/values-ky/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-ky-rKG/strings.xml
rename to v7/appcompat/res/values-ky/strings.xml
diff --git a/v7/appcompat/res/values-lo-rLA/strings.xml b/v7/appcompat/res/values-lo/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-lo-rLA/strings.xml
rename to v7/appcompat/res/values-lo/strings.xml
diff --git a/v7/appcompat/res/values-mk-rMK/strings.xml b/v7/appcompat/res/values-mk/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-mk-rMK/strings.xml
rename to v7/appcompat/res/values-mk/strings.xml
diff --git a/v7/appcompat/res/values-ml-rIN/strings.xml b/v7/appcompat/res/values-ml/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-ml-rIN/strings.xml
rename to v7/appcompat/res/values-ml/strings.xml
diff --git a/v7/appcompat/res/values-mn-rMN/strings.xml b/v7/appcompat/res/values-mn/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-mn-rMN/strings.xml
rename to v7/appcompat/res/values-mn/strings.xml
diff --git a/v7/appcompat/res/values-mr-rIN/strings.xml b/v7/appcompat/res/values-mr/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-mr-rIN/strings.xml
rename to v7/appcompat/res/values-mr/strings.xml
diff --git a/v7/appcompat/res/values-ms-rMY/strings.xml b/v7/appcompat/res/values-ms/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-ms-rMY/strings.xml
rename to v7/appcompat/res/values-ms/strings.xml
diff --git a/v7/appcompat/res/values-my-rMM/strings.xml b/v7/appcompat/res/values-my/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-my-rMM/strings.xml
rename to v7/appcompat/res/values-my/strings.xml
diff --git a/v7/appcompat/res/values-ne-rNP/strings.xml b/v7/appcompat/res/values-ne/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-ne-rNP/strings.xml
rename to v7/appcompat/res/values-ne/strings.xml
diff --git a/v7/appcompat/res/values-pa-rIN/strings.xml b/v7/appcompat/res/values-pa/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-pa-rIN/strings.xml
rename to v7/appcompat/res/values-pa/strings.xml
diff --git a/v7/appcompat/res/values-si-rLK/strings.xml b/v7/appcompat/res/values-si/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-si-rLK/strings.xml
rename to v7/appcompat/res/values-si/strings.xml
diff --git a/v7/appcompat/res/values-sq-rAL/strings.xml b/v7/appcompat/res/values-sq/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-sq-rAL/strings.xml
rename to v7/appcompat/res/values-sq/strings.xml
diff --git a/v7/appcompat/res/values-ta-rIN/strings.xml b/v7/appcompat/res/values-ta/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-ta-rIN/strings.xml
rename to v7/appcompat/res/values-ta/strings.xml
diff --git a/v7/appcompat/res/values-te-rIN/strings.xml b/v7/appcompat/res/values-te/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-te-rIN/strings.xml
rename to v7/appcompat/res/values-te/strings.xml
diff --git a/v7/appcompat/res/values-ur-rPK/strings.xml b/v7/appcompat/res/values-ur/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-ur-rPK/strings.xml
rename to v7/appcompat/res/values-ur/strings.xml
diff --git a/v7/appcompat/res/values-uz-rUZ/strings.xml b/v7/appcompat/res/values-uz/strings.xml
similarity index 100%
rename from v7/appcompat/res/values-uz-rUZ/strings.xml
rename to v7/appcompat/res/values-uz/strings.xml
diff --git a/v7/appcompat/res/values/attrs.xml b/v7/appcompat/res/values/attrs.xml
index 03ddeec..c140a67 100644
--- a/v7/appcompat/res/values/attrs.xml
+++ b/v7/appcompat/res/values/attrs.xml
@@ -694,6 +694,12 @@
              for more info. -->
         <attr name="actionProviderClass" format="string" />
 
+        <!-- The content description associated with the item. -->
+        <attr name="contentDescription" format="string"/>
+
+        <!-- The tooltip text associated with the item. -->
+        <attr name="tooltipText" format="string"/>
+
     </declare-styleable>
 
     <declare-styleable name="Spinner">
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java b/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java
index 1fe51b8..52b7b2e 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java
@@ -15,7 +15,6 @@
  */
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.app.ActionBar;
 import android.app.Activity;
 import android.content.Context;
@@ -499,7 +498,6 @@
      * Delegate if SDK version is between Honeycomb and ICS
      */
     @RequiresApi(11)
-    @TargetApi(11)
     private static class HoneycombDelegate implements Delegate {
 
         final Activity mActivity;
@@ -548,7 +546,6 @@
      * Delegate if SDK version is between ICS and JBMR2
      */
     @RequiresApi(14)
-    @TargetApi(14)
     private static class IcsDelegate extends HoneycombDelegate {
 
         IcsDelegate(Activity activity) {
@@ -572,7 +569,6 @@
      * Delegate if SDK version is JB MR2 or newer
      */
     @RequiresApi(18)
-    @TargetApi(18)
     private static class JellybeanMr2Delegate implements Delegate {
 
         final Activity mActivity;
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggleHoneycomb.java b/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggleHoneycomb.java
index 1463ecb..92cf866 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggleHoneycomb.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggleHoneycomb.java
@@ -18,7 +18,6 @@
 package android.support.v7.app;
 
 import android.R;
-import android.annotation.TargetApi;
 import android.app.ActionBar;
 import android.app.Activity;
 import android.content.res.TypedArray;
@@ -42,7 +41,6 @@
  * Moved from Support-v4
  */
 @RequiresApi(11)
-@TargetApi(11)
 class ActionBarDrawerToggleHoneycomb {
     private static final String TAG = "ActionBarDrawerToggleHoneycomb";
 
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
index 6da5250..5cf58bd 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Context;
 import android.content.res.Resources;
@@ -39,7 +38,6 @@
 import android.view.Window;
 
 @RequiresApi(9)
-@TargetApi(9)
 abstract class AppCompatDelegateImplBase extends AppCompatDelegate {
 
     static final boolean DEBUG = false;
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplN.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplN.java
index 9f162dd..e282324 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplN.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplN.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 import android.view.KeyboardShortcutGroup;
@@ -26,7 +25,6 @@
 import java.util.List;
 
 @RequiresApi(24)
-@TargetApi(24)
 class AppCompatDelegateImplN extends AppCompatDelegateImplV23 {
 
     AppCompatDelegateImplN(Context context, Window window, AppCompatCallback callback) {
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java
index f3fda8e..736b160 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 import android.util.AttributeSet;
@@ -24,7 +23,6 @@
 import android.view.Window;
 
 @RequiresApi(11)
-@TargetApi(11)
 class AppCompatDelegateImplV11 extends AppCompatDelegateImplV9 {
 
     AppCompatDelegateImplV11(Context context, Window window, AppCompatCallback callback) {
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
index 152f379..1559691 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -38,7 +37,6 @@
 import android.view.Window;
 
 @RequiresApi(14)
-@TargetApi(14)
 class AppCompatDelegateImplV14 extends AppCompatDelegateImplV11 {
 
     private static final String KEY_LOCAL_NIGHT_MODE = "appcompat:local_night_mode";
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV23.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV23.java
index d061114..0095b55 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV23.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV23.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.app.UiModeManager;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
@@ -24,7 +23,6 @@
 import android.view.Window;
 
 @RequiresApi(23)
-@TargetApi(23)
 class AppCompatDelegateImplV23 extends AppCompatDelegateImplV14 {
 
     private final UiModeManager mUiModeManager;
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
index c5839f9..dbdbe56 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
@@ -20,7 +20,6 @@
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.Window.FEATURE_OPTIONS_PANEL;
 
-import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.Context;
@@ -95,7 +94,6 @@
 import org.xmlpull.v1.XmlPullParser;
 
 @RequiresApi(9)
-@TargetApi(9)
 class AppCompatDelegateImplV9 extends AppCompatDelegateImplBase
         implements MenuBuilder.Callback, LayoutInflaterFactory {
 
@@ -789,7 +787,7 @@
                             endOnGoingFadeAnimation();
 
                             if (shouldAnimateActionModeView()) {
-                                ViewCompat.setAlpha(mActionModeView, 0f);
+                                mActionModeView.setAlpha(0f);
                                 mFadeAnim = ViewCompat.animate(mActionModeView).alpha(1f);
                                 mFadeAnim.setListener(new ViewPropertyAnimatorListenerAdapter() {
                                     @Override
@@ -799,13 +797,13 @@
 
                                     @Override
                                     public void onAnimationEnd(View view) {
-                                        ViewCompat.setAlpha(mActionModeView, 1f);
+                                        mActionModeView.setAlpha(1f);
                                         mFadeAnim.setListener(null);
                                         mFadeAnim = null;
                                     }
                                 });
                             } else {
-                                ViewCompat.setAlpha(mActionModeView, 1f);
+                                mActionModeView.setAlpha(1f);
                                 mActionModeView.setVisibility(View.VISIBLE);
                             }
                         }
@@ -832,7 +830,7 @@
                     mActionMode = mode;
 
                     if (shouldAnimateActionModeView()) {
-                        ViewCompat.setAlpha(mActionModeView, 0f);
+                        mActionModeView.setAlpha(0f);
                         mFadeAnim = ViewCompat.animate(mActionModeView).alpha(1f);
                         mFadeAnim.setListener(new ViewPropertyAnimatorListenerAdapter() {
                             @Override
@@ -847,13 +845,13 @@
 
                             @Override
                             public void onAnimationEnd(View view) {
-                                ViewCompat.setAlpha(mActionModeView, 1f);
+                                mActionModeView.setAlpha(1f);
                                 mFadeAnim.setListener(null);
                                 mFadeAnim = null;
                             }
                         });
                     } else {
-                        ViewCompat.setAlpha(mActionModeView, 1f);
+                        mActionModeView.setAlpha(1f);
                         mActionModeView.setVisibility(View.VISIBLE);
                         mActionModeView.sendAccessibilityEvent(
                                 AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompat.java b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
index bd72879..0f3b4f1 100644
--- a/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -85,7 +84,6 @@
     }
 
     @RequiresApi(24)
-    @TargetApi(24)
     private static void addStyleToBuilderApi24(NotificationBuilderWithBuilderAccessor builder,
             android.support.v4.app.NotificationCompat.Builder b) {
         if (b.mStyle instanceof DecoratedCustomViewStyle) {
@@ -98,7 +96,6 @@
     }
 
     @RequiresApi(21)
-    @TargetApi(21)
     private static RemoteViews addStyleGetContentViewLollipop(
             NotificationBuilderWithBuilderAccessor builder,
             android.support.v4.app.NotificationCompat.Builder b) {
@@ -138,7 +135,6 @@
     }
 
     @RequiresApi(16)
-    @TargetApi(16)
     private static RemoteViews addStyleGetContentViewJellybean(
             NotificationBuilderWithBuilderAccessor builder,
             android.support.v4.app.NotificationCompat.Builder b) {
@@ -226,7 +222,6 @@
     }
 
     @RequiresApi(14)
-    @TargetApi(14)
     private static RemoteViews addStyleGetContentViewIcs(
             NotificationBuilderWithBuilderAccessor builder,
             android.support.v4.app.NotificationCompat.Builder b) {
@@ -251,7 +246,6 @@
     }
 
     @RequiresApi(16)
-    @TargetApi(16)
     private static void addBigStyleToBuilderJellybean(Notification n,
             android.support.v4.app.NotificationCompat.Builder b) {
         if (b.mStyle instanceof MediaStyle) {
@@ -292,7 +286,6 @@
     }
 
     @RequiresApi(16)
-    @TargetApi(16)
     private static void addDecoratedBigStyleToBuilderJellybean(Notification n,
             android.support.v4.app.NotificationCompat.Builder b) {
         RemoteViews bigContentView = b.getBigContentView();
@@ -311,7 +304,6 @@
     }
 
     @RequiresApi(21)
-    @TargetApi(21)
     private static void addDecoratedHeadsUpToBuilderLollipop(Notification n,
             android.support.v4.app.NotificationCompat.Builder b) {
         RemoteViews headsUp = b.getHeadsUpContentView();
@@ -330,7 +322,6 @@
     }
 
     @RequiresApi(21)
-    @TargetApi(21)
     private static void addBigStyleToBuilderLollipop(Notification n,
             android.support.v4.app.NotificationCompat.Builder b) {
         RemoteViews innerView = b.getBigContentView() != null
@@ -359,7 +350,6 @@
     }
 
     @RequiresApi(21)
-    @TargetApi(21)
     private static void addHeadsUpToBuilderLollipop(Notification n,
             android.support.v4.app.NotificationCompat.Builder b) {
         RemoteViews innerView = b.getHeadsUpContentView() != null
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl21.java b/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl21.java
index 9b0f028..2a4bf7b 100644
--- a/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl21.java
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl21.java
@@ -16,14 +16,12 @@
 
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.media.session.MediaSession;
 import android.support.annotation.RequiresApi;
 import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
 
 @RequiresApi(21)
-@TargetApi(21)
 class NotificationCompatImpl21 {
 
     public static void addMediaStyle(NotificationBuilderWithBuilderAccessor b,
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl24.java b/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl24.java
index a65751b..c48e286 100644
--- a/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl24.java
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompatImpl24.java
@@ -16,13 +16,11 @@
 
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.support.annotation.RequiresApi;
 import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
 
 @RequiresApi(24)
-@TargetApi(24)
 class NotificationCompatImpl24 {
 
     public static void addDecoratedCustomViewStyle(NotificationBuilderWithBuilderAccessor b) {
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompatImplBase.java b/v7/appcompat/src/android/support/v7/app/NotificationCompatImplBase.java
index a6e73ef..c1432c9 100644
--- a/v7/appcompat/src/android/support/v7/app/NotificationCompatImplBase.java
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompatImplBase.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -47,7 +46,6 @@
  * contentView and bigContentView of the notification.
  */
 @RequiresApi(9)
-@TargetApi(9)
 class NotificationCompatImplBase {
 
     static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;
@@ -55,7 +53,6 @@
     private static final int MAX_ACTION_BUTTONS = 3;
 
     @RequiresApi(11)
-    @TargetApi(11)
     public static <T extends NotificationCompatBase.Action> RemoteViews overrideContentViewMedia(
             NotificationBuilderWithBuilderAccessor builder,
             Context context, CharSequence contentTitle, CharSequence contentText,
@@ -75,7 +72,6 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     private static <T extends NotificationCompatBase.Action> RemoteViews generateContentViewMedia(
             Context context, CharSequence contentTitle, CharSequence contentText,
             CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
@@ -121,7 +117,6 @@
     }
 
     @RequiresApi(16)
-    @TargetApi(16)
     public static <T extends NotificationCompatBase.Action> void overrideMediaBigContentView(
             Notification n, Context context, CharSequence contentTitle, CharSequence contentText,
             CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
@@ -137,7 +132,6 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     public static <T extends NotificationCompatBase.Action> RemoteViews generateMediaBigView(
             Context context, CharSequence contentTitle, CharSequence contentText,
             CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
@@ -169,7 +163,6 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     private static RemoteViews generateMediaActionButton(Context context,
             NotificationCompatBase.Action action) {
         final boolean tombstone = (action.getActionIntent() == null);
@@ -186,7 +179,6 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     private static int getBigMediaLayoutResource(boolean decoratedCustomView, int actionCount) {
         if (actionCount <= 3) {
             return decoratedCustomView
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompatImplJellybean.java b/v7/appcompat/src/android/support/v7/app/NotificationCompatImplJellybean.java
index b600d43..2fca0f0 100644
--- a/v7/appcompat/src/android/support/v7/app/NotificationCompatImplJellybean.java
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompatImplJellybean.java
@@ -16,13 +16,11 @@
 
 package android.support.v7.app;
 
-import android.annotation.TargetApi;
 import android.app.Notification;
 import android.support.annotation.RequiresApi;
 import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
 
 @RequiresApi(16)
-@TargetApi(16)
 class NotificationCompatImplJellybean {
 
     public static void addBigTextStyle(NotificationBuilderWithBuilderAccessor b,
diff --git a/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java b/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
index 2f7eba3..3326874 100644
--- a/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
+++ b/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
@@ -139,8 +139,8 @@
         @Override
         public void onAnimationEnd(View view) {
             if (mContentAnimations && mContentView != null) {
-                ViewCompat.setTranslationY(mContentView, 0f);
-                ViewCompat.setTranslationY(mContainerView, 0f);
+                mContentView.setTranslationY(0f);
+                mContainerView.setTranslationY(0f);
             }
             mContainerView.setVisibility(View.GONE);
             mContainerView.setTransitioning(false);
@@ -772,20 +772,20 @@
         if (mCurWindowVisibility == View.VISIBLE && ALLOW_SHOW_HIDE_ANIMATIONS &&
                 (mShowHideAnimationEnabled || fromSystem)) {
             // because we're about to ask its window loc
-            ViewCompat.setTranslationY(mContainerView, 0f);
+            mContainerView.setTranslationY(0f);
             float startingY = -mContainerView.getHeight();
             if (fromSystem) {
                 int topLeft[] = {0, 0};
                 mContainerView.getLocationInWindow(topLeft);
                 startingY -= topLeft[1];
             }
-            ViewCompat.setTranslationY(mContainerView, startingY);
+            mContainerView.setTranslationY(startingY);
             ViewPropertyAnimatorCompatSet anim = new ViewPropertyAnimatorCompatSet();
             ViewPropertyAnimatorCompat a = ViewCompat.animate(mContainerView).translationY(0f);
             a.setUpdateListener(mUpdateListener);
             anim.play(a);
             if (mContentAnimations && mContentView != null) {
-                ViewCompat.setTranslationY(mContentView, startingY);
+                mContentView.setTranslationY(startingY);
                 anim.play(ViewCompat.animate(mContentView).translationY(0f));
             }
             anim.setInterpolator(sShowInterpolator);
@@ -801,10 +801,10 @@
             mCurrentShowAnim = anim;
             anim.start();
         } else {
-            ViewCompat.setAlpha(mContainerView, 1f);
-            ViewCompat.setTranslationY(mContainerView, 0);
+            mContainerView.setAlpha(1f);
+            mContainerView.setTranslationY(0);
             if (mContentAnimations && mContentView != null) {
-                ViewCompat.setTranslationY(mContentView, 0);
+                mContentView.setTranslationY(0);
             }
             mShowListener.onAnimationEnd(null);
         }
@@ -818,9 +818,9 @@
             mCurrentShowAnim.cancel();
         }
 
-        if (mCurWindowVisibility == View.VISIBLE && ALLOW_SHOW_HIDE_ANIMATIONS &&
-                (mShowHideAnimationEnabled || fromSystem)) {
-            ViewCompat.setAlpha(mContainerView, 1f);
+        if (mCurWindowVisibility == View.VISIBLE && ALLOW_SHOW_HIDE_ANIMATIONS
+                && (mShowHideAnimationEnabled || fromSystem)) {
+            mContainerView.setAlpha(1f);
             mContainerView.setTransitioning(true);
             ViewPropertyAnimatorCompatSet anim = new ViewPropertyAnimatorCompatSet();
             float endingY = -mContainerView.getHeight();
diff --git a/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java b/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
index ff929ba..3ab5f81 100644
--- a/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
+++ b/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.os.Build;
 import android.support.annotation.RestrictTo;
@@ -40,7 +39,6 @@
  * @hide
  */
 @RestrictTo(LIBRARY_GROUP)
-@TargetApi(Build.VERSION_CODES.HONEYCOMB)
 public class SupportActionModeWrapper extends ActionMode {
 
     final Context mContext;
diff --git a/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java b/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
index 4f71d02..d8551ae 100644
--- a/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
+++ b/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
@@ -321,6 +321,9 @@
 
         ActionProvider itemActionProvider;
 
+        private CharSequence itemContentDescription;
+        private CharSequence itemTooltipText;
+
         private static final int defaultGroupId = NO_ID;
         private static final int defaultItemId = NO_ID;
         private static final int defaultItemCategory = 0;
@@ -412,6 +415,9 @@
                 itemActionProvider = null;
             }
 
+            itemContentDescription = a.getText(R.styleable.MenuItem_contentDescription);
+            itemTooltipText = a.getText(R.styleable.MenuItem_tooltipText);
+
             a.recycle();
 
             itemAdded = false;
@@ -476,6 +482,9 @@
             if (itemActionProvider != null) {
                 MenuItemCompat.setActionProvider(item, itemActionProvider);
             }
+
+            MenuItemCompat.setContentDescription(item, itemContentDescription);
+            MenuItemCompat.setTooltipText(item, itemTooltipText);
         }
 
         public void addItem() {
diff --git a/v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java b/v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java
index 4fbdd50..7df9844 100644
--- a/v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java
+++ b/v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
 import android.view.ActionMode;
@@ -60,7 +59,6 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     @Override
     public boolean dispatchKeyShortcutEvent(KeyEvent event) {
         return mWrapped.dispatchKeyShortcutEvent(event);
@@ -77,7 +75,6 @@
     }
 
     @RequiresApi(12)
-    @TargetApi(12)
     @Override
     public boolean dispatchGenericMotionEvent(MotionEvent event) {
         return mWrapped.dispatchGenericMotionEvent(event);
@@ -144,7 +141,6 @@
     }
 
     @RequiresApi(23)
-    @TargetApi(23)
     @Override
     public boolean onSearchRequested(SearchEvent searchEvent) {
         return mWrapped.onSearchRequested(searchEvent);
@@ -156,35 +152,30 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     @Override
     public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
         return mWrapped.onWindowStartingActionMode(callback);
     }
 
     @RequiresApi(23)
-    @TargetApi(23)
     @Override
     public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
         return mWrapped.onWindowStartingActionMode(callback, type);
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     @Override
     public void onActionModeStarted(ActionMode mode) {
         mWrapped.onActionModeStarted(mode);
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     @Override
     public void onActionModeFinished(ActionMode mode) {
         mWrapped.onActionModeFinished(mode);
     }
 
     @RequiresApi(24)
-    @TargetApi(24)
     @Override
     public void onProvideKeyboardShortcuts(
             List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
index 2d13a56..27e7eec 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
@@ -55,6 +55,9 @@
 
     private SupportMenuItem.OnMenuItemClickListener mClickListener;
 
+    private CharSequence mContentDescription;
+    private CharSequence mTooltipText;
+
     private static final int NO_ICON = 0;
 
     private int mFlags = ENABLED;
@@ -297,4 +300,26 @@
         // No need to save the listener; ActionMenuItem does not support collapsing items.
         return this;
     }
+
+    @Override
+    public SupportMenuItem setContentDescription(CharSequence contentDescription) {
+        mContentDescription = contentDescription;
+        return this;
+    }
+
+    @Override
+    public CharSequence getContentDescription() {
+        return mContentDescription;
+    }
+
+    @Override
+    public SupportMenuItem setTooltipText(CharSequence tooltipText) {
+        mTooltipText = tooltipText;
+        return this;
+    }
+
+    @Override
+    public CharSequence getTooltipText() {
+        return mTooltipText;
+    }
 }
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
index 77f5f17..d8ab16b 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
@@ -22,12 +22,10 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Parcelable;
 import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.ConfigurationHelper;
-import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
 import android.support.v7.widget.ActionMenuView;
@@ -35,18 +33,15 @@
 import android.support.v7.widget.ForwardingListener;
 import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
-import android.widget.Toast;
 
 /**
  * @hide
  */
 @RestrictTo(LIBRARY_GROUP)
 public class ActionMenuItemView extends AppCompatTextView
-        implements MenuView.ItemView, View.OnClickListener, View.OnLongClickListener,
-        ActionMenuView.ActionMenuChildView {
+        implements MenuView.ItemView, View.OnClickListener, ActionMenuView.ActionMenuChildView {
 
     private static final String TAG = "ActionMenuItemView";
 
@@ -87,7 +82,6 @@
         mMaxIconSize = (int) (MAX_ICON_SIZE * density + 0.5f);
 
         setOnClickListener(this);
-        setOnLongClickListener(this);
 
         mSavedPaddingLeft = -1;
         setSaveEnabled(false);
@@ -190,6 +184,23 @@
                 (mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat));
 
         setText(visible ? mTitle : null);
+
+        // Show the tooltip for items that do not already show text.
+        final CharSequence contentDescription = mItemData.getContentDescription();
+        if (TextUtils.isEmpty(contentDescription)) {
+            // Use the uncondensed title for content description.
+            setContentDescription(mItemData.getTitle());
+        } else {
+            setContentDescription(contentDescription);
+        }
+
+        final CharSequence tooltipText = mItemData.getTooltipText();
+        if (TextUtils.isEmpty(tooltipText)) {
+            // Use the uncondensed title for tooltip, but only if the title is not shown already.
+            ViewCompat.setTooltipText(this, visible ? null : mItemData.getTitle());
+        } else {
+            ViewCompat.setTooltipText(this, tooltipText);
+        }
     }
 
     public void setIcon(Drawable icon) {
@@ -225,7 +236,6 @@
     public void setTitle(CharSequence title) {
         mTitle = title;
 
-        setContentDescription(mTitle);
         updateTextButtonVisibility();
     }
 
@@ -242,40 +252,6 @@
     }
 
     @Override
-    public boolean onLongClick(View v) {
-        if (hasText()) {
-            // Don't show the cheat sheet for items that already show text.
-            return false;
-        }
-
-        final int[] screenPos = new int[2];
-        final Rect displayFrame = new Rect();
-        getLocationOnScreen(screenPos);
-        getWindowVisibleDisplayFrame(displayFrame);
-
-        final Context context = getContext();
-        final int width = getWidth();
-        final int height = getHeight();
-        final int midy = screenPos[1] + height / 2;
-        int referenceX = screenPos[0] + width / 2;
-        if (ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_LTR) {
-            final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
-            referenceX = screenWidth - referenceX; // mirror
-        }
-        Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT);
-        if (midy < displayFrame.height()) {
-            // Show along the top; follow action buttons
-            cheatSheet.setGravity(Gravity.TOP | GravityCompat.END, referenceX,
-                    screenPos[1] + height - displayFrame.top);
-        } else {
-            // Show along the bottom center
-            cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
-        }
-        cheatSheet.show();
-        return true;
-    }
-
-    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         final boolean textVisible = hasText();
         if (textVisible && mSavedPaddingLeft >= 0) {
diff --git a/v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java b/v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java
index 1cf72c3..ff83ae4 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java
@@ -20,7 +20,6 @@
 
 import android.content.Context;
 import android.support.annotation.RestrictTo;
-import android.support.v4.view.ViewCompat;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -105,7 +104,7 @@
                     if (item != oldItem) {
                         // Don't let old states linger with new data.
                         itemView.setPressed(false);
-                        ViewCompat.jumpDrawablesToCurrentState(itemView);
+                        itemView.jumpDrawablesToCurrentState();
                     }
                     if (itemView != convertView) {
                         addItemView(itemView, childIndex);
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java b/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java
index 6a736aa..00be2ea 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java
@@ -116,6 +116,8 @@
         setIcon(itemData.getIcon());
         setEnabled(itemData.isEnabled());
         setSubMenuArrowVisible(itemData.hasSubMenu());
+        setContentDescription(itemData.getContentDescription());
+        ViewCompat.setTooltipText(this, itemData.getTooltipText());
     }
 
     public void setForceShowIcon(boolean forceShow) {
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java b/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
index f1b94b0..0bdb068 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
@@ -77,6 +77,9 @@
     private Runnable mItemCallback;
     private SupportMenuItem.OnMenuItemClickListener mClickListener;
 
+    private CharSequence mContentDescription;
+    private CharSequence mTooltipText;
+
     private int mFlags = ENABLED;
     private static final int CHECKABLE = 0x00000001;
     private static final int CHECKED = 0x00000002;
@@ -743,4 +746,32 @@
         throw new UnsupportedOperationException(
                 "This is not supported, use MenuItemCompat.setOnActionExpandListener()");
     }
+
+    @Override
+    public SupportMenuItem setContentDescription(CharSequence contentDescription) {
+        mContentDescription = contentDescription;
+
+        mMenu.onItemsChanged(false);
+
+        return this;
+    }
+
+    @Override
+    public CharSequence getContentDescription() {
+        return mContentDescription;
+    }
+
+    @Override
+    public SupportMenuItem setTooltipText(CharSequence tooltipText) {
+        mTooltipText = tooltipText;
+
+        mMenu.onItemsChanged(false);
+
+        return this;
+    }
+
+    @Override
+    public CharSequence getTooltipText() {
+        return mTooltipText;
+    }
 }
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
index 4ba3c89..87ccd80 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
@@ -42,7 +41,6 @@
  * @hide
  */
 @RestrictTo(LIBRARY_GROUP)
-@TargetApi(14)
 @RequiresApi(14)
 public class MenuItemWrapperICS extends BaseMenuWrapper<SupportMenuItem> implements MenuItem {
     static final String LOG_TAG = "MenuItemWrapper";
@@ -298,6 +296,28 @@
         return this;
     }
 
+    @Override
+    public MenuItem setContentDescription(CharSequence contentDescription) {
+        mWrappedObject.setContentDescription(contentDescription);
+        return this;
+    }
+
+    @Override
+    public CharSequence getContentDescription() {
+        return mWrappedObject.getContentDescription();
+    }
+
+    @Override
+    public MenuItem setTooltipText(CharSequence tooltipText) {
+        mWrappedObject.setTooltipText(tooltipText);
+        return this;
+    }
+
+    @Override
+    public CharSequence getTooltipText() {
+        return mWrappedObject.getTooltipText();
+    }
+
     public void setExclusiveCheckable(boolean checkable) {
         try {
             if (mSetExclusiveCheckableMethod == null) {
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java
index 07db707..267903b 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.support.annotation.RequiresApi;
 import android.support.annotation.RestrictTo;
@@ -32,7 +31,6 @@
  * @hide
  */
 @RestrictTo(LIBRARY_GROUP)
-@TargetApi(16)
 @RequiresApi(16)
 class MenuItemWrapperJB extends MenuItemWrapperICS {
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java b/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java
index 25208af..9672449 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.view.menu;
 
-import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -30,7 +29,6 @@
 /**
  * Wraps a support {@link SupportMenu} as a framework {@link android.view.Menu}
  */
-@TargetApi(14)
 @RequiresApi(14)
 class MenuWrapperICS extends BaseMenuWrapper<SupportMenu> implements Menu {
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java b/v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java
index 55245f6..b7478a9 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
@@ -34,7 +33,6 @@
  */
 @RestrictTo(LIBRARY_GROUP)
 @RequiresApi(14)
-@TargetApi(14)
 class SubMenuWrapperICS extends MenuWrapperICS implements SubMenu {
 
     SubMenuWrapperICS(Context context, SupportSubMenu subMenu) {
diff --git a/v7/appcompat/src/android/support/v7/widget/AbsActionBarView.java b/v7/appcompat/src/android/support/v7/widget/AbsActionBarView.java
index 1faf568..413f47f 100644
--- a/v7/appcompat/src/android/support/v7/widget/AbsActionBarView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AbsActionBarView.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
-import android.os.Build;
 import android.support.v4.view.MotionEventCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.ViewPropertyAnimatorCompat;
@@ -162,7 +161,7 @@
 
         if (visibility == VISIBLE) {
             if (getVisibility() != VISIBLE) {
-                ViewCompat.setAlpha(this, 0f);
+                setAlpha(0f);
             }
             ViewPropertyAnimatorCompat anim = ViewCompat.animate(this).alpha(1f);
             anim.setDuration(duration);
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawable.java b/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawable.java
index d8b0f2d..5e86497 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawable.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawable.java
@@ -16,14 +16,12 @@
 
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(9)
-@TargetApi(9)
 class ActionBarBackgroundDrawable extends Drawable {
 
     final ActionBarContainer mContainer;
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawableV21.java b/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawableV21.java
index 56f2a09..989fc4c 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawableV21.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawableV21.java
@@ -16,13 +16,11 @@
 
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.Outline;
 import android.support.annotation.NonNull;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(21)
-@TargetApi(21)
 class ActionBarBackgroundDrawableV21 extends ActionBarBackgroundDrawable {
 
     public ActionBarBackgroundDrawableV21(ActionBarContainer container) {
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java b/v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java
index b685b4c..6f4e8ce 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java
@@ -18,6 +18,8 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
@@ -30,9 +32,6 @@
 import android.support.v4.view.NestedScrollingParent;
 import android.support.v4.view.NestedScrollingParentHelper;
 import android.support.v4.view.ViewCompat;
-import android.support.v4.view.ViewPropertyAnimatorCompat;
-import android.support.v4.view.ViewPropertyAnimatorListener;
-import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
 import android.support.v4.widget.ScrollerCompat;
 import android.support.v7.app.AppCompatDelegate;
 import android.support.v7.appcompat.R;
@@ -42,6 +41,7 @@
 import android.view.Menu;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
 import android.view.Window;
 
 /**
@@ -89,18 +89,17 @@
 
     private ScrollerCompat mFlingEstimator;
 
-    ViewPropertyAnimatorCompat mCurrentActionBarTopAnimator;
+    ViewPropertyAnimator mCurrentActionBarTopAnimator;
 
-    final ViewPropertyAnimatorListener mTopAnimatorListener
-            = new ViewPropertyAnimatorListenerAdapter() {
+    final AnimatorListenerAdapter mTopAnimatorListener = new AnimatorListenerAdapter() {
         @Override
-        public void onAnimationEnd(View view) {
+        public void onAnimationEnd(Animator animator) {
             mCurrentActionBarTopAnimator = null;
             mAnimatingForFling = false;
         }
 
         @Override
-        public void onAnimationCancel(View view) {
+        public void onAnimationCancel(Animator animator) {
             mCurrentActionBarTopAnimator = null;
             mAnimatingForFling = false;
         }
@@ -109,7 +108,7 @@
     private final Runnable mRemoveActionBarHideOffset = new Runnable() {
         public void run() {
             haltActionBarHideOffsetAnimations();
-            mCurrentActionBarTopAnimator = ViewCompat.animate(mActionBarTop).translationY(0)
+            mCurrentActionBarTopAnimator = mActionBarTop.animate().translationY(0)
                     .setListener(mTopAnimatorListener);
         }
     };
@@ -117,7 +116,7 @@
     private final Runnable mAddActionBarHideOffset = new Runnable() {
         public void run() {
             haltActionBarHideOffsetAnimations();
-            mCurrentActionBarTopAnimator = ViewCompat.animate(mActionBarTop)
+            mCurrentActionBarTopAnimator = mActionBarTop.animate()
                     .translationY(-mActionBarTop.getHeight())
                     .setListener(mTopAnimatorListener);
         }
@@ -343,8 +342,7 @@
                 mActionBarTop.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
         maxHeight = Math.max(maxHeight,
                 mActionBarTop.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
-        childState = ViewUtils.combineMeasuredStates(childState,
-                ViewCompat.getMeasuredState(mActionBarTop));
+        childState = View.combineMeasuredStates(childState, mActionBarTop.getMeasuredState());
 
         final int vis = ViewCompat.getWindowSystemUiVisibility(this);
         final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
@@ -396,8 +394,7 @@
                 mContent.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
         maxHeight = Math.max(maxHeight,
                 mContent.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
-        childState = ViewUtils.combineMeasuredStates(childState,
-                ViewCompat.getMeasuredState(mContent));
+        childState = View.combineMeasuredStates(childState, mContent.getMeasuredState());
 
         // Account for padding too
         maxWidth += getPaddingLeft() + getPaddingRight();
@@ -408,8 +405,8 @@
         maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
 
         setMeasuredDimension(
-                ViewCompat.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
-                ViewCompat.resolveSizeAndState(maxHeight, heightMeasureSpec,
+                View.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+                View.resolveSizeAndState(maxHeight, heightMeasureSpec,
                         childState << MEASURED_HEIGHT_STATE_SHIFT));
     }
 
@@ -444,7 +441,7 @@
         super.draw(c);
         if (mWindowContentOverlay != null && !mIgnoreWindowContentOverlay) {
             final int top = mActionBarTop.getVisibility() == VISIBLE ?
-                    (int) (mActionBarTop.getBottom() + ViewCompat.getTranslationY(mActionBarTop) + 0.5f)
+                    (int) (mActionBarTop.getBottom() + mActionBarTop.getTranslationY() + 0.5f)
                     : 0;
             mWindowContentOverlay.setBounds(0, top, getWidth(),
                     top + mWindowContentOverlay.getIntrinsicHeight());
@@ -559,14 +556,14 @@
     }
 
     public int getActionBarHideOffset() {
-        return mActionBarTop != null ? -((int) ViewCompat.getTranslationY(mActionBarTop)) : 0;
+        return mActionBarTop != null ? -((int) mActionBarTop.getTranslationY()) : 0;
     }
 
     public void setActionBarHideOffset(int offset) {
         haltActionBarHideOffsetAnimations();
         final int topHeight = mActionBarTop.getHeight();
         offset = Math.max(0, Math.min(offset, topHeight));
-        ViewCompat.setTranslationY(mActionBarTop, -offset);
+        mActionBarTop.setTranslationY(-offset);
     }
 
     void haltActionBarHideOffsetAnimations() {
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java b/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
index 3abc33b..05f17fd 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
@@ -27,6 +27,7 @@
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.support.v4.view.ActionProvider;
 import android.support.v4.view.GravityCompat;
+import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
 import android.support.v7.transition.ActionBarTransition;
 import android.support.v7.view.ActionBarPolicy;
@@ -647,6 +648,8 @@
             setVisibility(VISIBLE);
             setEnabled(true);
 
+            ViewCompat.setTooltipText(this, getContentDescription());
+
             setOnTouchListener(new ForwardingListener(this) {
                 @Override
                 public ShowableListMenu getPopup() {
diff --git a/v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java b/v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java
index bdd3435..ad641df 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java
@@ -16,21 +16,20 @@
 
 package android.support.v7.widget;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
 import android.database.DataSetObservable;
 import android.os.AsyncTask;
-import android.support.v4.os.AsyncTaskCompat;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Xml;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -572,7 +571,7 @@
         }
         mHistoricalRecordsChanged = false;
         if (!TextUtils.isEmpty(mHistoryFileName)) {
-            AsyncTaskCompat.executeParallel(new PersistHistoryAsyncTask(),
+            new PersistHistoryAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
                     new ArrayList<HistoricalRecord>(mHistoricalRecords), mHistoryFileName);
         }
     }
diff --git a/v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java b/v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java
index a1f5018..d78aa40 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java
@@ -28,7 +28,6 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RestrictTo;
 import android.support.v4.view.ActionProvider;
-import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
 import android.support.v7.view.menu.ShowableListMenu;
 import android.util.AttributeSet;
@@ -762,9 +761,9 @@
                     titleView.setText(activity.loadLabel(packageManager));
                     // Highlight the default.
                     if (mShowDefaultActivity && position == 0 && mHighlightDefaultActivity) {
-                        ViewCompat.setActivated(convertView, true);
+                        convertView.setActivated(true);
                     } else {
-                        ViewCompat.setActivated(convertView, false);
+                        convertView.setActivated(false);
                     }
                     return convertView;
                 default:
diff --git a/v7/appcompat/src/android/support/v7/widget/AlertDialogLayout.java b/v7/appcompat/src/android/support/v7/widget/AlertDialogLayout.java
index 5e650b2..6739c81 100644
--- a/v7/appcompat/src/android/support/v7/widget/AlertDialogLayout.java
+++ b/v7/appcompat/src/android/support/v7/widget/AlertDialogLayout.java
@@ -106,8 +106,7 @@
             topPanel.measure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
 
             usedHeight += topPanel.getMeasuredHeight();
-            childState = ViewCompat.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(topPanel));
+            childState = View.combineMeasuredStates(childState, topPanel.getMeasuredState());
         }
 
         int buttonHeight = 0;
@@ -118,8 +117,7 @@
             buttonWantsHeight = buttonPanel.getMeasuredHeight() - buttonHeight;
 
             usedHeight += buttonHeight;
-            childState = ViewCompat.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(buttonPanel));
+            childState = View.combineMeasuredStates(childState, buttonPanel.getMeasuredState());
         }
 
         int middleHeight = 0;
@@ -136,8 +134,7 @@
             middleHeight = middlePanel.getMeasuredHeight();
 
             usedHeight += middleHeight;
-            childState = ViewCompat.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(middlePanel));
+            childState = View.combineMeasuredStates(childState, middlePanel.getMeasuredState());
         }
 
         int remainingHeight = heightSize - usedHeight;
@@ -159,8 +156,7 @@
             buttonPanel.measure(widthMeasureSpec, childHeightSpec);
 
             usedHeight += buttonPanel.getMeasuredHeight();
-            childState = ViewCompat.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(buttonPanel));
+            childState = View.combineMeasuredStates(childState, buttonPanel.getMeasuredState());
         }
 
         // If we still have remaining space, make the middle pane bigger up
@@ -180,8 +176,7 @@
             middlePanel.measure(widthMeasureSpec, childHeightSpec);
 
             usedHeight += middlePanel.getMeasuredHeight();
-            childState = ViewCompat.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(middlePanel));
+            childState = View.combineMeasuredStates(childState, middlePanel.getMeasuredState());
         }
 
         // Compute desired width as maximum child width.
@@ -195,9 +190,9 @@
 
         maxWidth += getPaddingLeft() + getPaddingRight();
 
-        final int widthSizeAndState = ViewCompat.resolveSizeAndState(
+        final int widthSizeAndState = View.resolveSizeAndState(
                 maxWidth, widthMeasureSpec, childState);
-        final int heightSizeAndState = ViewCompat.resolveSizeAndState(
+        final int heightSizeAndState = View.resolveSizeAndState(
                 usedHeight, heightMeasureSpec, 0);
         setMeasuredDimension(widthSizeAndState, heightSizeAndState);
 
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java b/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
index f7fa23f..23c6308 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
@@ -171,7 +170,6 @@
     }
 
     @RequiresApi(14)
-    @TargetApi(14)
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java b/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
index 50a17cd..d42a4fc 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
@@ -24,7 +24,6 @@
 import static android.support.v7.widget.ThemeUtils.getThemeAttrColorStateList;
 
 import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -740,7 +739,6 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     private static class AvdcInflateDelegate implements InflateDelegate {
         AvdcInflateDelegate() {
         }
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java b/v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java
index c9e778d..097ce91 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.os.Build;
 import android.support.annotation.AttrRes;
@@ -50,7 +49,6 @@
         init(context, attrs, defStyleAttr, 0);
     }
 
-    @TargetApi(11)
     public AppCompatPopupWindow(@NonNull Context context, @Nullable AttributeSet attrs,
             @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
@@ -95,7 +93,6 @@
         super.showAsDropDown(anchor, xoff, yoff);
     }
 
-    @TargetApi(Build.VERSION_CODES.KITKAT)
     @Override
     public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
         if (COMPAT_OVERLAP_ANCHOR && mOverlapAnchor) {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java b/v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java
index afaa02a..7dd683c 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java
@@ -18,9 +18,9 @@
 
 import android.content.Context;
 import android.graphics.Bitmap;
-import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
+import android.view.View;
 import android.widget.RatingBar;
 
 /**
@@ -55,7 +55,7 @@
         Bitmap sampleTile = mAppCompatProgressBarHelper.getSampleTime();
         if (sampleTile != null) {
             final int width = sampleTile.getWidth() * getNumStars();
-            setMeasuredDimension(ViewCompat.resolveSizeAndState(width, widthMeasureSpec, 0),
+            setMeasuredDimension(View.resolveSizeAndState(width, widthMeasureSpec, 0),
                     getMeasuredHeight());
         }
     }
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java b/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java
index bac1cb8..724fbd4 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.support.annotation.RequiresApi;
@@ -62,7 +61,6 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     @Override
     public void jumpDrawablesToCurrentState() {
         super.jumpDrawablesToCurrentState();
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBarHelper.java b/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBarHelper.java
index 93e1851..e1e62ee 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBarHelper.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBarHelper.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.PorterDuff;
@@ -143,7 +142,6 @@
     }
 
     @RequiresApi(11)
-    @TargetApi(11)
     void jumpDrawablesToCurrentState() {
         if (mTickMark != null) {
             mTickMark.jumpToCurrentState();
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java b/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
index c210036..0dc5759 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.drawable.Drawable;
@@ -29,7 +28,6 @@
 import android.widget.TextView;
 
 @RequiresApi(9)
-@TargetApi(9)
 class AppCompatTextHelper {
 
     static AppCompatTextHelper create(TextView textView) {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelperV17.java b/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelperV17.java
index e022756..d5cc872 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelperV17.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelperV17.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -26,7 +25,6 @@
 import android.widget.TextView;
 
 @RequiresApi(17)
-@TargetApi(17)
 class AppCompatTextHelperV17 extends AppCompatTextHelper {
     private TintInfo mDrawableStartTint;
     private TintInfo mDrawableEndTint;
diff --git a/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java b/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
index 048f2b6..ea224b6 100644
--- a/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
+++ b/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
@@ -19,7 +19,6 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.os.Build;
 import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.ConfigurationHelper;
 import android.support.v4.view.ViewCompat;
@@ -102,20 +101,9 @@
         if (mAllowStacking && !isStacked()) {
             final boolean stack;
 
-            if (Build.VERSION.SDK_INT >= 11) {
-                // On API v11+ we can use MEASURED_STATE_MASK and MEASURED_STATE_TOO_SMALL
-                final int measuredWidth = ViewCompat.getMeasuredWidthAndState(this);
-                final int measuredWidthState = measuredWidth & ViewCompat.MEASURED_STATE_MASK;
-                stack = measuredWidthState == ViewCompat.MEASURED_STATE_TOO_SMALL;
-            } else {
-                // Before that we need to manually total up the children's preferred width.
-                // This isn't perfect but works well enough for a workaround.
-                int childWidthTotal = 0;
-                for (int i = 0, count = getChildCount(); i < count; i++) {
-                    childWidthTotal += getChildAt(i).getMeasuredWidth();
-                }
-                stack = (childWidthTotal + getPaddingLeft() + getPaddingRight()) > widthSize;
-            }
+            final int measuredWidth = getMeasuredWidthAndState();
+            final int measuredWidthState = measuredWidth & View.MEASURED_STATE_MASK;
+            stack = measuredWidthState == View.MEASURED_STATE_TOO_SMALL;
 
             if (stack) {
                 setStacked(true);
diff --git a/v7/appcompat/src/android/support/v7/widget/ForwardingListener.java b/v7/appcompat/src/android/support/v7/widget/ForwardingListener.java
index 80fbbd4..fa5e02c 100644
--- a/v7/appcompat/src/android/support/v7/widget/ForwardingListener.java
+++ b/v7/appcompat/src/android/support/v7/widget/ForwardingListener.java
@@ -18,7 +18,6 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.os.Build;
 import android.os.SystemClock;
 import android.support.annotation.RequiresApi;
@@ -88,7 +87,6 @@
     }
 
     @RequiresApi(12)
-    @TargetApi(12)
     private void addDetachListenerApi12(View src) {
         src.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
             @Override
diff --git a/v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java b/v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java
index 10633f6..a212c94 100644
--- a/v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java
+++ b/v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java
@@ -706,8 +706,8 @@
             final int margin = lp.leftMargin + lp.rightMargin;
             final int measuredWidth = child.getMeasuredWidth() + margin;
             maxWidth = Math.max(maxWidth, measuredWidth);
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(child));
+            childState = View.combineMeasuredStates(childState,
+                    child.getMeasuredState());
 
             allFillParent = allFillParent && lp.width == LayoutParams.MATCH_PARENT;
             if (lp.weight > 0) {
@@ -764,8 +764,8 @@
         heightSize = Math.max(heightSize, getSuggestedMinimumHeight());
 
         // Reconcile our calculated size with the heightMeasureSpec
-        int heightSizeAndState = ViewCompat.resolveSizeAndState(heightSize, heightMeasureSpec, 0);
-        heightSize = heightSizeAndState & ViewCompat.MEASURED_SIZE_MASK;
+        int heightSizeAndState = View.resolveSizeAndState(heightSize, heightMeasureSpec, 0);
+        heightSize = heightSizeAndState & View.MEASURED_SIZE_MASK;
 
         // Either expand children with weight to take up available space or
         // shrink them if they extend beyond our current bounds. If we skipped
@@ -817,9 +817,9 @@
                     }
 
                     // Child may now not fit in vertical dimension.
-                    childState = ViewUtils.combineMeasuredStates(childState,
-                            ViewCompat.getMeasuredState(child) & (ViewCompat.MEASURED_STATE_MASK
-                                    >> ViewCompat.MEASURED_HEIGHT_STATE_SHIFT));
+                    childState = View.combineMeasuredStates(childState,
+                            child.getMeasuredState() & (View.MEASURED_STATE_MASK
+                                    >> View.MEASURED_HEIGHT_STATE_SHIFT));
                 }
 
                 final int margin =  lp.leftMargin + lp.rightMargin;
@@ -881,7 +881,7 @@
         // Check against our minimum width
         maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
 
-        setMeasuredDimension(ViewCompat.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+        setMeasuredDimension(View.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
                 heightSizeAndState);
 
         if (matchWidth) {
@@ -1055,7 +1055,7 @@
             final int margin = lp.topMargin + lp.bottomMargin;
             final int childHeight = child.getMeasuredHeight() + margin;
             childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(child));
+                    child.getMeasuredState());
 
             if (baselineAligned) {
                 final int childBaseline = child.getBaseline();
@@ -1148,8 +1148,8 @@
         widthSize = Math.max(widthSize, getSuggestedMinimumWidth());
 
         // Reconcile our calculated size with the widthMeasureSpec
-        int widthSizeAndState = ViewCompat.resolveSizeAndState(widthSize, widthMeasureSpec, 0);
-        widthSize = widthSizeAndState & ViewCompat.MEASURED_SIZE_MASK;
+        int widthSizeAndState = View.resolveSizeAndState(widthSize, widthMeasureSpec, 0);
+        widthSize = widthSizeAndState & View.MEASURED_SIZE_MASK;
 
         // Either expand children with weight to take up available space or
         // shrink them if they extend beyond our current bounds. If we skipped
@@ -1207,8 +1207,8 @@
                     }
 
                     // Child may now not fit in horizontal dimension.
-                    childState = ViewUtils.combineMeasuredStates(childState,
-                            ViewCompat.getMeasuredState(child) & ViewCompat.MEASURED_STATE_MASK);
+                    childState = View.combineMeasuredStates(childState,
+                            child.getMeasuredState() & View.MEASURED_STATE_MASK);
                 }
 
                 if (isExactly) {
@@ -1301,9 +1301,9 @@
         // Check against our minimum height
         maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
 
-        setMeasuredDimension(widthSizeAndState | (childState&ViewCompat.MEASURED_STATE_MASK),
-                ViewCompat.resolveSizeAndState(maxHeight, heightMeasureSpec,
-                        (childState<<ViewCompat.MEASURED_HEIGHT_STATE_SHIFT)));
+        setMeasuredDimension(widthSizeAndState | (childState & View.MEASURED_STATE_MASK),
+                View.resolveSizeAndState(maxHeight, heightMeasureSpec,
+                        (childState << View.MEASURED_HEIGHT_STATE_SHIFT)));
 
         if (matchHeight) {
             forceUniformHeight(count, widthMeasureSpec);
diff --git a/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java b/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
index ea536d2..a8b4257 100644
--- a/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
+++ b/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
@@ -17,6 +17,8 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
@@ -24,8 +26,6 @@
 import android.support.annotation.RestrictTo;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewCompat;
-import android.support.v4.view.ViewPropertyAnimatorCompat;
-import android.support.v4.view.ViewPropertyAnimatorListener;
 import android.support.v7.app.ActionBar;
 import android.support.v7.appcompat.R;
 import android.support.v7.view.ActionBarPolicy;
@@ -35,6 +35,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
+import android.view.ViewPropertyAnimator;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.DecelerateInterpolator;
@@ -46,7 +47,6 @@
 import android.widget.ListView;
 import android.widget.Spinner;
 import android.widget.TextView;
-import android.widget.Toast;
 
 /**
  * This widget implements the dynamic action bar tab behavior that can change across different
@@ -71,7 +71,7 @@
     private int mContentHeight;
     private int mSelectedTabIndex;
 
-    protected ViewPropertyAnimatorCompat mVisibilityAnim;
+    protected ViewPropertyAnimator mVisibilityAnim;
     protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener();
 
     private static final Interpolator sAlphaInterpolator = new DecelerateInterpolator();
@@ -237,17 +237,17 @@
         }
         if (visibility == VISIBLE) {
             if (getVisibility() != VISIBLE) {
-                ViewCompat.setAlpha(this, 0f);
+                setAlpha(0f);
             }
 
-            ViewPropertyAnimatorCompat anim = ViewCompat.animate(this).alpha(1f);
+            ViewPropertyAnimator anim = animate().alpha(1f);
             anim.setDuration(FADE_DURATION);
 
             anim.setInterpolator(sAlphaInterpolator);
             anim.setListener(mVisAnimListener.withFinalVisibility(anim, visibility));
             anim.start();
         } else {
-            ViewPropertyAnimatorCompat anim = ViewCompat.animate(this).alpha(0f);
+            ViewPropertyAnimator anim = animate().alpha(0f);
             anim.setDuration(FADE_DURATION);
 
             anim.setInterpolator(sAlphaInterpolator);
@@ -377,7 +377,7 @@
         // no-op
     }
 
-    private class TabView extends LinearLayoutCompat implements OnLongClickListener {
+    private class TabView extends LinearLayoutCompat {
         private final int[] BG_ATTRS = {
                 android.R.attr.background
         };
@@ -511,36 +511,10 @@
                 if (mIconView != null) {
                     mIconView.setContentDescription(tab.getContentDescription());
                 }
-
-                if (!hasText && !TextUtils.isEmpty(tab.getContentDescription())) {
-                    setOnLongClickListener(this);
-                } else {
-                    setOnLongClickListener(null);
-                    setLongClickable(false);
-                }
+                ViewCompat.setTooltipText(this, hasText ? null : tab.getContentDescription());
             }
         }
 
-        @Override
-        public boolean onLongClick(View v) {
-            final int[] screenPos = new int[2];
-            getLocationOnScreen(screenPos);
-
-            final Context context = getContext();
-            final int width = getWidth();
-            final int height = getHeight();
-            final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
-
-            Toast cheatSheet = Toast.makeText(context, mTab.getContentDescription(),
-                    Toast.LENGTH_SHORT);
-            // Show under the tab
-            cheatSheet.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL,
-                    (screenPos[0] + width / 2) - screenWidth / 2, height);
-
-            cheatSheet.show();
-            return true;
-        }
-
         public ActionBar.Tab getTab() {
             return mTab;
         }
@@ -592,11 +566,11 @@
         }
     }
 
-    protected class VisibilityAnimListener implements ViewPropertyAnimatorListener {
+    protected class VisibilityAnimListener extends AnimatorListenerAdapter {
         private boolean mCanceled = false;
         private int mFinalVisibility;
 
-        public VisibilityAnimListener withFinalVisibility(ViewPropertyAnimatorCompat animation,
+        public VisibilityAnimListener withFinalVisibility(ViewPropertyAnimator animation,
                 int visibility) {
             mFinalVisibility = visibility;
             mVisibilityAnim = animation;
@@ -604,13 +578,13 @@
         }
 
         @Override
-        public void onAnimationStart(View view) {
+        public void onAnimationStart(Animator animator) {
             setVisibility(VISIBLE);
             mCanceled = false;
         }
 
         @Override
-        public void onAnimationEnd(View view) {
+        public void onAnimationEnd(Animator animator) {
             if (mCanceled) return;
 
             mVisibilityAnim = null;
@@ -618,7 +592,7 @@
         }
 
         @Override
-        public void onAnimationCancel(View view) {
+        public void onAnimationCancel(Animator animator) {
             mCanceled = true;
         }
     }
diff --git a/v7/appcompat/src/android/support/v7/widget/SearchView.java b/v7/appcompat/src/android/support/v7/widget/SearchView.java
index 5b3b777..55ff0e6 100644
--- a/v7/appcompat/src/android/support/v7/widget/SearchView.java
+++ b/v7/appcompat/src/android/support/v7/widget/SearchView.java
@@ -19,7 +19,6 @@
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 import static android.support.v7.widget.SuggestionsAdapter.getColumnString;
 
-import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.app.SearchManager;
 import android.app.SearchableInfo;
@@ -328,6 +327,9 @@
 
         mSearchHintIcon = a.getDrawable(R.styleable.SearchView_searchHintIcon);
 
+        ViewCompat.setTooltipText(mSearchButton,
+                getResources().getString(R.string.abc_searchview_description_search));
+
         // Extract dropdown layout resource IDs for later use.
         mSuggestionRowLayout = a.getResourceId(R.styleable.SearchView_suggestionRowLayout,
                 R.layout.abc_search_dropdown_item_icons_2line);
@@ -402,7 +404,6 @@
         updateQueryHint();
     }
 
-    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
     private void addOnLayoutChangeListenerToDropDownAnchorSDK11() {
         mDropDownAnchor.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
             @Override
diff --git a/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java b/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
index c9e1dc8..3ed014d 100644
--- a/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
+++ b/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
@@ -840,7 +839,7 @@
 
         final int measuredHeight = getMeasuredHeight();
         if (measuredHeight < switchHeight) {
-            setMeasuredDimension(ViewCompat.getMeasuredWidthAndState(this), switchHeight);
+            setMeasuredDimension(getMeasuredWidthAndState(), switchHeight);
         }
     }
 
diff --git a/v7/appcompat/src/android/support/v7/widget/Toolbar.java b/v7/appcompat/src/android/support/v7/widget/Toolbar.java
index 8687292..8c39331 100644
--- a/v7/appcompat/src/android/support/v7/widget/Toolbar.java
+++ b/v7/appcompat/src/android/support/v7/widget/Toolbar.java
@@ -1593,8 +1593,8 @@
             navWidth = mNavButtonView.getMeasuredWidth() + getHorizontalMargins(mNavButtonView);
             height = Math.max(height, mNavButtonView.getMeasuredHeight() +
                     getVerticalMargins(mNavButtonView));
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(mNavButtonView));
+            childState = View.combineMeasuredStates(childState,
+                    mNavButtonView.getMeasuredState());
         }
 
         if (shouldLayout(mCollapseButtonView)) {
@@ -1604,8 +1604,8 @@
                     getHorizontalMargins(mCollapseButtonView);
             height = Math.max(height, mCollapseButtonView.getMeasuredHeight() +
                     getVerticalMargins(mCollapseButtonView));
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(mCollapseButtonView));
+            childState = View.combineMeasuredStates(childState,
+                    mCollapseButtonView.getMeasuredState());
         }
 
         final int contentInsetStart = getCurrentContentInsetStart();
@@ -1619,8 +1619,8 @@
             menuWidth = mMenuView.getMeasuredWidth() + getHorizontalMargins(mMenuView);
             height = Math.max(height, mMenuView.getMeasuredHeight() +
                     getVerticalMargins(mMenuView));
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(mMenuView));
+            childState = View.combineMeasuredStates(childState,
+                    mMenuView.getMeasuredState());
         }
 
         final int contentInsetEnd = getCurrentContentInsetEnd();
@@ -1632,8 +1632,8 @@
                     heightMeasureSpec, 0, collapsingMargins);
             height = Math.max(height, mExpandedActionView.getMeasuredHeight() +
                     getVerticalMargins(mExpandedActionView));
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(mExpandedActionView));
+            childState = View.combineMeasuredStates(childState,
+                    mExpandedActionView.getMeasuredState());
         }
 
         if (shouldLayout(mLogoView)) {
@@ -1641,8 +1641,8 @@
                     heightMeasureSpec, 0, collapsingMargins);
             height = Math.max(height, mLogoView.getMeasuredHeight() +
                     getVerticalMargins(mLogoView));
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(mLogoView));
+            childState = View.combineMeasuredStates(childState,
+                    mLogoView.getMeasuredState());
         }
 
         final int childCount = getChildCount();
@@ -1657,8 +1657,7 @@
             width += measureChildCollapseMargins(child, widthMeasureSpec, width,
                     heightMeasureSpec, 0, collapsingMargins);
             height = Math.max(height, child.getMeasuredHeight() + getVerticalMargins(child));
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(child));
+            childState = View.combineMeasuredStates(childState, child.getMeasuredState());
         }
 
         int titleWidth = 0;
@@ -1671,8 +1670,7 @@
                     collapsingMargins);
             titleWidth = mTitleTextView.getMeasuredWidth() + getHorizontalMargins(mTitleTextView);
             titleHeight = mTitleTextView.getMeasuredHeight() + getVerticalMargins(mTitleTextView);
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(mTitleTextView));
+            childState = View.combineMeasuredStates(childState, mTitleTextView.getMeasuredState());
         }
         if (shouldLayout(mSubtitleTextView)) {
             titleWidth = Math.max(titleWidth, measureChildCollapseMargins(mSubtitleTextView,
@@ -1681,8 +1679,8 @@
                     collapsingMargins));
             titleHeight += mSubtitleTextView.getMeasuredHeight() +
                     getVerticalMargins(mSubtitleTextView);
-            childState = ViewUtils.combineMeasuredStates(childState,
-                    ViewCompat.getMeasuredState(mSubtitleTextView));
+            childState = View.combineMeasuredStates(childState,
+                    mSubtitleTextView.getMeasuredState());
         }
 
         width += titleWidth;
@@ -1693,12 +1691,12 @@
         width += getPaddingLeft() + getPaddingRight();
         height += getPaddingTop() + getPaddingBottom();
 
-        final int measuredWidth = ViewCompat.resolveSizeAndState(
+        final int measuredWidth = View.resolveSizeAndState(
                 Math.max(width, getSuggestedMinimumWidth()),
-                widthMeasureSpec, childState & ViewCompat.MEASURED_STATE_MASK);
-        final int measuredHeight = ViewCompat.resolveSizeAndState(
+                widthMeasureSpec, childState & View.MEASURED_STATE_MASK);
+        final int measuredHeight = View.resolveSizeAndState(
                 Math.max(height, getSuggestedMinimumHeight()),
-                heightMeasureSpec, childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
+                heightMeasureSpec, childState << View.MEASURED_HEIGHT_STATE_SHIFT);
 
         setMeasuredDimension(measuredWidth, shouldCollapse() ? 0 : measuredHeight);
     }
diff --git a/v7/appcompat/src/android/support/v7/widget/ViewUtils.java b/v7/appcompat/src/android/support/v7/widget/ViewUtils.java
index 2a158c5..58acb03 100644
--- a/v7/appcompat/src/android/support/v7/widget/ViewUtils.java
+++ b/v7/appcompat/src/android/support/v7/widget/ViewUtils.java
@@ -58,15 +58,18 @@
     }
 
     /**
-     * Merge two states as returned by {@link ViewCompat#getMeasuredState(android.view.View)} ()}.
+     * Merge two states as returned by {@link View#getMeasuredState()} ()}.
      * @param curState The current state as returned from a view or the result
      * of combining multiple views.
      * @param newState The new view state to combine.
      * @return Returns a new integer reflecting the combination of the two
      * states.
+     *
+     * @deprecated Use {@link View#combineMeasuredStates(int, int)} directly.
      */
+    @Deprecated
     public static int combineMeasuredStates(int curState, int newState) {
-        return curState | newState;
+        return View.combineMeasuredStates(curState, newState);
     }
 
     /**
diff --git a/v7/appcompat/tests/AndroidManifest.xml b/v7/appcompat/tests/AndroidManifest.xml
index 7385a5f..0245e26 100644
--- a/v7/appcompat/tests/AndroidManifest.xml
+++ b/v7/appcompat/tests/AndroidManifest.xml
@@ -19,7 +19,7 @@
           package="android.support.v7.appcompat.test">
 
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                       android.support.test.espresso, android.support.test.espresso.idling"/>
diff --git a/v7/appcompat/tests/res/menu/popup_menu.xml b/v7/appcompat/tests/res/menu/popup_menu.xml
index f50efc5..09d3bfa 100644
--- a/v7/appcompat/tests/res/menu/popup_menu.xml
+++ b/v7/appcompat/tests/res/menu/popup_menu.xml
@@ -13,9 +13,12 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto">
     <item android:id="@+id/action_highlight"
-          android:title="@string/popup_menu_highlight" />
+          android:title="@string/popup_menu_highlight"
+          app:contentDescription="@string/popup_menu_highlight_description"
+          app:tooltipText="@string/popup_menu_highlight_tooltip" />
     <item android:id="@+id/action_edit"
           android:title="@string/popup_menu_edit" />
     <item android:id="@+id/action_delete"
diff --git a/v7/appcompat/tests/res/menu/sample_actions.xml b/v7/appcompat/tests/res/menu/sample_actions.xml
index 68882bd..8b3f893 100644
--- a/v7/appcompat/tests/res/menu/sample_actions.xml
+++ b/v7/appcompat/tests/res/menu/sample_actions.xml
@@ -18,12 +18,15 @@
 
     <item android:id="@+id/action_search"
           android:title="@string/search_menu_title"
+          app:contentDescription="@string/search_menu_description"
+          app:tooltipText="@string/search_menu_tooltip"
           app:showAsAction="always|collapseActionView"
           app:actionViewClass="android.support.v7.widget.SearchView"/>
 
     <item android:id="@+id/action_alpha_shortcut"
-          android:title="Alpha"
-          android:alphabeticShortcut="A"/>
+          android:title="@string/alpha_menu_title"
+          android:alphabeticShortcut="A"
+          app:showAsAction="always" />
 
     <item android:id="@+id/action_numeric_shortcut"
           android:title="Numeric"
diff --git a/v7/appcompat/tests/res/values/strings.xml b/v7/appcompat/tests/res/values/strings.xml
index 812bd61..fbc132b 100644
--- a/v7/appcompat/tests/res/values/strings.xml
+++ b/v7/appcompat/tests/res/values/strings.xml
@@ -24,7 +24,11 @@
     <string name="popup_activity">Popup activity</string>
     <string name="popup_show">Show popup</string>
     <string name="popup_menu_highlight">Highlight</string>
+    <string name="popup_menu_highlight_description">Highlight description</string>
+    <string name="popup_menu_highlight_tooltip">Highlight tooltip</string>
     <string name="popup_menu_edit">Edit</string>
+    <string name="popup_menu_edit_description">Edit description</string>
+    <string name="popup_menu_edit_tooltip">Edit tooltip</string>
     <string name="popup_menu_delete">Delete</string>
     <string name="popup_menu_ignore">Ignore</string>
     <string name="popup_menu_share">Share</string>
@@ -68,4 +72,11 @@
     </string-array>
 
     <string name="night_mode">DAY</string>
+
+    <string name="search_menu_description">Search description</string>
+    <string name="search_menu_tooltip">Search tooltip</string>
+
+    <string name="alpha_menu_title">Alpha</string>
+    <string name="alpha_menu_description">Alpha description</string>
+    <string name="alpha_menu_tooltip">Alpha tooltip</string>
 </resources>
diff --git a/v7/appcompat/tests/src/android/support/v7/app/AlertDialogTest.java b/v7/appcompat/tests/src/android/support/v7/app/AlertDialogTest.java
index 022face..1d4b244 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/AlertDialogTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/AlertDialogTest.java
@@ -90,9 +90,9 @@
  *     <li>Testing <code>setIcon</code> API assumes that the icon is displayed by a separate
  *     <code>ImageView</code> which is a sibling of a title view.</li>
  *     <li>Testing <code>setMultiChoiceItems</code> API assumes that each item in the list
- *     is rendered by a single <code></code>CheckedTextView</code>.</li>
+ *     is rendered by a single <code>CheckedTextView</code>.</li>
  *     <li>Testing <code>setSingleChoiceItems</code> API assumes that each item in the list
- *     is rendered by a single <code></code>CheckedTextView</code>.</li>
+ *     is rendered by a single <code>CheckedTextView</code>.</li>
  * </ul>
  */
 public class AlertDialogTest extends BaseInstrumentationTestCase<AlertDialogTestActivity> {
@@ -111,9 +111,14 @@
     }
 
     @After
-    public void tearDown() {
-        if (mAlertDialog != null) {
-            mAlertDialog.dismiss();
+    public void tearDown() throws Throwable {
+        if ((mAlertDialog != null) && mAlertDialog.isShowing()) {
+            mActivityTestRule.runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mAlertDialog.hide();
+                }
+            });
         }
     }
 
@@ -692,7 +697,7 @@
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     public void testSingleChoiceItemsFromRuntimeArray() {
         final String[] content = new String[] { "Alice", "Bob", "Charlie", "Delta" };
         final DialogInterface.OnClickListener mockClickListener =
@@ -706,7 +711,7 @@
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     public void testSingleChoiceItemsFromResourcesArray() {
         final DialogInterface.OnClickListener mockClickListener =
                 mock(DialogInterface.OnClickListener.class);
@@ -1366,4 +1371,4 @@
             return mHeight;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/app/BaseKeyEventsTestCase.java b/v7/appcompat/tests/src/android/support/v7/app/BaseKeyEventsTestCase.java
index 78fdda3..fbfd963 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/BaseKeyEventsTestCase.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/BaseKeyEventsTestCase.java
@@ -31,6 +31,7 @@
 
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.SmallTest;
+import android.support.v4.view.MenuItemCompat;
 import android.support.v7.appcompat.test.R;
 import android.support.v7.testutils.BaseTestActivity;
 import android.support.v7.view.ActionMode;
@@ -93,10 +94,8 @@
     @Test
     @LargeTest
     public void testBackCollapsesSearchView() throws InterruptedException {
-        final String itemTitle = getActivity().getString(R.string.search_menu_title);
-
         // Click on the Search menu item
-        onView(withContentDescription(itemTitle)).perform(click());
+        onView(withId(R.id.action_search)).perform(click());
         // Check that the SearchView is displayed
         onView(withId(R.id.search_bar)).check(matches(isDisplayed()));
 
@@ -180,6 +179,36 @@
         assertEquals("onKeyDown event matches", KeyEvent.KEYCODE_MENU, upEvent.getKeyCode());
     }
 
+    @Test
+    @SmallTest
+    public void testActionMenuContent() throws Throwable {
+        onView(withId(R.id.action_search))
+                .check(matches(isDisplayed()))
+                .check(matches(withContentDescription(R.string.search_menu_description)));
+
+        onView(withId(R.id.action_alpha_shortcut))
+                .check(matches(isDisplayed()))
+                .check(matches(withContentDescription(R.string.alpha_menu_title)));
+
+        Menu menu = getActivity().getMenu();
+        final MenuItem alphaItem = menu.findItem(R.id.action_alpha_shortcut);
+        assertNotNull(alphaItem);
+
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                MenuItemCompat.setContentDescription(alphaItem,
+                        getActivity().getString(R.string.alpha_menu_description));
+                MenuItemCompat.setTooltipText(alphaItem,
+                        getActivity().getString(R.string.alpha_menu_tooltip));
+            }
+        });
+
+        onView(withId(R.id.action_alpha_shortcut))
+                .check(matches(isDisplayed()))
+                .check(matches(withContentDescription(R.string.alpha_menu_description)));
+    }
+
     private void repopulateWithEmptyMenu() throws InterruptedException {
         int count = 0;
         getActivity().setShouldPopulateOptionsMenu(false);
diff --git a/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutTest.java b/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutTest.java
index 3fe899d..9b8051e 100755
--- a/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutTest.java
@@ -46,7 +46,6 @@
 import android.support.test.espresso.action.Swipe;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
-import android.support.test.filters.SmallTest;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.widget.DrawerLayout;
 import android.support.v7.appcompat.test.R;
@@ -246,7 +245,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testDrawerHeight() {
         // Open the drawer so it becomes visible
         onView(withId(R.id.drawer_layout)).perform(openDrawer(GravityCompat.START));
@@ -289,7 +288,7 @@
     // Tests for listener(s) being notified of various events
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testDrawerListenerCallbacksOnOpeningViaAPI() {
         // Register a mock listener
         DrawerLayout.DrawerListener mockedListener = mock(DrawerLayout.DrawerListener.class);
@@ -326,7 +325,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testDrawerListenerCallbacksOnOpeningNoAnimationViaAPI() {
         // Register a mock listener
         DrawerLayout.DrawerListener mockedListener = mock(DrawerLayout.DrawerListener.class);
@@ -355,7 +354,7 @@
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testDrawerListenerCallbacksOnClosingViaAPI() {
         // Open the drawer so it becomes visible
         onView(withId(R.id.drawer_layout)).perform(openDrawer(GravityCompat.START));
@@ -395,7 +394,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testDrawerListenerCallbacksOnClosingNoAnimationViaAPI() {
         // Open the drawer so it becomes visible
         onView(withId(R.id.drawer_layout)).perform(openDrawer(GravityCompat.START, false));
@@ -427,7 +426,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testDrawerListenerCallbacksOnOpeningViaSwipes() {
         // Register a mock listener
         DrawerLayout.DrawerListener mockedListener = mock(DrawerLayout.DrawerListener.class);
@@ -472,7 +471,7 @@
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testDrawerListenerCallbacksOnClosingViaSwipes() {
         // Open the drawer so it becomes visible
         onView(withId(R.id.drawer_layout)).perform(openDrawer(GravityCompat.START));
@@ -520,7 +519,7 @@
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testDrawerLockUnlock() {
         assertEquals("Drawer is unlocked in initial state",
                 DrawerLayout.LOCK_MODE_UNLOCKED, mDrawerLayout.getDrawerLockMode(mStartDrawer));
diff --git a/v7/appcompat/tests/src/android/support/v7/app/NightModeTestCase.java b/v7/appcompat/tests/src/android/support/v7/app/NightModeTestCase.java
index 7564e94..2168069 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/NightModeTestCase.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/NightModeTestCase.java
@@ -27,15 +27,15 @@
 
 import android.app.Instrumentation;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.v4.content.ContextCompat;
 import android.support.v7.appcompat.test.R;
-import android.test.suitebuilder.annotation.MediumTest;
 
 import org.junit.Before;
 import org.junit.Test;
 
-@MediumTest
+@LargeTest
 @SdkSuppress(minSdkVersion = 14)
 public class NightModeTestCase extends BaseInstrumentationTestCase<NightModeActivity> {
 
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/ListPopupWindowTest.java b/v7/appcompat/tests/src/android/support/v7/widget/ListPopupWindowTest.java
index 34c07a3..907e653 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/ListPopupWindowTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/ListPopupWindowTest.java
@@ -46,7 +46,6 @@
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
-import android.support.test.filters.SmallTest;
 import android.support.v7.app.BaseInstrumentationTestCase;
 import android.support.v7.appcompat.test.R;
 import android.view.LayoutInflater;
@@ -100,7 +99,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testBasicContent() {
         Builder popupBuilder = new Builder();
         popupBuilder.wireToActionButton();
@@ -154,7 +153,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testDismissalViaAPI() throws Throwable {
         Builder popupBuilder = new Builder().withDismissListener();
         popupBuilder.wireToActionButton();
@@ -241,19 +240,19 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testDismissalOutsideNonModal() throws Throwable {
         testDismissalViaTouch(false);
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testDismissalOutsideModal() throws Throwable {
         testDismissalViaTouch(true);
     }
 
     @Test
-    @SmallTest
+    @LargeTest
     public void testItemClickViaEvent() {
         Builder popupBuilder = new Builder().withItemClickListener();
         popupBuilder.wireToActionButton();
@@ -280,7 +279,7 @@
     }
 
     @Test
-    @SmallTest
+    @MediumTest
     public void testItemClickViaAPI() throws Throwable {
         Builder popupBuilder = new Builder().withItemClickListener();
         popupBuilder.wireToActionButton();
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/PopupMenuTest.java b/v7/appcompat/tests/src/android/support/v7/widget/PopupMenuTest.java
index 7d6e39f..82a6d12 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/PopupMenuTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/PopupMenuTest.java
@@ -51,8 +51,10 @@
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
+import android.support.v4.view.MenuItemCompat;
 import android.support.v7.app.BaseInstrumentationTestCase;
 import android.support.v7.appcompat.test.R;
+import android.text.TextUtils;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.MotionEvent;
@@ -101,12 +103,32 @@
 
     @Test
     @MediumTest
-    public void testBasicContent() {
+    public void testBasicContent() throws Throwable {
         final Builder menuBuilder = new Builder();
         menuBuilder.wireToActionButton();
 
         onView(withId(R.id.test_button)).perform(click());
         assertNotNull("Popup menu created", mPopupMenu);
+
+        final MenuItem hightlightItem = mPopupMenu.getMenu().findItem(R.id.action_highlight);
+        assertEquals(mResources.getString(R.string.popup_menu_highlight_description),
+                MenuItemCompat.getContentDescription(hightlightItem));
+        assertEquals(mResources.getString(R.string.popup_menu_highlight_tooltip),
+                MenuItemCompat.getTooltipText(hightlightItem));
+
+        final MenuItem editItem = mPopupMenu.getMenu().findItem(R.id.action_edit);
+        assertNotNull(MenuItemCompat.getContentDescription(hightlightItem));
+        assertNotNull(MenuItemCompat.getTooltipText(hightlightItem));
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                MenuItemCompat.setContentDescription(editItem,
+                        mResources.getString(R.string.popup_menu_edit_description));
+                MenuItemCompat.setTooltipText(editItem,
+                        mResources.getString(R.string.popup_menu_edit_tooltip));
+            }
+        });
+
         // Unlike ListPopupWindow, PopupMenu doesn't have an API to check whether it is showing.
         // Use a custom matcher to check the visibility of the drop down list view instead.
         onView(withClassName(Matchers.is(DROP_DOWN_CLASS_NAME)))
@@ -120,11 +142,15 @@
         onData(anything()).atPosition(0).check(matches(isDisplayed()));
         onView(withText(mResources.getString(R.string.popup_menu_highlight)))
                 .inRoot(withDecorView(not(is(mMainDecorView))))
-                .check(matches(isDisplayed()));
+                .check(matches(isDisplayed()))
+                .check(matches(selfOrParentWithContentDescription(
+                        mResources.getString(R.string.popup_menu_highlight_description))));
         onData(anything()).atPosition(1).check(matches(isDisplayed()));
         onView(withText(mResources.getString(R.string.popup_menu_edit)))
                 .inRoot(withDecorView(not(is(mMainDecorView))))
-                .check(matches(isDisplayed()));
+                .check(matches(isDisplayed()))
+                .check(matches(selfOrParentWithContentDescription(
+                        mResources.getString(R.string.popup_menu_edit_description))));
         onData(anything()).atPosition(2).check(matches(isDisplayed()));
         onView(withText(mResources.getString(R.string.popup_menu_delete)))
                 .inRoot(withDecorView(not(is(mMainDecorView))))
@@ -601,4 +627,33 @@
             });
         }
     }
+
+    private static Matcher<View> selfOrParentWithContentDescription(final CharSequence expected) {
+        return new TypeSafeMatcher<View>() {
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("self of parent has content description: " + expected);
+            }
+
+            @Override
+            public boolean matchesSafely(View view) {
+                return TextUtils.equals(expected, getSelfOrParentContentDescription(view));
+            }
+
+            private CharSequence getSelfOrParentContentDescription(View view) {
+                while (view != null) {
+                    final CharSequence contentDescription = view.getContentDescription();
+                    if (contentDescription != null) {
+                        return contentDescription;
+                    }
+                    final ViewParent parent = view.getParent();
+                    if (!(parent instanceof View)) {
+                        break;
+                    }
+                    view = (View) parent;
+                }
+                return null;
+            }
+        };
+    }
 }
diff --git a/v7/cardview/Android.mk b/v7/cardview/Android.mk
index 40f6b23..cd3b407 100644
--- a/v7/cardview/Android.mk
+++ b/v7/cardview/Android.mk
@@ -31,7 +31,6 @@
     $(call all-java-files-under,api21) \
     $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-annotations
 LOCAL_JAR_EXCLUDE_FILES := none
diff --git a/v7/cardview/AndroidManifest-make.xml b/v7/cardview/AndroidManifest-make.xml
deleted file mode 100644
index c35e369..0000000
--- a/v7/cardview/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.v7.cardview">
-    <uses-sdk android:minSdkVersion="9"/>
-    <application />
-</manifest>
diff --git a/v7/cardview/AndroidManifest.xml b/v7/cardview/AndroidManifest.xml
index e85003c..b83c815 100644
--- a/v7/cardview/AndroidManifest.xml
+++ b/v7/cardview/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.cardview">
-    <uses-sdk android:minSdkVersion="9"/>
+    <uses-sdk android:minSdkVersion="14"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/v7/cardview/api21/android/support/v7/widget/CardViewApi21.java b/v7/cardview/api21/android/support/v7/widget/CardViewApi21.java
index b4f2460..7942895 100644
--- a/v7/cardview/api21/android/support/v7/widget/CardViewApi21.java
+++ b/v7/cardview/api21/android/support/v7/widget/CardViewApi21.java
@@ -15,7 +15,6 @@
  */
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.support.annotation.Nullable;
@@ -23,7 +22,6 @@
 import android.view.View;
 
 @RequiresApi(21)
-@TargetApi(21)
 class CardViewApi21 implements CardViewImpl {
 
     @Override
diff --git a/v7/cardview/api21/android/support/v7/widget/RoundRectDrawable.java b/v7/cardview/api21/android/support/v7/widget/RoundRectDrawable.java
index 7e85b7f..09cc205 100644
--- a/v7/cardview/api21/android/support/v7/widget/RoundRectDrawable.java
+++ b/v7/cardview/api21/android/support/v7/widget/RoundRectDrawable.java
@@ -15,7 +15,6 @@
  */
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -41,7 +40,6 @@
  * Simpler and uses less resources compared to GradientDrawable or ShapeDrawable.
  */
 @RequiresApi(21)
-@TargetApi(21)
 class RoundRectDrawable extends Drawable {
     private float mRadius;
     private final Paint mPaint;
diff --git a/v7/cardview/base/android/support/v7/widget/CardViewDelegate.java b/v7/cardview/base/android/support/v7/widget/CardViewDelegate.java
index 2573631..b710b46 100644
--- a/v7/cardview/base/android/support/v7/widget/CardViewDelegate.java
+++ b/v7/cardview/base/android/support/v7/widget/CardViewDelegate.java
@@ -15,7 +15,6 @@
  */
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.RequiresApi;
 import android.view.View;
@@ -26,7 +25,6 @@
  * Necessary to resolve circular dependency between base CardView and platform implementations.
  */
 @RequiresApi(9)
-@TargetApi(9)
 interface CardViewDelegate {
     void setCardBackground(Drawable drawable);
     Drawable getCardBackground();
diff --git a/v7/cardview/base/android/support/v7/widget/CardViewImpl.java b/v7/cardview/base/android/support/v7/widget/CardViewImpl.java
index f36bd2b..d9439ae 100644
--- a/v7/cardview/base/android/support/v7/widget/CardViewImpl.java
+++ b/v7/cardview/base/android/support/v7/widget/CardViewImpl.java
@@ -15,7 +15,6 @@
  */
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.support.annotation.Nullable;
@@ -25,7 +24,6 @@
  * Interface for platform specific CardView implementations.
  */
 @RequiresApi(9)
-@TargetApi(9)
 interface CardViewImpl {
     void initialize(CardViewDelegate cardView, Context context, ColorStateList backgroundColor,
             float radius, float elevation, float maxElevation);
diff --git a/v7/cardview/build.gradle b/v7/cardview/build.gradle
index ce3f28d..f45350e 100644
--- a/v7/cardview/build.gradle
+++ b/v7/cardview/build.gradle
@@ -1,4 +1,4 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'cardview-v7'
 
 dependencies {
@@ -6,14 +6,11 @@
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'base',
                 'gingerbread',
@@ -23,59 +20,10 @@
         ]
         main.res.srcDir 'res'
     }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support CardView v7'
-                description "Android Support CardView v7"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support CardView v7'
+    inceptionYear '2011'
+    description 'Android Support CardView v7'
 }
diff --git a/v7/cardview/gingerbread/android/support/v7/widget/CardViewGingerbread.java b/v7/cardview/gingerbread/android/support/v7/widget/CardViewGingerbread.java
index f430213..298505b 100644
--- a/v7/cardview/gingerbread/android/support/v7/widget/CardViewGingerbread.java
+++ b/v7/cardview/gingerbread/android/support/v7/widget/CardViewGingerbread.java
@@ -15,7 +15,6 @@
  */
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.Canvas;
@@ -27,7 +26,6 @@
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(9)
-@TargetApi(9)
 class CardViewGingerbread implements CardViewImpl {
 
     final RectF sCornerRect = new RectF();
diff --git a/v7/cardview/gingerbread/android/support/v7/widget/RoundRectDrawableWithShadow.java b/v7/cardview/gingerbread/android/support/v7/widget/RoundRectDrawableWithShadow.java
index 32bf877..3b33ccf 100644
--- a/v7/cardview/gingerbread/android/support/v7/widget/RoundRectDrawableWithShadow.java
+++ b/v7/cardview/gingerbread/android/support/v7/widget/RoundRectDrawableWithShadow.java
@@ -15,7 +15,6 @@
  */
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Canvas;
@@ -38,7 +37,6 @@
  * A rounded rectangle drawable which also includes a shadow around.
  */
 @RequiresApi(9)
-@TargetApi(9)
 class RoundRectDrawableWithShadow extends Drawable {
     // used to calculate content padding
     final static double COS_45 = Math.cos(Math.toRadians(45));
diff --git a/v7/cardview/jellybean-mr1/android/support/v7/widget/CardViewJellybeanMr1.java b/v7/cardview/jellybean-mr1/android/support/v7/widget/CardViewJellybeanMr1.java
index a9c0e0a..a9ed03f 100644
--- a/v7/cardview/jellybean-mr1/android/support/v7/widget/CardViewJellybeanMr1.java
+++ b/v7/cardview/jellybean-mr1/android/support/v7/widget/CardViewJellybeanMr1.java
@@ -15,14 +15,12 @@
  */
 package android.support.v7.widget;
 
-import android.annotation.TargetApi;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.RectF;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(17)
-@TargetApi(17)
 class CardViewJellybeanMr1 extends CardViewGingerbread {
 
     @Override
diff --git a/v7/gridlayout/Android.mk b/v7/gridlayout/Android.mk
index c584dbe..6eac23b4 100644
--- a/v7/gridlayout/Android.mk
+++ b/v7/gridlayout/Android.mk
@@ -29,7 +29,6 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-core-ui \
diff --git a/v7/gridlayout/AndroidManifest-make.xml b/v7/gridlayout/AndroidManifest-make.xml
deleted file mode 100644
index d2cc627..0000000
--- a/v7/gridlayout/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.v7.gridlayout">
-    <uses-sdk android:minSdkVersion="9"/>
-    <application />
-</manifest>
diff --git a/v7/gridlayout/AndroidManifest.xml b/v7/gridlayout/AndroidManifest.xml
index dfcc942..6f12842 100644
--- a/v7/gridlayout/AndroidManifest.xml
+++ b/v7/gridlayout/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.gridlayout">
-    <uses-sdk android:minSdkVersion="9"/>
+    <uses-sdk android:minSdkVersion="14"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/v7/gridlayout/build.gradle b/v7/gridlayout/build.gradle
index 56f320f..63d149f 100644
--- a/v7/gridlayout/build.gradle
+++ b/v7/gridlayout/build.gradle
@@ -1,95 +1,33 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'gridlayout-v7'
 
 dependencies {
     compile project(':support-compat')
     compile project(':support-core-ui')
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    testCompile 'junit:junit:4.12'
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDir 'src'
         main.res.srcDir 'res'
         main.assets.srcDir 'assets'
         main.resources.srcDir 'src'
-
-        // this moves src/instrumentTest to tests so all folders follow:
-        // tests/java, tests/res, tests/assets, ...
-        // This is a *reset* so it replaces the default paths
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Library v4'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support Grid Layout'
+    inceptionYear '2013'
+    description 'Android Support Grid Layout'
 }
diff --git a/v7/gridlayout/src/android/support/v7/widget/GridLayout.java b/v7/gridlayout/src/android/support/v7/widget/GridLayout.java
index 8dc04dc..ad9ece5 100644
--- a/v7/gridlayout/src/android/support/v7/widget/GridLayout.java
+++ b/v7/gridlayout/src/android/support/v7/widget/GridLayout.java
@@ -16,6 +16,19 @@
 
 package android.support.v7.widget;
 
+import static android.view.Gravity.AXIS_PULL_AFTER;
+import static android.view.Gravity.AXIS_PULL_BEFORE;
+import static android.view.Gravity.AXIS_SPECIFIED;
+import static android.view.Gravity.AXIS_X_SHIFT;
+import static android.view.Gravity.AXIS_Y_SHIFT;
+import static android.view.Gravity.HORIZONTAL_GRAVITY_MASK;
+import static android.view.Gravity.VERTICAL_GRAVITY_MASK;
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
+
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -23,6 +36,7 @@
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.ViewGroupCompat;
+import android.support.v7.gridlayout.R;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.LogPrinter;
@@ -33,8 +47,6 @@
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
-import android.support.v7.gridlayout.R;
-
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -42,12 +54,6 @@
 import java.util.List;
 import java.util.Map;
 
-import static android.view.Gravity.*;
-import static android.view.View.MeasureSpec.EXACTLY;
-import static android.view.View.MeasureSpec.makeMeasureSpec;
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-
 /**
  * A layout that places its children in a rectangular <em>grid</em>.
  * <p>
@@ -968,8 +974,8 @@
         int measuredHeight = Math.max(heightSansPadding + vPadding, getSuggestedMinimumHeight());
 
         setMeasuredDimension(
-                ViewCompat.resolveSizeAndState(measuredWidth, widthSpec, 0),
-                ViewCompat.resolveSizeAndState(measuredHeight, heightSpec, 0));
+                View.resolveSizeAndState(measuredWidth, widthSpec, 0),
+                View.resolveSizeAndState(measuredHeight, heightSpec, 0));
     }
 
     private int getMeasurement(View c, boolean horizontal) {
diff --git a/v7/gridlayout/tests/AndroidManifest.xml b/v7/gridlayout/tests/AndroidManifest.xml
index 4c4b0ab..cbc80a0 100644
--- a/v7/gridlayout/tests/AndroidManifest.xml
+++ b/v7/gridlayout/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.v7.gridlayout.test">
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                   android.support.test.espresso, android.support.test.espresso.idling" />
diff --git a/v7/mediarouter/Android.mk b/v7/mediarouter/Android.mk
index 6162f87..21b4a62 100644
--- a/v7/mediarouter/Android.mk
+++ b/v7/mediarouter/Android.mk
@@ -35,7 +35,6 @@
     $(call all-java-files-under,api24) \
     $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-v7-appcompat \
     android-support-v7-palette \
diff --git a/v7/mediarouter/AndroidManifest-make.xml b/v7/mediarouter/AndroidManifest-make.xml
deleted file mode 100644
index 59d9f99..0000000
--- a/v7/mediarouter/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.v7.mediarouter">
-    <uses-sdk android:minSdkVersion="9"/>
-    <application />
-</manifest>
diff --git a/v7/mediarouter/AndroidManifest.xml b/v7/mediarouter/AndroidManifest.xml
index bbebdfe..5466168 100644
--- a/v7/mediarouter/AndroidManifest.xml
+++ b/v7/mediarouter/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.mediarouter">
-    <uses-sdk android:minSdkVersion="9"/>
+    <uses-sdk android:minSdkVersion="14"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/v7/mediarouter/api24/android/support/v7/media/MediaRouterApi24.java b/v7/mediarouter/api24/android/support/v7/media/MediaRouterApi24.java
index 48bef17..0b1eda9 100644
--- a/v7/mediarouter/api24/android/support/v7/media/MediaRouterApi24.java
+++ b/v7/mediarouter/api24/android/support/v7/media/MediaRouterApi24.java
@@ -16,11 +16,9 @@
 
 package android.support.v7.media;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(24)
-@TargetApi(24)
 final class MediaRouterApi24 {
     public static final class RouteInfo {
         public static int getDeviceType(Object routeObj) {
diff --git a/v7/mediarouter/build.gradle b/v7/mediarouter/build.gradle
index 7796565..d0448dd 100644
--- a/v7/mediarouter/build.gradle
+++ b/v7/mediarouter/build.gradle
@@ -1,25 +1,19 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'mediarouter-v7'
 
 dependencies {
     compile project(":support-appcompat-v7")
     compile project(":support-palette-v7")
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}")
-    testCompile 'junit:junit:4.12'
+    androidTestCompile libs.test_runner
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDirs = [
                 'jellybean',
                 'jellybean-mr1',
@@ -28,65 +22,11 @@
                 'src'
         ]
         main.res.srcDir 'res'
-
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android MediaRouter Support Library'
-                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android MediaRouter Support Library'
+    inceptionYear '2013'
+    description 'Android MediaRouter Support Library'
 }
diff --git a/v7/mediarouter/jellybean-mr1/android/support/v7/media/MediaRouterJellybeanMr1.java b/v7/mediarouter/jellybean-mr1/android/support/v7/media/MediaRouterJellybeanMr1.java
index 3a42a2f..6fc5ba5 100644
--- a/v7/mediarouter/jellybean-mr1/android/support/v7/media/MediaRouterJellybeanMr1.java
+++ b/v7/mediarouter/jellybean-mr1/android/support/v7/media/MediaRouterJellybeanMr1.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.media;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.hardware.display.DisplayManager;
 import android.os.Build;
@@ -30,7 +29,6 @@
 import java.lang.reflect.Method;
 
 @RequiresApi(17)
-@TargetApi(17)
 final class MediaRouterJellybeanMr1 {
     private static final String TAG = "MediaRouterJellybeanMr1";
 
diff --git a/v7/mediarouter/jellybean-mr2/android/support/v7/media/MediaRouterJellybeanMr2.java b/v7/mediarouter/jellybean-mr2/android/support/v7/media/MediaRouterJellybeanMr2.java
index 6799faa..8abfc7f 100644
--- a/v7/mediarouter/jellybean-mr2/android/support/v7/media/MediaRouterJellybeanMr2.java
+++ b/v7/mediarouter/jellybean-mr2/android/support/v7/media/MediaRouterJellybeanMr2.java
@@ -16,11 +16,9 @@
 
 package android.support.v7.media;
 
-import android.annotation.TargetApi;
 import android.support.annotation.RequiresApi;
 
 @RequiresApi(18)
-@TargetApi(18)
 final class MediaRouterJellybeanMr2 {
     public static Object getDefaultRoute(Object routerObj) {
         return ((android.media.MediaRouter)routerObj).getDefaultRoute();
diff --git a/v7/mediarouter/jellybean/android/support/v7/media/MediaRouterJellybean.java b/v7/mediarouter/jellybean/android/support/v7/media/MediaRouterJellybean.java
index 2613f90..0a090a5 100644
--- a/v7/mediarouter/jellybean/android/support/v7/media/MediaRouterJellybean.java
+++ b/v7/mediarouter/jellybean/android/support/v7/media/MediaRouterJellybean.java
@@ -16,7 +16,6 @@
 
 package android.support.v7.media;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
@@ -31,7 +30,6 @@
 import java.util.List;
 
 @RequiresApi(16)
-@TargetApi(16)
 final class MediaRouterJellybean {
     private static final String TAG = "MediaRouterJellybean";
 
diff --git a/v7/mediarouter/res/values-az-rAZ/strings.xml b/v7/mediarouter/res/values-az/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-az-rAZ/strings.xml
rename to v7/mediarouter/res/values-az/strings.xml
diff --git a/v7/mediarouter/res/values-b+sr+Latn/strings.xml b/v7/mediarouter/res/values-b+sr+Latn/strings.xml
index 8075d2e..4bc9baa 100644
--- a/v7/mediarouter/res/values-b+sr+Latn/strings.xml
+++ b/v7/mediarouter/res/values-b+sr+Latn/strings.xml
@@ -22,7 +22,7 @@
     <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Dugme Prebaci. Veza je prekinuta"</string>
     <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Dugme Prebaci. Povezuje se"</string>
     <string name="mr_cast_button_connected" msgid="5088427771788648085">"Dugme Prebaci. Povezan je"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Prebacujte na"</string>
+    <string name="mr_chooser_title" msgid="414301941546135990">"Prebacuj na"</string>
     <string name="mr_chooser_searching" msgid="6349900579507521956">"Pronalaženje uređaja"</string>
     <string name="mr_controller_disconnect" msgid="1227264889412989580">"Prekini vezu"</string>
     <string name="mr_controller_stop" msgid="4570331844078181931">"Zaustavi prebacivanje"</string>
diff --git a/v7/mediarouter/res/values-be-rBY/strings.xml b/v7/mediarouter/res/values-be/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-be-rBY/strings.xml
rename to v7/mediarouter/res/values-be/strings.xml
diff --git a/v7/mediarouter/res/values-bn-rBD/strings.xml b/v7/mediarouter/res/values-bn/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-bn-rBD/strings.xml
rename to v7/mediarouter/res/values-bn/strings.xml
diff --git a/v7/mediarouter/res/values-bs-rBA/strings.xml b/v7/mediarouter/res/values-bs/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-bs-rBA/strings.xml
rename to v7/mediarouter/res/values-bs/strings.xml
diff --git a/v7/mediarouter/res/values-et-rEE/strings.xml b/v7/mediarouter/res/values-et/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-et-rEE/strings.xml
rename to v7/mediarouter/res/values-et/strings.xml
diff --git a/v7/mediarouter/res/values-eu-rES/strings.xml b/v7/mediarouter/res/values-eu/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-eu-rES/strings.xml
rename to v7/mediarouter/res/values-eu/strings.xml
diff --git a/v7/mediarouter/res/values-gl-rES/strings.xml b/v7/mediarouter/res/values-gl/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-gl-rES/strings.xml
rename to v7/mediarouter/res/values-gl/strings.xml
diff --git a/v7/mediarouter/res/values-gu-rIN/strings.xml b/v7/mediarouter/res/values-gu/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-gu-rIN/strings.xml
rename to v7/mediarouter/res/values-gu/strings.xml
diff --git a/v7/mediarouter/res/values-hi/strings.xml b/v7/mediarouter/res/values-hi/strings.xml
index e74967e..5b01c7c 100644
--- a/v7/mediarouter/res/values-hi/strings.xml
+++ b/v7/mediarouter/res/values-hi/strings.xml
@@ -19,12 +19,12 @@
     <string name="mr_system_route_name" msgid="5441529851481176817">"सिस्टम"</string>
     <string name="mr_user_route_category_name" msgid="7498112907524977311">"डिवाइस"</string>
     <string name="mr_button_content_description" msgid="3698378085901466129">"कास्ट करें बटन"</string>
-    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"कास्ट करें बटन. डिस्कनेक्ट है"</string>
+    <string name="mr_cast_button_disconnected" msgid="816305490427819240">"कास्ट करें बटन. डिसकनेक्ट है"</string>
     <string name="mr_cast_button_connecting" msgid="2187642765091873834">"कास्ट करें बटन. कनेक्ट हो रहा है"</string>
     <string name="mr_cast_button_connected" msgid="5088427771788648085">"कास्ट करें बटन. कनेक्ट है"</string>
     <string name="mr_chooser_title" msgid="414301941546135990">"इस पर कास्‍ट करें"</string>
     <string name="mr_chooser_searching" msgid="6349900579507521956">"डिवाइस ढूंढ रहा है"</string>
-    <string name="mr_controller_disconnect" msgid="1227264889412989580">"डिस्कनेक्ट करें"</string>
+    <string name="mr_controller_disconnect" msgid="1227264889412989580">"डिसकनेक्ट करें"</string>
     <string name="mr_controller_stop" msgid="4570331844078181931">"कास्ट करना बंद करें"</string>
     <string name="mr_controller_close_description" msgid="7333862312480583260">"बंद करें"</string>
     <string name="mr_controller_play" msgid="683634565969987458">"चलाएं"</string>
diff --git a/v7/mediarouter/res/values-hy-rAM/strings.xml b/v7/mediarouter/res/values-hy/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-hy-rAM/strings.xml
rename to v7/mediarouter/res/values-hy/strings.xml
diff --git a/v7/mediarouter/res/values-is-rIS/strings.xml b/v7/mediarouter/res/values-is/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-is-rIS/strings.xml
rename to v7/mediarouter/res/values-is/strings.xml
diff --git a/v7/mediarouter/res/values-ka-rGE/strings.xml b/v7/mediarouter/res/values-ka/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-ka-rGE/strings.xml
rename to v7/mediarouter/res/values-ka/strings.xml
diff --git a/v7/mediarouter/res/values-kk-rKZ/strings.xml b/v7/mediarouter/res/values-kk/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-kk-rKZ/strings.xml
rename to v7/mediarouter/res/values-kk/strings.xml
diff --git a/v7/mediarouter/res/values-km-rKH/strings.xml b/v7/mediarouter/res/values-km/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-km-rKH/strings.xml
rename to v7/mediarouter/res/values-km/strings.xml
diff --git a/v7/mediarouter/res/values-kn-rIN/strings.xml b/v7/mediarouter/res/values-kn/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-kn-rIN/strings.xml
rename to v7/mediarouter/res/values-kn/strings.xml
diff --git a/v7/mediarouter/res/values-ky-rKG/strings.xml b/v7/mediarouter/res/values-ky/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-ky-rKG/strings.xml
rename to v7/mediarouter/res/values-ky/strings.xml
diff --git a/v7/mediarouter/res/values-lo-rLA/strings.xml b/v7/mediarouter/res/values-lo/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-lo-rLA/strings.xml
rename to v7/mediarouter/res/values-lo/strings.xml
diff --git a/v7/mediarouter/res/values-mk-rMK/strings.xml b/v7/mediarouter/res/values-mk/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-mk-rMK/strings.xml
rename to v7/mediarouter/res/values-mk/strings.xml
diff --git a/v7/mediarouter/res/values-ml-rIN/strings.xml b/v7/mediarouter/res/values-ml/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-ml-rIN/strings.xml
rename to v7/mediarouter/res/values-ml/strings.xml
diff --git a/v7/mediarouter/res/values-mn-rMN/strings.xml b/v7/mediarouter/res/values-mn/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-mn-rMN/strings.xml
rename to v7/mediarouter/res/values-mn/strings.xml
diff --git a/v7/mediarouter/res/values-mr-rIN/strings.xml b/v7/mediarouter/res/values-mr/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-mr-rIN/strings.xml
rename to v7/mediarouter/res/values-mr/strings.xml
diff --git a/v7/mediarouter/res/values-ms-rMY/strings.xml b/v7/mediarouter/res/values-ms/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-ms-rMY/strings.xml
rename to v7/mediarouter/res/values-ms/strings.xml
diff --git a/v7/mediarouter/res/values-my-rMM/strings.xml b/v7/mediarouter/res/values-my/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-my-rMM/strings.xml
rename to v7/mediarouter/res/values-my/strings.xml
diff --git a/v7/mediarouter/res/values-ne-rNP/strings.xml b/v7/mediarouter/res/values-ne/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-ne-rNP/strings.xml
rename to v7/mediarouter/res/values-ne/strings.xml
diff --git a/v7/mediarouter/res/values-pa-rIN/strings.xml b/v7/mediarouter/res/values-pa/strings.xml
similarity index 98%
rename from v7/mediarouter/res/values-pa-rIN/strings.xml
rename to v7/mediarouter/res/values-pa/strings.xml
index 258529d..c207246 100644
--- a/v7/mediarouter/res/values-pa-rIN/strings.xml
+++ b/v7/mediarouter/res/values-pa/strings.xml
@@ -25,7 +25,7 @@
     <string name="mr_chooser_title" msgid="414301941546135990">"ਇਸ ਨਾਲ ਕਾਸਟ ਕਰੋ"</string>
     <string name="mr_chooser_searching" msgid="6349900579507521956">"ਡਿਵਾਈਸਾਂ ਲੱਭ ਰਿਹਾ ਹੈ"</string>
     <string name="mr_controller_disconnect" msgid="1227264889412989580">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
-    <string name="mr_controller_stop" msgid="4570331844078181931">"ਜੋੜਨਾ ਰੋਕੋ"</string>
+    <string name="mr_controller_stop" msgid="4570331844078181931">"ਕਾਸਟ ਕਰਨਾ ਰੋਕੋ"</string>
     <string name="mr_controller_close_description" msgid="7333862312480583260">"ਬੰਦ ਕਰੋ"</string>
     <string name="mr_controller_play" msgid="683634565969987458">"ਪਲੇ ਕਰੋ"</string>
     <string name="mr_controller_pause" msgid="5451884435510905406">"ਰੋਕੋ"</string>
diff --git a/v7/mediarouter/res/values-si-rLK/strings.xml b/v7/mediarouter/res/values-si/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-si-rLK/strings.xml
rename to v7/mediarouter/res/values-si/strings.xml
diff --git a/v7/mediarouter/res/values-sq-rAL/strings.xml b/v7/mediarouter/res/values-sq/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-sq-rAL/strings.xml
rename to v7/mediarouter/res/values-sq/strings.xml
diff --git a/v7/mediarouter/res/values-sr/strings.xml b/v7/mediarouter/res/values-sr/strings.xml
index bddc045..ef1b2b1 100644
--- a/v7/mediarouter/res/values-sr/strings.xml
+++ b/v7/mediarouter/res/values-sr/strings.xml
@@ -22,7 +22,7 @@
     <string name="mr_cast_button_disconnected" msgid="816305490427819240">"Дугме Пребаци. Веза је прекинута"</string>
     <string name="mr_cast_button_connecting" msgid="2187642765091873834">"Дугме Пребаци. Повезује се"</string>
     <string name="mr_cast_button_connected" msgid="5088427771788648085">"Дугме Пребаци. Повезан је"</string>
-    <string name="mr_chooser_title" msgid="414301941546135990">"Пребацујте на"</string>
+    <string name="mr_chooser_title" msgid="414301941546135990">"Пребацуј на"</string>
     <string name="mr_chooser_searching" msgid="6349900579507521956">"Проналажење уређаја"</string>
     <string name="mr_controller_disconnect" msgid="1227264889412989580">"Прекини везу"</string>
     <string name="mr_controller_stop" msgid="4570331844078181931">"Заустави пребацивање"</string>
diff --git a/v7/mediarouter/res/values-ta-rIN/strings.xml b/v7/mediarouter/res/values-ta/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-ta-rIN/strings.xml
rename to v7/mediarouter/res/values-ta/strings.xml
diff --git a/v7/mediarouter/res/values-te-rIN/strings.xml b/v7/mediarouter/res/values-te/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-te-rIN/strings.xml
rename to v7/mediarouter/res/values-te/strings.xml
diff --git a/v7/mediarouter/res/values-ur-rPK/strings.xml b/v7/mediarouter/res/values-ur/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-ur-rPK/strings.xml
rename to v7/mediarouter/res/values-ur/strings.xml
diff --git a/v7/mediarouter/res/values-uz-rUZ/strings.xml b/v7/mediarouter/res/values-uz/strings.xml
similarity index 100%
rename from v7/mediarouter/res/values-uz-rUZ/strings.xml
rename to v7/mediarouter/res/values-uz/strings.xml
diff --git a/v7/mediarouter/res/values-zh-rCN/strings.xml b/v7/mediarouter/res/values-zh-rCN/strings.xml
index c22a91c..30c7dcc 100644
--- a/v7/mediarouter/res/values-zh-rCN/strings.xml
+++ b/v7/mediarouter/res/values-zh-rCN/strings.xml
@@ -30,7 +30,7 @@
     <string name="mr_controller_play" msgid="683634565969987458">"播放"</string>
     <string name="mr_controller_pause" msgid="5451884435510905406">"暂停"</string>
     <string name="mr_controller_expand_group" msgid="8062427022744266907">"展开"</string>
-    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"折叠"</string>
+    <string name="mr_controller_collapse_group" msgid="7924809056904240926">"收起"</string>
     <string name="mr_controller_album_art" msgid="6422801843540543585">"专辑封面"</string>
     <string name="mr_controller_volume_slider" msgid="2361785992211841709">"音量滑块"</string>
     <string name="mr_controller_no_media_selected" msgid="6547130360349182381">"未选择任何媒体"</string>
diff --git a/v7/mediarouter/res/values/attrs.xml b/v7/mediarouter/res/values/attrs.xml
index c618fd8..cf6a7b5 100644
--- a/v7/mediarouter/res/values/attrs.xml
+++ b/v7/mediarouter/res/values/attrs.xml
@@ -22,7 +22,7 @@
              that media is playing to the local device only. -->
         <attr name="externalRouteEnabledDrawable" format="reference" />
         <!-- Tint to apply to the media route button -->
-        <attr name="buttonTint" />
+        <attr name="buttonTint" format="color" />
 
         <attr name="android:minWidth" />
         <attr name="android:minHeight" />
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
index 2da193b..5b9d556 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
@@ -22,24 +22,20 @@
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
-import android.graphics.Rect;
 import android.graphics.drawable.AnimationDrawable;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.NonNull;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.graphics.drawable.DrawableCompat;
-import android.support.v4.view.GravityCompat;
+import android.support.v4.view.ViewCompat;
 import android.support.v7.media.MediaRouteSelector;
 import android.support.v7.media.MediaRouter;
 import android.support.v7.mediarouter.R;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.view.Gravity;
-import android.view.HapticFeedbackConstants;
 import android.view.SoundEffectConstants;
 import android.view.View;
-import android.widget.Toast;
 
 /**
  * The media route button allows the user to select routes and to control the
@@ -95,7 +91,6 @@
 
     private Drawable mRemoteIndicator;
     private boolean mRemoteActive;
-    private boolean mCheatSheetEnabled;
     private boolean mIsConnecting;
 
     private ColorStateList mButtonTint;
@@ -141,7 +136,6 @@
 
         updateContentDescription();
         setClickable(true);
-        setLongClickable(true);
     }
 
     /**
@@ -280,7 +274,8 @@
      * button when the button is long pressed.
      */
     void setCheatSheetEnabled(boolean enable) {
-        mCheatSheetEnabled = enable;
+        ViewCompat.setTooltipText(this,
+                enable ? getContext().getString(R.string.mr_button_content_description) : null);
     }
 
     @Override
@@ -294,42 +289,6 @@
     }
 
     @Override
-    public boolean performLongClick() {
-        if (super.performLongClick()) {
-            return true;
-        }
-
-        if (!mCheatSheetEnabled) {
-            return false;
-        }
-
-        final int[] screenPos = new int[2];
-        final Rect displayFrame = new Rect();
-        getLocationOnScreen(screenPos);
-        getWindowVisibleDisplayFrame(displayFrame);
-
-        final Context context = getContext();
-        final int width = getWidth();
-        final int height = getHeight();
-        final int midy = screenPos[1] + height / 2;
-        final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
-
-        Toast cheatSheet = Toast.makeText(context, R.string.mr_button_content_description,
-                Toast.LENGTH_SHORT);
-        if (midy < displayFrame.height()) {
-            // Show along the top; follow action buttons
-            cheatSheet.setGravity(Gravity.TOP | GravityCompat.END,
-                    screenWidth - screenPos[0] - width / 2, height);
-        } else {
-            // Show along the bottom center
-            cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
-        }
-        cheatSheet.show();
-        performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-        return true;
-    }
-
-    @Override
     protected int[] onCreateDrawableState(int extraSpace) {
         final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
 
diff --git a/v7/mediarouter/tests/AndroidManifest.xml b/v7/mediarouter/tests/AndroidManifest.xml
index 372a813..19eebd9 100644
--- a/v7/mediarouter/tests/AndroidManifest.xml
+++ b/v7/mediarouter/tests/AndroidManifest.xml
@@ -19,7 +19,7 @@
           package="android.support.v7.mediarouter.test">
 
     <uses-sdk
-            android:minSdkVersion="9"
+            android:minSdkVersion="14"
             android:targetSdkVersion="23"
             tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                       android.support.test.espresso, android.support.test.espresso.idling"/>
diff --git a/v7/palette/Android.mk b/v7/palette/Android.mk
index a9f9a75..f823d30 100644
--- a/v7/palette/Android.mk
+++ b/v7/palette/Android.mk
@@ -29,7 +29,7 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/src/main/res
-LOCAL_MANIFEST_FILE := src/main/AndroidManifest-make.xml
+LOCAL_MANIFEST_FILE := AndroidManifest.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-core-utils \
diff --git a/v7/palette/src/main/AndroidManifest.xml b/v7/palette/AndroidManifest.xml
similarity index 95%
rename from v7/palette/src/main/AndroidManifest.xml
rename to v7/palette/AndroidManifest.xml
index 52e90a2..78735ba 100644
--- a/v7/palette/src/main/AndroidManifest.xml
+++ b/v7/palette/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.palette">
-    <uses-sdk android:minSdkVersion="9"/>
+    <uses-sdk android:minSdkVersion="14"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/v7/palette/build.gradle b/v7/palette/build.gradle
index 686fe71..6ab7995 100644
--- a/v7/palette/build.gradle
+++ b/v7/palette/build.gradle
@@ -1,76 +1,23 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'palette-v7'
 
 dependencies {
     compile project(':support-compat')
     compile project(':support-core-utils')
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    testCompile 'junit:junit:4.12'
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
+        minSdkVersion 14
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Palette v7'
-                description "Android Support for extracting color palettes from images"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support Palette v7'
+    inceptionYear '2014'
+    description 'Android Support Palette v7'
 }
diff --git a/v7/palette/src/androidTest/AndroidManifest.xml b/v7/palette/src/androidTest/AndroidManifest.xml
index c4fd08f..697c7de 100644
--- a/v7/palette/src/androidTest/AndroidManifest.xml
+++ b/v7/palette/src/androidTest/AndroidManifest.xml
@@ -18,7 +18,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.v7.palette.test">
 
-    <uses-sdk android:minSdkVersion="9"
+    <uses-sdk android:minSdkVersion="14"
               tools:overrideLibrary="android.support.test, android.app, android.support.test.rule"/>
 
     <application>
diff --git a/v7/palette/src/main/AndroidManifest-make.xml b/v7/palette/src/main/AndroidManifest-make.xml
deleted file mode 100644
index 5124bc5..0000000
--- a/v7/palette/src/main/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.v7.palette">
-    <uses-sdk android:minSdkVersion="9"/>
-    <application />
-</manifest>
diff --git a/v7/palette/src/main/java/android/support/v7/graphics/Palette.java b/v7/palette/src/main/java/android/support/v7/graphics/Palette.java
index d092587..fe6f147 100644
--- a/v7/palette/src/main/java/android/support/v7/graphics/Palette.java
+++ b/v7/palette/src/main/java/android/support/v7/graphics/Palette.java
@@ -24,7 +24,6 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v4.graphics.ColorUtils;
-import android.support.v4.os.AsyncTaskCompat;
 import android.support.v4.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseBooleanArray;
@@ -856,23 +855,22 @@
                 throw new IllegalArgumentException("listener can not be null");
             }
 
-            return AsyncTaskCompat.executeParallel(
-                    new AsyncTask<Bitmap, Void, Palette>() {
-                        @Override
-                        protected Palette doInBackground(Bitmap... params) {
-                            try {
-                                return generate();
-                            } catch (Exception e) {
-                                Log.e(LOG_TAG, "Exception thrown during async generate", e);
-                                return null;
-                            }
-                        }
+            return new AsyncTask<Bitmap, Void, Palette>() {
+                @Override
+                protected Palette doInBackground(Bitmap... params) {
+                    try {
+                        return generate();
+                    } catch (Exception e) {
+                        Log.e(LOG_TAG, "Exception thrown during async generate", e);
+                        return null;
+                    }
+                }
 
-                        @Override
-                        protected void onPostExecute(Palette colorExtractor) {
-                            listener.onGenerated(colorExtractor);
-                        }
-                    }, mBitmap);
+                @Override
+                protected void onPostExecute(Palette colorExtractor) {
+                    listener.onGenerated(colorExtractor);
+                }
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mBitmap);
         }
 
         private int[] getPixelsFromBitmap(Bitmap bitmap) {
diff --git a/v7/preference/Android.mk b/v7/preference/Android.mk
index 110aed2..e751e1c 100644
--- a/v7/preference/Android.mk
+++ b/v7/preference/Android.mk
@@ -32,7 +32,6 @@
     $(call all-java-files-under,constants) \
     $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-v7-appcompat \
     android-support-v7-recyclerview \
diff --git a/v7/preference/AndroidManifest-make.xml b/v7/preference/AndroidManifest-make.xml
deleted file mode 100644
index 9231775..0000000
--- a/v7/preference/AndroidManifest-make.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.support.v7.preference">
-    <uses-sdk android:minSdkVersion="9" />
-    <application />
-</manifest>
diff --git a/v7/preference/AndroidManifest.xml b/v7/preference/AndroidManifest.xml
index 19e6215..6923656 100644
--- a/v7/preference/AndroidManifest.xml
+++ b/v7/preference/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.support.v7.preference">
-    <uses-sdk android:minSdkVersion="9" />
+    <uses-sdk android:minSdkVersion="14" />
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
     <application />
 </manifest>
diff --git a/v7/preference/build.gradle b/v7/preference/build.gradle
index b5fd656..457f344 100644
--- a/v7/preference/build.gradle
+++ b/v7/preference/build.gradle
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'preference-v7'
 
 dependencies {
@@ -22,43 +22,25 @@
     compile project(':support-appcompat-v7')
     compile project(':support-recyclerview-v7')
 
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    testCompile 'junit:junit:4.12'
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-        minSdkVersion 9
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDir 'src'
         main.java.srcDir 'constants'
         main.res.srcDir 'res'
         main.assets.srcDir 'assets'
         main.resources.srcDir 'src'
-
-        // this moves src/instrumentTest to tests so all folders follow:
-        // tests/java, tests/res, tests/assets, ...
-        // This is a *reset* so it replaces the default paths
-        androidTest.setRoot('tests')
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 
     lintOptions {
@@ -71,52 +53,8 @@
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support Preference v7'
-                description "Android Support Preference v7"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2015'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support Preference v7'
+    inceptionYear '2015'
+    description 'Android Support Preference v7'
 }
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java b/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
index 7d42155..b7846b3 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
@@ -31,7 +31,6 @@
 import android.support.annotation.XmlRes;
 import android.support.v4.app.DialogFragment;
 import android.support.v4.app.Fragment;
-import android.support.v4.view.ViewCompat;
 import android.support.v7.preference.internal.AbstractMultiSelectListPreference;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
@@ -779,7 +778,7 @@
             for (int childViewIndex = 0; childViewIndex < childCount; childViewIndex++) {
                 final View view = parent.getChildAt(childViewIndex);
                 if (shouldDrawDividerBelow(view, parent)) {
-                    int top = (int) ViewCompat.getY(view) + view.getHeight();
+                    int top = (int) view.getY() + view.getHeight();
                     mDivider.setBounds(0, top, width, top + mDividerHeight);
                     mDivider.draw(c);
                 }
diff --git a/v7/preference/tests/AndroidManifest.xml b/v7/preference/tests/AndroidManifest.xml
index d47fd5b..4d3afdd 100644
--- a/v7/preference/tests/AndroidManifest.xml
+++ b/v7/preference/tests/AndroidManifest.xml
@@ -19,7 +19,7 @@
     package="android.support.v7.preference.tests">
 
     <uses-sdk
-        android:minSdkVersion="9"
+        android:minSdkVersion="14"
         android:targetSdkVersion="24"
         tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
                 android.support.test.espresso, android.support.test.espresso.idling" />
diff --git a/v7/recyclerview/Android.mk b/v7/recyclerview/Android.mk
index 819b104..e434ab2 100644
--- a/v7/recyclerview/Android.mk
+++ b/v7/recyclerview/Android.mk
@@ -29,7 +29,6 @@
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-core-ui \
diff --git a/v7/recyclerview/AndroidManifest-make.xml b/v7/recyclerview/AndroidManifest-make.xml
deleted file mode 100644
index d1c1489..0000000
--- a/v7/recyclerview/AndroidManifest-make.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.v7.recyclerview">
-    <uses-sdk android:minSdkVersion="9"/>
-</manifest>
diff --git a/v7/recyclerview/AndroidManifest.xml b/v7/recyclerview/AndroidManifest.xml
index f4f010d..5eef157 100644
--- a/v7/recyclerview/AndroidManifest.xml
+++ b/v7/recyclerview/AndroidManifest.xml
@@ -15,6 +15,6 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.recyclerview">
-    <uses-sdk android:minSdkVersion="9"/>
+    <uses-sdk android:minSdkVersion="14"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
 </manifest>
diff --git a/v7/recyclerview/build.gradle b/v7/recyclerview/build.gradle
index e262ec7..2e4cfcf 100644
--- a/v7/recyclerview/build.gradle
+++ b/v7/recyclerview/build.gradle
@@ -1,49 +1,38 @@
-apply plugin: 'com.android.library'
+apply plugin: android.support.SupportLibraryPlugin
 archivesBaseName = 'recyclerview-v7'
 
 dependencies {
     compile project(':support-annotations')
     compile project(':support-compat')
     compile project(':support-core-ui')
-    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+
+    androidTestCompile (libs.test_runner) {
         exclude module: 'support-annotations'
     }
-    androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
+    androidTestCompile (libs.espresso_core) {
         exclude module: 'support-annotations'
     }
-    testCompile 'junit:junit:4.12'
-    testCompile "org.mockito:mockito-core:1.9.5"
-    testCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+    androidTestCompile libs.mockito_core
+    androidTestCompile libs.dexmaker
+    androidTestCompile libs.dexmaker_mockito
+
+    testCompile libs.junit
+    testCompile libs.mockito_core
+    testCompile ("$libs.test_runner") {
         exclude module: 'support-annotations'
     }
-    androidTestCompile "org.mockito:mockito-core:1.9.5"
-    androidTestCompile "com.google.dexmaker:dexmaker:1.2"
-    androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
 }
 
 android {
-    compileSdkVersion project.ext.currentSdk
-
     defaultConfig {
-        minSdkVersion 9
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        minSdkVersion 14
     }
 
     sourceSets {
-        main.manifest.srcFile 'AndroidManifest.xml'
         main.java.srcDir 'src'
         main.res.srcDirs 'res', 'res-public'
 
-        androidTest.setRoot('tests')
         test.java.srcDir 'jvm-tests/src'
-        androidTest.java.srcDir 'tests/src'
-        androidTest.res.srcDir 'tests/res'
-        androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
     }
 
     testOptions {
@@ -55,52 +44,8 @@
     }
 }
 
-android.libraryVariants.all { variant ->
-    def name = variant.buildType.name
-
-    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
-        return; // Skip debug builds.
-    }
-    def suffix = name.capitalize()
-
-    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
-        classifier = 'sources'
-        from android.sourceSets.main.java.srcDirs
-    }
-
-    artifacts.add('archives', sourcesJarTask);
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url: uri(rootProject.ext.supportRepoOut)) {
-            }
-
-            pom.project {
-                name 'Android Support RecyclerView v7'
-                description "Android Support RecyclerView v7"
-                url 'http://developer.android.com/tools/extras/support-library.html'
-                inceptionYear '2011'
-
-                licenses {
-                    license {
-                        name 'The Apache Software License, Version 2.0'
-                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-                        distribution 'repo'
-                    }
-                }
-
-                scm {
-                    url "http://source.android.com"
-                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
-                }
-                developers {
-                    developer {
-                        name 'The Android Open Source Project'
-                    }
-                }
-            }
-        }
-    }
+supportLibrary {
+    name 'Android Support RecyclerView v7'
+    inceptionYear '2014'
+    description 'Android Support RecyclerView v7'
 }
diff --git a/v7/recyclerview/src/android/support/v7/widget/AdapterHelper.java b/v7/recyclerview/src/android/support/v7/widget/AdapterHelper.java
index c133a98..663e484 100644
--- a/v7/recyclerview/src/android/support/v7/widget/AdapterHelper.java
+++ b/v7/recyclerview/src/android/support/v7/widget/AdapterHelper.java
@@ -43,9 +43,9 @@
  */
 class AdapterHelper implements OpReorderer.Callback {
 
-    final static int POSITION_TYPE_INVISIBLE = 0;
+    static final int POSITION_TYPE_INVISIBLE = 0;
 
-    final static int POSITION_TYPE_NEW_OR_LAID_OUT = 1;
+    static final int POSITION_TYPE_NEW_OR_LAID_OUT = 1;
 
     private static final boolean DEBUG = false;
 
@@ -286,7 +286,7 @@
                 if (op.cmd == UpdateOp.UPDATE) {
                     offsetPositionForPartial += tmpCnt;
                 }
-                tmpStart = updatedPos;// need to remove previously dispatched
+                tmpStart = updatedPos; // need to remove previously dispatched
                 tmpCnt = 1;
             }
         }
@@ -585,7 +585,7 @@
 
     public int applyPendingUpdatesToPosition(int position) {
         final int size = mPendingUpdates.size();
-        for (int i = 0; i < size; i ++) {
+        for (int i = 0; i < size; i++) {
             UpdateOp op = mPendingUpdates.get(i);
             switch (op.cmd) {
                 case UpdateOp.ADD:
@@ -604,7 +604,7 @@
                     break;
                 case UpdateOp.MOVE:
                     if (op.positionStart == position) {
-                        position = op.itemCount;//position end
+                        position = op.itemCount; //position end
                     } else {
                         if (op.positionStart < position) {
                             position -= 1;
@@ -672,7 +672,7 @@
         public String toString() {
             return Integer.toHexString(System.identityHashCode(this))
                     + "[" + cmdToString() + ",s:" + positionStart + "c:" + itemCount
-                    +",p:"+payload + "]";
+                    + ",p:" + payload + "]";
         }
 
         @Override
diff --git a/v7/recyclerview/src/android/support/v7/widget/ChildHelper.java b/v7/recyclerview/src/android/support/v7/widget/ChildHelper.java
index dd75b19..f306931 100644
--- a/v7/recyclerview/src/android/support/v7/widget/ChildHelper.java
+++ b/v7/recyclerview/src/android/support/v7/widget/ChildHelper.java
@@ -121,7 +121,7 @@
             final int diff = index - (offset - removedBefore);
             if (diff == 0) {
                 while (mBucket.get(offset)) { // ensure this offset is not hidden
-                    offset ++;
+                    offset++;
                 }
                 return offset;
             } else {
@@ -238,8 +238,8 @@
         }
         mCallback.attachViewToParent(child, offset, layoutParams);
         if (DEBUG) {
-            Log.d(TAG, "attach view to parent index:" + index + ",off:" + offset + "," +
-                    "h:" + hidden + ", " + this);
+            Log.d(TAG, "attach view to parent index:" + index + ",off:" + offset + ","
+                    + "h:" + hidden + ", " + this);
         }
     }
 
@@ -335,7 +335,7 @@
         mBucket.set(offset);
         hideViewInternal(view);
         if (DEBUG) {
-            Log.d(TAG, "hiding child " + view + " at offset " + offset+ ", " + this);
+            Log.d(TAG, "hiding child " + view + " at offset " + offset + ", " + this);
         }
     }
 
@@ -394,33 +394,33 @@
      */
     static class Bucket {
 
-        final static int BITS_PER_WORD = Long.SIZE;
+        static final int BITS_PER_WORD = Long.SIZE;
 
-        final static long LAST_BIT = 1L << (Long.SIZE - 1);
+        static final long LAST_BIT = 1L << (Long.SIZE - 1);
 
         long mData = 0;
 
-        Bucket next;
+        Bucket mNext;
 
         void set(int index) {
             if (index >= BITS_PER_WORD) {
                 ensureNext();
-                next.set(index - BITS_PER_WORD);
+                mNext.set(index - BITS_PER_WORD);
             } else {
                 mData |= 1L << index;
             }
         }
 
         private void ensureNext() {
-            if (next == null) {
-                next = new Bucket();
+            if (mNext == null) {
+                mNext = new Bucket();
             }
         }
 
         void clear(int index) {
             if (index >= BITS_PER_WORD) {
-                if (next != null) {
-                    next.clear(index - BITS_PER_WORD);
+                if (mNext != null) {
+                    mNext.clear(index - BITS_PER_WORD);
                 }
             } else {
                 mData &= ~(1L << index);
@@ -431,7 +431,7 @@
         boolean get(int index) {
             if (index >= BITS_PER_WORD) {
                 ensureNext();
-                return next.get(index - BITS_PER_WORD);
+                return mNext.get(index - BITS_PER_WORD);
             } else {
                 return (mData & (1L << index)) != 0;
             }
@@ -439,15 +439,15 @@
 
         void reset() {
             mData = 0;
-            if (next != null) {
-                next.reset();
+            if (mNext != null) {
+                mNext.reset();
             }
         }
 
         void insert(int index, boolean value) {
             if (index >= BITS_PER_WORD) {
                 ensureNext();
-                next.insert(index - BITS_PER_WORD, value);
+                mNext.insert(index - BITS_PER_WORD, value);
             } else {
                 final boolean lastBit = (mData & LAST_BIT) != 0;
                 long mask = (1L << index) - 1;
@@ -459,9 +459,9 @@
                 } else {
                     clear(index);
                 }
-                if (lastBit || next != null) {
+                if (lastBit || mNext != null) {
                     ensureNext();
-                    next.insert(0, lastBit);
+                    mNext.insert(0, lastBit);
                 }
             }
         }
@@ -469,7 +469,7 @@
         boolean remove(int index) {
             if (index >= BITS_PER_WORD) {
                 ensureNext();
-                return next.remove(index - BITS_PER_WORD);
+                return mNext.remove(index - BITS_PER_WORD);
             } else {
                 long mask = (1L << index);
                 final boolean value = (mData & mask) != 0;
@@ -479,18 +479,18 @@
                 // cannot use >> because it adds one.
                 final long after = Long.rotateRight(mData & ~mask, 1);
                 mData = before | after;
-                if (next != null) {
-                    if (next.get(0)) {
+                if (mNext != null) {
+                    if (mNext.get(0)) {
                         set(BITS_PER_WORD - 1);
                     }
-                    next.remove(0);
+                    mNext.remove(0);
                 }
                 return value;
             }
         }
 
         int countOnesBefore(int index) {
-            if (next == null) {
+            if (mNext == null) {
                 if (index >= BITS_PER_WORD) {
                     return Long.bitCount(mData);
                 }
@@ -499,18 +499,18 @@
             if (index < BITS_PER_WORD) {
                 return Long.bitCount(mData & ((1L << index) - 1));
             } else {
-                return next.countOnesBefore(index - BITS_PER_WORD) + Long.bitCount(mData);
+                return mNext.countOnesBefore(index - BITS_PER_WORD) + Long.bitCount(mData);
             }
         }
 
         @Override
         public String toString() {
-            return next == null ? Long.toBinaryString(mData)
-                    : next.toString() + "xx" + Long.toBinaryString(mData);
+            return mNext == null ? Long.toBinaryString(mData)
+                    : mNext.toString() + "xx" + Long.toBinaryString(mData);
         }
     }
 
-    static interface Callback {
+    interface Callback {
 
         int getChildCount();
 
diff --git a/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java b/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java
index f388c3f..33ad434 100644
--- a/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java
+++ b/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java
@@ -15,13 +15,15 @@
  */
 package android.support.v7.widget;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
 import android.support.annotation.NonNull;
-import android.support.v4.animation.AnimatorCompatHelper;
 import android.support.v4.view.ViewCompat;
-import android.support.v4.view.ViewPropertyAnimatorCompat;
-import android.support.v4.view.ViewPropertyAnimatorListener;
 import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.view.View;
+import android.view.ViewPropertyAnimator;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -36,6 +38,8 @@
 public class DefaultItemAnimator extends SimpleItemAnimator {
     private static final boolean DEBUG = false;
 
+    private static TimeInterpolator sDefaultInterpolator;
+
     private ArrayList<ViewHolder> mPendingRemovals = new ArrayList<>();
     private ArrayList<ViewHolder> mPendingAdditions = new ArrayList<>();
     private ArrayList<MoveInfo> mPendingMoves = new ArrayList<>();
@@ -82,14 +86,14 @@
 
         @Override
         public String toString() {
-            return "ChangeInfo{" +
-                    "oldHolder=" + oldHolder +
-                    ", newHolder=" + newHolder +
-                    ", fromX=" + fromX +
-                    ", fromY=" + fromY +
-                    ", toX=" + toX +
-                    ", toY=" + toY +
-                    '}';
+            return "ChangeInfo{"
+                    + "oldHolder=" + oldHolder
+                    + ", newHolder=" + newHolder
+                    + ", fromX=" + fromX
+                    + ", fromY=" + fromY
+                    + ", toX=" + toX
+                    + ", toY=" + toY
+                    + '}';
         }
     }
 
@@ -193,51 +197,52 @@
 
     private void animateRemoveImpl(final ViewHolder holder) {
         final View view = holder.itemView;
-        final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);
+        final ViewPropertyAnimator animation = view.animate();
         mRemoveAnimations.add(holder);
-        animation.setDuration(getRemoveDuration())
-                .alpha(0).setListener(new VpaListenerAdapter() {
-            @Override
-            public void onAnimationStart(View view) {
-                dispatchRemoveStarting(holder);
-            }
+        animation.setDuration(getRemoveDuration()).alpha(0).setListener(
+                new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationStart(Animator animator) {
+                        dispatchRemoveStarting(holder);
+                    }
 
-            @Override
-            public void onAnimationEnd(View view) {
-                animation.setListener(null);
-                ViewCompat.setAlpha(view, 1);
-                dispatchRemoveFinished(holder);
-                mRemoveAnimations.remove(holder);
-                dispatchFinishedWhenDone();
-            }
-        }).start();
+                    @Override
+                    public void onAnimationEnd(Animator animator) {
+                        animation.setListener(null);
+                        view.setAlpha(1);
+                        dispatchRemoveFinished(holder);
+                        mRemoveAnimations.remove(holder);
+                        dispatchFinishedWhenDone();
+                    }
+                }).start();
     }
 
     @Override
     public boolean animateAdd(final ViewHolder holder) {
         resetAnimation(holder);
-        ViewCompat.setAlpha(holder.itemView, 0);
+        holder.itemView.setAlpha(0);
         mPendingAdditions.add(holder);
         return true;
     }
 
     void animateAddImpl(final ViewHolder holder) {
         final View view = holder.itemView;
-        final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);
+        final ViewPropertyAnimator animation = view.animate();
         mAddAnimations.add(holder);
-        animation.alpha(1).setDuration(getAddDuration()).
-                setListener(new VpaListenerAdapter() {
+        animation.alpha(1).setDuration(getAddDuration())
+                .setListener(new AnimatorListenerAdapter() {
                     @Override
-                    public void onAnimationStart(View view) {
+                    public void onAnimationStart(Animator animator) {
                         dispatchAddStarting(holder);
                     }
-                    @Override
-                    public void onAnimationCancel(View view) {
-                        ViewCompat.setAlpha(view, 1);
-                    }
 
                     @Override
-                    public void onAnimationEnd(View view) {
+                    public void onAnimationCancel(Animator animator) {
+                        view.setAlpha(1);
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Animator animator) {
                         animation.setListener(null);
                         dispatchAddFinished(holder);
                         mAddAnimations.remove(holder);
@@ -250,8 +255,8 @@
     public boolean animateMove(final ViewHolder holder, int fromX, int fromY,
             int toX, int toY) {
         final View view = holder.itemView;
-        fromX += ViewCompat.getTranslationX(holder.itemView);
-        fromY += ViewCompat.getTranslationY(holder.itemView);
+        fromX += holder.itemView.getTranslationX();
+        fromY += holder.itemView.getTranslationY();
         resetAnimation(holder);
         int deltaX = toX - fromX;
         int deltaY = toY - fromY;
@@ -260,10 +265,10 @@
             return false;
         }
         if (deltaX != 0) {
-            ViewCompat.setTranslationX(view, -deltaX);
+            view.setTranslationX(-deltaX);
         }
         if (deltaY != 0) {
-            ViewCompat.setTranslationY(view, -deltaY);
+            view.setTranslationY(-deltaY);
         }
         mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
         return true;
@@ -274,32 +279,34 @@
         final int deltaX = toX - fromX;
         final int deltaY = toY - fromY;
         if (deltaX != 0) {
-            ViewCompat.animate(view).translationX(0);
+            view.animate().translationX(0);
         }
         if (deltaY != 0) {
-            ViewCompat.animate(view).translationY(0);
+            view.animate().translationY(0);
         }
         // TODO: make EndActions end listeners instead, since end actions aren't called when
         // vpas are canceled (and can't end them. why?)
         // need listener functionality in VPACompat for this. Ick.
-        final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);
+        final ViewPropertyAnimator animation = view.animate();
         mMoveAnimations.add(holder);
-        animation.setDuration(getMoveDuration()).setListener(new VpaListenerAdapter() {
+        animation.setDuration(getMoveDuration()).setListener(new AnimatorListenerAdapter() {
             @Override
-            public void onAnimationStart(View view) {
+            public void onAnimationStart(Animator animator) {
                 dispatchMoveStarting(holder);
             }
+
             @Override
-            public void onAnimationCancel(View view) {
+            public void onAnimationCancel(Animator animator) {
                 if (deltaX != 0) {
-                    ViewCompat.setTranslationX(view, 0);
+                    view.setTranslationX(0);
                 }
                 if (deltaY != 0) {
-                    ViewCompat.setTranslationY(view, 0);
+                    view.setTranslationY(0);
                 }
             }
+
             @Override
-            public void onAnimationEnd(View view) {
+            public void onAnimationEnd(Animator animator) {
                 animation.setListener(null);
                 dispatchMoveFinished(holder);
                 mMoveAnimations.remove(holder);
@@ -316,22 +323,22 @@
             // run a move animation to handle position changes.
             return animateMove(oldHolder, fromX, fromY, toX, toY);
         }
-        final float prevTranslationX = ViewCompat.getTranslationX(oldHolder.itemView);
-        final float prevTranslationY = ViewCompat.getTranslationY(oldHolder.itemView);
-        final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView);
+        final float prevTranslationX = oldHolder.itemView.getTranslationX();
+        final float prevTranslationY = oldHolder.itemView.getTranslationY();
+        final float prevAlpha = oldHolder.itemView.getAlpha();
         resetAnimation(oldHolder);
         int deltaX = (int) (toX - fromX - prevTranslationX);
         int deltaY = (int) (toY - fromY - prevTranslationY);
         // recover prev translation state after ending animation
-        ViewCompat.setTranslationX(oldHolder.itemView, prevTranslationX);
-        ViewCompat.setTranslationY(oldHolder.itemView, prevTranslationY);
-        ViewCompat.setAlpha(oldHolder.itemView, prevAlpha);
+        oldHolder.itemView.setTranslationX(prevTranslationX);
+        oldHolder.itemView.setTranslationY(prevTranslationY);
+        oldHolder.itemView.setAlpha(prevAlpha);
         if (newHolder != null) {
             // carry over translation values
             resetAnimation(newHolder);
-            ViewCompat.setTranslationX(newHolder.itemView, -deltaX);
-            ViewCompat.setTranslationY(newHolder.itemView, -deltaY);
-            ViewCompat.setAlpha(newHolder.itemView, 0);
+            newHolder.itemView.setTranslationX(-deltaX);
+            newHolder.itemView.setTranslationY(-deltaY);
+            newHolder.itemView.setAlpha(0);
         }
         mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY));
         return true;
@@ -343,23 +350,23 @@
         final ViewHolder newHolder = changeInfo.newHolder;
         final View newView = newHolder != null ? newHolder.itemView : null;
         if (view != null) {
-            final ViewPropertyAnimatorCompat oldViewAnim = ViewCompat.animate(view).setDuration(
+            final ViewPropertyAnimator oldViewAnim = view.animate().setDuration(
                     getChangeDuration());
             mChangeAnimations.add(changeInfo.oldHolder);
             oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX);
             oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY);
-            oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() {
+            oldViewAnim.alpha(0).setListener(new AnimatorListenerAdapter() {
                 @Override
-                public void onAnimationStart(View view) {
+                public void onAnimationStart(Animator animator) {
                     dispatchChangeStarting(changeInfo.oldHolder, true);
                 }
 
                 @Override
-                public void onAnimationEnd(View view) {
+                public void onAnimationEnd(Animator animator) {
                     oldViewAnim.setListener(null);
-                    ViewCompat.setAlpha(view, 1);
-                    ViewCompat.setTranslationX(view, 0);
-                    ViewCompat.setTranslationY(view, 0);
+                    view.setAlpha(1);
+                    view.setTranslationX(0);
+                    view.setTranslationY(0);
                     dispatchChangeFinished(changeInfo.oldHolder, true);
                     mChangeAnimations.remove(changeInfo.oldHolder);
                     dispatchFinishedWhenDone();
@@ -367,25 +374,25 @@
             }).start();
         }
         if (newView != null) {
-            final ViewPropertyAnimatorCompat newViewAnimation = ViewCompat.animate(newView);
+            final ViewPropertyAnimator newViewAnimation = newView.animate();
             mChangeAnimations.add(changeInfo.newHolder);
-            newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).
-                    alpha(1).setListener(new VpaListenerAdapter() {
-                @Override
-                public void onAnimationStart(View view) {
-                    dispatchChangeStarting(changeInfo.newHolder, false);
-                }
-                @Override
-                public void onAnimationEnd(View view) {
-                    newViewAnimation.setListener(null);
-                    ViewCompat.setAlpha(newView, 1);
-                    ViewCompat.setTranslationX(newView, 0);
-                    ViewCompat.setTranslationY(newView, 0);
-                    dispatchChangeFinished(changeInfo.newHolder, false);
-                    mChangeAnimations.remove(changeInfo.newHolder);
-                    dispatchFinishedWhenDone();
-                }
-            }).start();
+            newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration())
+                    .alpha(1).setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationStart(Animator animator) {
+                            dispatchChangeStarting(changeInfo.newHolder, false);
+                        }
+                        @Override
+                        public void onAnimationEnd(Animator animator) {
+                            newViewAnimation.setListener(null);
+                            newView.setAlpha(1);
+                            newView.setTranslationX(0);
+                            newView.setTranslationY(0);
+                            dispatchChangeFinished(changeInfo.newHolder, false);
+                            mChangeAnimations.remove(changeInfo.newHolder);
+                            dispatchFinishedWhenDone();
+                        }
+                    }).start();
         }
     }
 
@@ -418,9 +425,9 @@
         } else {
             return false;
         }
-        ViewCompat.setAlpha(item.itemView, 1);
-        ViewCompat.setTranslationX(item.itemView, 0);
-        ViewCompat.setTranslationY(item.itemView, 0);
+        item.itemView.setAlpha(1);
+        item.itemView.setTranslationX(0);
+        item.itemView.setTranslationY(0);
         dispatchChangeFinished(item, oldItem);
         return true;
     }
@@ -429,24 +436,24 @@
     public void endAnimation(ViewHolder item) {
         final View view = item.itemView;
         // this will trigger end callback which should set properties to their target values.
-        ViewCompat.animate(view).cancel();
+        view.animate().cancel();
         // TODO if some other animations are chained to end, how do we cancel them as well?
         for (int i = mPendingMoves.size() - 1; i >= 0; i--) {
             MoveInfo moveInfo = mPendingMoves.get(i);
             if (moveInfo.holder == item) {
-                ViewCompat.setTranslationY(view, 0);
-                ViewCompat.setTranslationX(view, 0);
+                view.setTranslationY(0);
+                view.setTranslationX(0);
                 dispatchMoveFinished(item);
                 mPendingMoves.remove(i);
             }
         }
         endChangeAnimation(mPendingChanges, item);
         if (mPendingRemovals.remove(item)) {
-            ViewCompat.setAlpha(view, 1);
+            view.setAlpha(1);
             dispatchRemoveFinished(item);
         }
         if (mPendingAdditions.remove(item)) {
-            ViewCompat.setAlpha(view, 1);
+            view.setAlpha(1);
             dispatchAddFinished(item);
         }
 
@@ -462,8 +469,8 @@
             for (int j = moves.size() - 1; j >= 0; j--) {
                 MoveInfo moveInfo = moves.get(j);
                 if (moveInfo.holder == item) {
-                    ViewCompat.setTranslationY(view, 0);
-                    ViewCompat.setTranslationX(view, 0);
+                    view.setTranslationY(0);
+                    view.setTranslationX(0);
                     dispatchMoveFinished(item);
                     moves.remove(j);
                     if (moves.isEmpty()) {
@@ -476,7 +483,7 @@
         for (int i = mAdditionsList.size() - 1; i >= 0; i--) {
             ArrayList<ViewHolder> additions = mAdditionsList.get(i);
             if (additions.remove(item)) {
-                ViewCompat.setAlpha(view, 1);
+                view.setAlpha(1);
                 dispatchAddFinished(item);
                 if (additions.isEmpty()) {
                     mAdditionsList.remove(i);
@@ -512,23 +519,26 @@
     }
 
     private void resetAnimation(ViewHolder holder) {
-        AnimatorCompatHelper.clearInterpolator(holder.itemView);
+        if (sDefaultInterpolator == null) {
+            sDefaultInterpolator = new ValueAnimator().getInterpolator();
+        }
+        holder.itemView.animate().setInterpolator(sDefaultInterpolator);
         endAnimation(holder);
     }
 
     @Override
     public boolean isRunning() {
-        return (!mPendingAdditions.isEmpty() ||
-                !mPendingChanges.isEmpty() ||
-                !mPendingMoves.isEmpty() ||
-                !mPendingRemovals.isEmpty() ||
-                !mMoveAnimations.isEmpty() ||
-                !mRemoveAnimations.isEmpty() ||
-                !mAddAnimations.isEmpty() ||
-                !mChangeAnimations.isEmpty() ||
-                !mMovesList.isEmpty() ||
-                !mAdditionsList.isEmpty() ||
-                !mChangesList.isEmpty());
+        return (!mPendingAdditions.isEmpty()
+                || !mPendingChanges.isEmpty()
+                || !mPendingMoves.isEmpty()
+                || !mPendingRemovals.isEmpty()
+                || !mMoveAnimations.isEmpty()
+                || !mRemoveAnimations.isEmpty()
+                || !mAddAnimations.isEmpty()
+                || !mChangeAnimations.isEmpty()
+                || !mMovesList.isEmpty()
+                || !mAdditionsList.isEmpty()
+                || !mChangesList.isEmpty());
     }
 
     /**
@@ -548,8 +558,8 @@
         for (int i = count - 1; i >= 0; i--) {
             MoveInfo item = mPendingMoves.get(i);
             View view = item.holder.itemView;
-            ViewCompat.setTranslationY(view, 0);
-            ViewCompat.setTranslationX(view, 0);
+            view.setTranslationY(0);
+            view.setTranslationX(0);
             dispatchMoveFinished(item.holder);
             mPendingMoves.remove(i);
         }
@@ -562,8 +572,7 @@
         count = mPendingAdditions.size();
         for (int i = count - 1; i >= 0; i--) {
             ViewHolder item = mPendingAdditions.get(i);
-            View view = item.itemView;
-            ViewCompat.setAlpha(view, 1);
+            item.itemView.setAlpha(1);
             dispatchAddFinished(item);
             mPendingAdditions.remove(i);
         }
@@ -584,8 +593,8 @@
                 MoveInfo moveInfo = moves.get(j);
                 ViewHolder item = moveInfo.holder;
                 View view = item.itemView;
-                ViewCompat.setTranslationY(view, 0);
-                ViewCompat.setTranslationX(view, 0);
+                view.setTranslationY(0);
+                view.setTranslationX(0);
                 dispatchMoveFinished(moveInfo.holder);
                 moves.remove(j);
                 if (moves.isEmpty()) {
@@ -600,7 +609,7 @@
             for (int j = count - 1; j >= 0; j--) {
                 ViewHolder item = additions.get(j);
                 View view = item.itemView;
-                ViewCompat.setAlpha(view, 1);
+                view.setAlpha(1);
                 dispatchAddFinished(item);
                 additions.remove(j);
                 if (additions.isEmpty()) {
@@ -630,7 +639,7 @@
 
     void cancelAll(List<ViewHolder> viewHolders) {
         for (int i = viewHolders.size() - 1; i >= 0; i--) {
-            ViewCompat.animate(viewHolders.get(i).itemView).cancel();
+            viewHolders.get(i).itemView.animate().cancel();
         }
     }
 
@@ -655,18 +664,4 @@
             @NonNull List<Object> payloads) {
         return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads);
     }
-
-    private static class VpaListenerAdapter implements ViewPropertyAnimatorListener {
-        VpaListenerAdapter() {
-        }
-
-        @Override
-        public void onAnimationStart(View view) {}
-
-        @Override
-        public void onAnimationEnd(View view) {}
-
-        @Override
-        public void onAnimationCancel(View view) {}
-    }
 }
diff --git a/v7/recyclerview/src/android/support/v7/widget/DividerItemDecoration.java b/v7/recyclerview/src/android/support/v7/widget/DividerItemDecoration.java
index b3b7cd1..3da64bc 100644
--- a/v7/recyclerview/src/android/support/v7/widget/DividerItemDecoration.java
+++ b/v7/recyclerview/src/android/support/v7/widget/DividerItemDecoration.java
@@ -24,7 +24,6 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.NonNull;
-import android.support.v4.view.ViewCompat;
 import android.view.View;
 import android.widget.LinearLayout;
 
@@ -125,7 +124,7 @@
         for (int i = 0; i < childCount; i++) {
             final View child = parent.getChildAt(i);
             parent.getDecoratedBoundsWithMargins(child, mBounds);
-            final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child));
+            final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
             final int top = bottom - mDivider.getIntrinsicHeight();
             mDivider.setBounds(left, top, right, bottom);
             mDivider.draw(canvas);
@@ -152,7 +151,7 @@
         for (int i = 0; i < childCount; i++) {
             final View child = parent.getChildAt(i);
             parent.getLayoutManager().getDecoratedBoundsWithMargins(child, mBounds);
-            final int right = mBounds.right + Math.round(ViewCompat.getTranslationX(child));
+            final int right = mBounds.right + Math.round(child.getTranslationX());
             final int left = right - mDivider.getIntrinsicWidth();
             mDivider.setBounds(left, top, right, bottom);
             mDivider.draw(canvas);
diff --git a/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
index 0b4ccc0..60f601c 100644
--- a/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
@@ -432,8 +432,8 @@
                     if (invalidMatch == null) {
                         invalidMatch = view; // removed item, least preferred
                     }
-                } else if (mOrientationHelper.getDecoratedStart(view) >= boundsEnd ||
-                        mOrientationHelper.getDecoratedEnd(view) < boundsStart) {
+                } else if (mOrientationHelper.getDecoratedStart(view) >= boundsEnd
+                        || mOrientationHelper.getDecoratedEnd(view) < boundsStart) {
                     if (outOfBoundsMatch == null) {
                         outOfBoundsMatch = view; // item is not visible, less preferred
                     }
@@ -545,8 +545,8 @@
             int pos = layoutState.mCurrentPosition;
             final int spanSize = getSpanSize(recycler, state, pos);
             if (spanSize > mSpanCount) {
-                throw new IllegalArgumentException("Item at position " + pos + " requires " +
-                        spanSize + " spans but GridLayoutManager has only " + mSpanCount
+                throw new IllegalArgumentException("Item at position " + pos + " requires "
+                        + spanSize + " spans but GridLayoutManager has only " + mSpanCount
                         + " spans.");
             }
             remainingSpan -= spanSize;
@@ -595,8 +595,8 @@
                 maxSize = size;
             }
             final LayoutParams lp = (LayoutParams) view.getLayoutParams();
-            final float otherSize = 1f * mOrientationHelper.getDecoratedMeasurementInOther(view) /
-                    lp.mSpanSize;
+            final float otherSize = 1f * mOrientationHelper.getDecoratedMeasurementInOther(view)
+                    / lp.mSpanSize;
             if (otherSize > maxSizeInOther) {
                 maxSizeInOther = otherSize;
             }
@@ -618,7 +618,7 @@
 
         // Views that did not measure the maxSize has to be re-measured
         // We will stop doing this once we introduce Gravity in the GLM layout params
-        for (int i = 0; i < count; i ++) {
+        for (int i = 0; i < count; i++) {
             final View view = mSet[i];
             if (mOrientationHelper.getDecoratedMeasurement(view) != maxSize) {
                 final LayoutParams lp = (LayoutParams) view.getLayoutParams();
@@ -826,7 +826,7 @@
      *
      * @see GridLayoutManager#setSpanSizeLookup(SpanSizeLookup)
      */
-    public static abstract class SpanSizeLookup {
+    public abstract static class SpanSizeLookup {
 
         final SparseIntArray mSpanIndexCache = new SparseIntArray();
 
@@ -838,7 +838,7 @@
          * @param position The adapter position of the item
          * @return The number of spans occupied by the item at the provided position
          */
-        abstract public int getSpanSize(int position);
+        public abstract int getSpanSize(int position);
 
         /**
          * Sets whether the results of {@link #getSpanIndex(int, int)} method should be cached or
@@ -1017,47 +1017,98 @@
             limit = getChildCount();
         }
         final boolean preferLastSpan = mOrientation == VERTICAL && isLayoutRTL();
-        View weakCandidate = null; // somewhat matches but not strong
-        int weakCandidateSpanIndex = -1;
-        int weakCandidateOverlap = 0; // how many spans overlap
 
+        // The focusable candidate to be picked if no perfect focusable candidate is found.
+        // The best focusable candidate is the one with the highest amount of span overlap with
+        // the currently focused view.
+        View focusableWeakCandidate = null; // somewhat matches but not strong
+        int focusableWeakCandidateSpanIndex = -1;
+        int focusableWeakCandidateOverlap = 0; // how many spans overlap
+
+        // The unfocusable candidate to become visible on the screen next, if no perfect or
+        // weak focusable candidates are found to receive focus next.
+        // We are only interested in partially visible unfocusable views. These are views that are
+        // not fully visible, that is either partially overlapping, or out-of-bounds and right below
+        // or above RV's padded bounded area. The best unfocusable candidate is the one with the
+        // highest amount of span overlap with the currently focused view.
+        View unfocusableWeakCandidate = null; // somewhat matches but not strong
+        int unfocusableWeakCandidateSpanIndex = -1;
+        int unfocusableWeakCandidateOverlap = 0; // how many spans overlap
+
+        // The span group index of the start child. This indicates the span group index of the
+        // next focusable item to receive focus, if a focusable item within the same span group
+        // exists. Any focusable item beyond this group index are not relevant since they
+        // were already stored in the layout before onFocusSearchFailed call and were not picked
+        // by the focusSearch algorithm.
+        int focusableSpanGroupIndex = getSpanGroupIndex(recycler, state, start);
         for (int i = start; i != limit; i += inc) {
+            int spanGroupIndex = getSpanGroupIndex(recycler, state, i);
             View candidate = getChildAt(i);
             if (candidate == prevFocusedChild) {
                 break;
             }
-            if (!candidate.isFocusable()) {
+
+            if (candidate.isFocusable() && spanGroupIndex != focusableSpanGroupIndex) {
+                // We are past the allowable span group index for the next focusable item.
+                // The search only continues if no focusable weak candidates have been found up
+                // until this point, in order to find the best unfocusable candidate to become
+                // visible on the screen next.
+                if (focusableWeakCandidate != null) {
+                    break;
+                }
                 continue;
             }
+
             final LayoutParams candidateLp = (LayoutParams) candidate.getLayoutParams();
             final int candidateStart = candidateLp.mSpanIndex;
             final int candidateEnd = candidateLp.mSpanIndex + candidateLp.mSpanSize;
-            if (candidateStart == prevSpanStart && candidateEnd == prevSpanEnd) {
+            if (candidate.isFocusable() && candidateStart == prevSpanStart
+                    && candidateEnd == prevSpanEnd) {
                 return candidate; // perfect match
             }
             boolean assignAsWeek = false;
-            if (weakCandidate == null) {
+            if ((candidate.isFocusable() && focusableWeakCandidate == null)
+                    || (!candidate.isFocusable() && unfocusableWeakCandidate == null)) {
                 assignAsWeek = true;
             } else {
                 int maxStart = Math.max(candidateStart, prevSpanStart);
                 int minEnd = Math.min(candidateEnd, prevSpanEnd);
                 int overlap = minEnd - maxStart;
-                if (overlap > weakCandidateOverlap) {
-                    assignAsWeek = true;
-                } else if (overlap == weakCandidateOverlap &&
-                        preferLastSpan == (candidateStart > weakCandidateSpanIndex)) {
-                    assignAsWeek = true;
+                if (candidate.isFocusable()) {
+                    if (overlap > focusableWeakCandidateOverlap) {
+                        assignAsWeek = true;
+                    } else if (overlap == focusableWeakCandidateOverlap
+                            && preferLastSpan == (candidateStart
+                            > focusableWeakCandidateSpanIndex)) {
+                        assignAsWeek = true;
+                    }
+                } else if (focusableWeakCandidate == null
+                        && isViewPartiallyVisible(candidate, false, true)) {
+                    if (overlap > unfocusableWeakCandidateOverlap) {
+                        assignAsWeek = true;
+                    } else if (overlap == unfocusableWeakCandidateOverlap
+                            && preferLastSpan == (candidateStart
+                                    > unfocusableWeakCandidateSpanIndex)) {
+                        assignAsWeek = true;
+                    }
                 }
             }
 
             if (assignAsWeek) {
-                weakCandidate = candidate;
-                weakCandidateSpanIndex = candidateLp.mSpanIndex;
-                weakCandidateOverlap = Math.min(candidateEnd, prevSpanEnd) -
-                        Math.max(candidateStart, prevSpanStart);
+                if (candidate.isFocusable()) {
+                    focusableWeakCandidate = candidate;
+                    focusableWeakCandidateSpanIndex = candidateLp.mSpanIndex;
+                    focusableWeakCandidateOverlap = Math.min(candidateEnd, prevSpanEnd)
+                            - Math.max(candidateStart, prevSpanStart);
+                } else {
+                    unfocusableWeakCandidate = candidate;
+                    unfocusableWeakCandidateSpanIndex = candidateLp.mSpanIndex;
+                    unfocusableWeakCandidateOverlap = Math.min(candidateEnd, prevSpanEnd)
+                            - Math.max(candidateStart, prevSpanStart);
+                }
             }
         }
-        return weakCandidate;
+        return (focusableWeakCandidate != null) ? focusableWeakCandidate : unfocusableWeakCandidate;
     }
 
     @Override
diff --git a/v7/recyclerview/src/android/support/v7/widget/LayoutState.java b/v7/recyclerview/src/android/support/v7/widget/LayoutState.java
index 23d8ee8..f75da1c 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LayoutState.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LayoutState.java
@@ -24,23 +24,23 @@
  */
 class LayoutState {
 
-    final static String TAG = "LayoutState";
+    static final String TAG = "LayoutState";
 
-    final static int LAYOUT_START = -1;
+    static final int LAYOUT_START = -1;
 
-    final static int LAYOUT_END = 1;
+    static final int LAYOUT_END = 1;
 
-    final static int INVALID_LAYOUT = Integer.MIN_VALUE;
+    static final int INVALID_LAYOUT = Integer.MIN_VALUE;
 
-    final static int ITEM_DIRECTION_HEAD = -1;
+    static final int ITEM_DIRECTION_HEAD = -1;
 
-    final static int ITEM_DIRECTION_TAIL = 1;
+    static final int ITEM_DIRECTION_TAIL = 1;
 
     /**
      * We may not want to recycle children in some cases (e.g. layout)
      */
     boolean mRecycle = true;
-    
+
     /**
      * Number of pixels that we should fill, in the layout direction.
      */
@@ -104,13 +104,13 @@
 
     @Override
     public String toString() {
-        return "LayoutState{" +
-                "mAvailable=" + mAvailable +
-                ", mCurrentPosition=" + mCurrentPosition +
-                ", mItemDirection=" + mItemDirection +
-                ", mLayoutDirection=" + mLayoutDirection +
-                ", mStartLine=" + mStartLine +
-                ", mEndLine=" + mEndLine +
-                '}';
+        return "LayoutState{"
+                + "mAvailable=" + mAvailable
+                + ", mCurrentPosition=" + mCurrentPosition
+                + ", mItemDirection=" + mItemDirection
+                + ", mLayoutDirection=" + mLayoutDirection
+                + ", mStartLine=" + mStartLine
+                + ", mEndLine=" + mEndLine
+                + '}';
     }
 }
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
index 6900437..65a2045 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
@@ -135,9 +135,9 @@
     SavedState mPendingSavedState = null;
 
     /**
-    *  Re-used variable to keep anchor information on re-layout.
-    *  Anchor position and coordinate defines the reference point for LLM while doing a layout.
-    * */
+     *  Re-used variable to keep anchor information on re-layout.
+     *  Anchor position and coordinate defines the reference point for LLM while doing a layout.
+     * */
     final AnchorInfo mAnchorInfo = new AnchorInfo();
 
     /**
@@ -180,7 +180,7 @@
      * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_stackFromEnd
      */
     public LinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
-                               int defStyleRes) {
+            int defStyleRes) {
         Properties properties = getProperties(context, attrs, defStyleAttr, defStyleRes);
         setOrientation(properties.orientation);
         setReverseLayout(properties.reverseLayout);
@@ -257,14 +257,14 @@
             state.mAnchorLayoutFromEnd = didLayoutFromEnd;
             if (didLayoutFromEnd) {
                 final View refChild = getChildClosestToEnd();
-                state.mAnchorOffset = mOrientationHelper.getEndAfterPadding() -
-                        mOrientationHelper.getDecoratedEnd(refChild);
+                state.mAnchorOffset = mOrientationHelper.getEndAfterPadding()
+                        - mOrientationHelper.getDecoratedEnd(refChild);
                 state.mAnchorPosition = getPosition(refChild);
             } else {
                 final View refChild = getChildClosestToStart();
                 state.mAnchorPosition = getPosition(refChild);
-                state.mAnchorOffset = mOrientationHelper.getDecoratedStart(refChild) -
-                        mOrientationHelper.getStartAfterPadding();
+                state.mAnchorOffset = mOrientationHelper.getDecoratedStart(refChild)
+                        - mOrientationHelper.getStartAfterPadding();
             }
         } else {
             state.invalidateAnchor();
@@ -495,8 +495,8 @@
         // resolve layout direction
         resolveShouldLayoutReverse();
 
-        if (!mAnchorInfo.mValid || mPendingScrollPosition != NO_POSITION ||
-                mPendingSavedState != null) {
+        if (!mAnchorInfo.mValid || mPendingScrollPosition != NO_POSITION
+                || mPendingSavedState != null) {
             mAnchorInfo.reset();
             mAnchorInfo.mLayoutFromEnd = mShouldReverseLayout ^ mStackFromEnd;
             // calculate anchor position and coordinate
@@ -523,8 +523,8 @@
         }
         extraForStart += mOrientationHelper.getStartAfterPadding();
         extraForEnd += mOrientationHelper.getEndPadding();
-        if (state.isPreLayout() && mPendingScrollPosition != NO_POSITION &&
-                mPendingScrollPositionOffset != INVALID_OFFSET) {
+        if (state.isPreLayout() && mPendingScrollPosition != NO_POSITION
+                && mPendingScrollPositionOffset != INVALID_OFFSET) {
             // if the child is visible and we are going to move it around, we should layout
             // extra items in the opposite direction to make sure new items animate nicely
             // instead of just fading in
@@ -533,8 +533,8 @@
                 final int current;
                 final int upcomingOffset;
                 if (mShouldReverseLayout) {
-                    current = mOrientationHelper.getEndAfterPadding() -
-                            mOrientationHelper.getDecoratedEnd(existing);
+                    current = mOrientationHelper.getEndAfterPadding()
+                            - mOrientationHelper.getDecoratedEnd(existing);
                     upcomingOffset = current - mPendingScrollPositionOffset;
                 } else {
                     current = mOrientationHelper.getDecoratedStart(existing)
@@ -552,11 +552,11 @@
         int endOffset;
         final int firstLayoutDirection;
         if (mAnchorInfo.mLayoutFromEnd) {
-            firstLayoutDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_TAIL :
-                    LayoutState.ITEM_DIRECTION_HEAD;
+            firstLayoutDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_TAIL
+                    : LayoutState.ITEM_DIRECTION_HEAD;
         } else {
-            firstLayoutDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_HEAD :
-                    LayoutState.ITEM_DIRECTION_TAIL;
+            firstLayoutDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_HEAD
+                    : LayoutState.ITEM_DIRECTION_TAIL;
         }
 
         onAnchorReady(recycler, state, mAnchorInfo, firstLayoutDirection);
@@ -669,14 +669,15 @@
      *                                 indices.
      */
     void onAnchorReady(RecyclerView.Recycler recycler, RecyclerView.State state,
-                       AnchorInfo anchorInfo, int firstLayoutItemDirection) {
+            AnchorInfo anchorInfo, int firstLayoutItemDirection) {
     }
 
     /**
      * If necessary, layouts new items for predictive animations
      */
     private void layoutForPredictiveAnimations(RecyclerView.Recycler recycler,
-            RecyclerView.State state, int startOffset,  int endOffset) {
+            RecyclerView.State state, int startOffset,
+            int endOffset) {
         // If there are scrap children that we did not layout, we need to find where they did go
         // and layout them accordingly so that animations can work as expected.
         // This case may happen if new views are added or an existing view expands and pushes
@@ -731,7 +732,7 @@
     }
 
     private void updateAnchorInfoForLayout(RecyclerView.Recycler recycler, RecyclerView.State state,
-                                           AnchorInfo anchorInfo) {
+            AnchorInfo anchorInfo) {
         if (updateAnchorFromPendingData(state, anchorInfo)) {
             if (DEBUG) {
                 Log.d(TAG, "updated anchor info from pending information");
@@ -759,7 +760,7 @@
      * If a child has focus, it is given priority.
      */
     private boolean updateAnchorFromChildren(RecyclerView.Recycler recycler,
-                                             RecyclerView.State state, AnchorInfo anchorInfo) {
+            RecyclerView.State state, AnchorInfo anchorInfo) {
         if (getChildCount() == 0) {
             return false;
         }
@@ -822,11 +823,11 @@
             // according to our current view bounds
             anchorInfo.mLayoutFromEnd = mPendingSavedState.mAnchorLayoutFromEnd;
             if (anchorInfo.mLayoutFromEnd) {
-                anchorInfo.mCoordinate = mOrientationHelper.getEndAfterPadding() -
-                        mPendingSavedState.mAnchorOffset;
+                anchorInfo.mCoordinate = mOrientationHelper.getEndAfterPadding()
+                        - mPendingSavedState.mAnchorOffset;
             } else {
-                anchorInfo.mCoordinate = mOrientationHelper.getStartAfterPadding() +
-                        mPendingSavedState.mAnchorOffset;
+                anchorInfo.mCoordinate = mOrientationHelper.getStartAfterPadding()
+                        + mPendingSavedState.mAnchorOffset;
             }
             return true;
         }
@@ -847,8 +848,8 @@
                     anchorInfo.mLayoutFromEnd = false;
                     return true;
                 }
-                final int endGap = mOrientationHelper.getEndAfterPadding() -
-                        mOrientationHelper.getDecoratedEnd(child);
+                final int endGap = mOrientationHelper.getEndAfterPadding()
+                        - mOrientationHelper.getDecoratedEnd(child);
                 if (endGap < 0) {
                     anchorInfo.mCoordinate = mOrientationHelper.getEndAfterPadding();
                     anchorInfo.mLayoutFromEnd = true;
@@ -856,7 +857,7 @@
                 }
                 anchorInfo.mCoordinate = anchorInfo.mLayoutFromEnd
                         ? (mOrientationHelper.getDecoratedEnd(child) + mOrientationHelper
-                                .getTotalSpaceChange())
+                        .getTotalSpaceChange())
                         : mOrientationHelper.getDecoratedStart(child);
             } else { // item is not visible.
                 if (getChildCount() > 0) {
@@ -873,11 +874,11 @@
         anchorInfo.mLayoutFromEnd = mShouldReverseLayout;
         // if this changes, we should update prepareForDrop as well
         if (mShouldReverseLayout) {
-            anchorInfo.mCoordinate = mOrientationHelper.getEndAfterPadding() -
-                    mPendingScrollPositionOffset;
+            anchorInfo.mCoordinate = mOrientationHelper.getEndAfterPadding()
+                    - mPendingScrollPositionOffset;
         } else {
-            anchorInfo.mCoordinate = mOrientationHelper.getStartAfterPadding() +
-                    mPendingScrollPositionOffset;
+            anchorInfo.mCoordinate = mOrientationHelper.getStartAfterPadding()
+                    + mPendingScrollPositionOffset;
         }
         return true;
     }
@@ -1733,7 +1734,7 @@
      * @return A View that can be used an an anchor View.
      */
     private View findReferenceChildClosestToEnd(RecyclerView.Recycler recycler,
-                                                RecyclerView.State state) {
+            RecyclerView.State state) {
         return mShouldReverseLayout ? findFirstReferenceChild(recycler, state) :
                 findLastReferenceChild(recycler, state);
     }
@@ -1750,7 +1751,7 @@
      * @return A View that can be used an an anchor View.
      */
     private View findReferenceChildClosestToStart(RecyclerView.Recycler recycler,
-                                                  RecyclerView.State state) {
+            RecyclerView.State state) {
         return mShouldReverseLayout ? findLastReferenceChild(recycler, state) :
                 findFirstReferenceChild(recycler, state);
     }
@@ -1765,7 +1766,7 @@
 
     // overridden by GridLayoutManager
     View findReferenceChild(RecyclerView.Recycler recycler, RecyclerView.State state,
-                            int start, int end, int itemCount) {
+            int start, int end, int itemCount) {
         ensureLayoutState();
         View invalidMatch = null;
         View outOfBoundsMatch = null;
@@ -1780,8 +1781,8 @@
                     if (invalidMatch == null) {
                         invalidMatch = view; // removed item, least preferred
                     }
-                } else if (mOrientationHelper.getDecoratedStart(view) >= boundsEnd ||
-                        mOrientationHelper.getDecoratedEnd(view) < boundsStart) {
+                } else if (mOrientationHelper.getDecoratedStart(view) >= boundsEnd
+                        || mOrientationHelper.getDecoratedEnd(view) < boundsStart) {
                     if (outOfBoundsMatch == null) {
                         outOfBoundsMatch = view; // item is not visible, less preferred
                     }
@@ -1793,6 +1794,32 @@
         return outOfBoundsMatch != null ? outOfBoundsMatch : invalidMatch;
     }
 
+    // returns the out-of-bound child view closest to RV's end bounds. An out-of-bound child is
+    // defined as a child that's either partially or fully invisible (outside RV's padding area).
+    private View findPartiallyOrCompletelyInvisibleChildClosestToEnd(RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        return mShouldReverseLayout ? findFirstPartiallyOrCompletelyInvisibleChild(recycler, state)
+                : findLastPartiallyOrCompletelyInvisibleChild(recycler, state);
+    }
+
+    // returns the out-of-bound child view closest to RV's starting bounds. An out-of-bound child is
+    // defined as a child that's either partially or fully invisible (outside RV's padding area).
+    private View findPartiallyOrCompletelyInvisibleChildClosestToStart(
+            RecyclerView.Recycler recycler, RecyclerView.State state) {
+        return mShouldReverseLayout ? findLastPartiallyOrCompletelyInvisibleChild(recycler, state) :
+                findFirstPartiallyOrCompletelyInvisibleChild(recycler, state);
+    }
+
+    private View findFirstPartiallyOrCompletelyInvisibleChild(RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        return findOnePartiallyOrCompletelyInvisibleChild(0, getChildCount());
+    }
+
+    private View findLastPartiallyOrCompletelyInvisibleChild(RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        return findOnePartiallyOrCompletelyInvisibleChild(getChildCount() - 1, -1);
+    }
+
     /**
      * Returns the adapter position of the first visible view. This position does not include
      * adapter changes that were dispatched after the last layout pass.
@@ -1876,27 +1903,52 @@
     View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible,
             boolean acceptPartiallyVisible) {
         ensureLayoutState();
-        final int start = mOrientationHelper.getStartAfterPadding();
-        final int end = mOrientationHelper.getEndAfterPadding();
-        final int next = toIndex > fromIndex ? 1 : -1;
-        View partiallyVisible = null;
-        for (int i = fromIndex; i != toIndex; i+=next) {
-            final View child = getChildAt(i);
-            final int childStart = mOrientationHelper.getDecoratedStart(child);
-            final int childEnd = mOrientationHelper.getDecoratedEnd(child);
-            if (childStart < end && childEnd > start) {
-                if (completelyVisible) {
-                    if (childStart >= start && childEnd <= end) {
-                        return child;
-                    } else if (acceptPartiallyVisible && partiallyVisible == null) {
-                        partiallyVisible = child;
-                    }
-                } else {
-                    return child;
-                }
-            }
+        @ViewBoundsCheck.ViewBounds int preferredBoundsFlag = 0;
+        @ViewBoundsCheck.ViewBounds int acceptableBoundsFlag = 0;
+        if (completelyVisible) {
+            preferredBoundsFlag = (ViewBoundsCheck.FLAG_CVS_GT_PVS | ViewBoundsCheck.FLAG_CVS_EQ_PVS
+                    | ViewBoundsCheck.FLAG_CVE_LT_PVE | ViewBoundsCheck.FLAG_CVE_EQ_PVE);
+        } else {
+            preferredBoundsFlag = (ViewBoundsCheck.FLAG_CVS_LT_PVE | ViewBoundsCheck.FLAG_CVS_EQ_PVE
+                    | ViewBoundsCheck.FLAG_CVE_GT_PVS | ViewBoundsCheck.FLAG_CVE_EQ_PVS);
         }
-        return partiallyVisible;
+        if (acceptPartiallyVisible) {
+            acceptableBoundsFlag = (ViewBoundsCheck.FLAG_CVS_LT_PVE
+                    | ViewBoundsCheck.FLAG_CVS_EQ_PVE | ViewBoundsCheck.FLAG_CVE_GT_PVS
+                    | ViewBoundsCheck.FLAG_CVE_EQ_PVS);
+        }
+        return (mOrientation == HORIZONTAL) ? mHorizontalBoundCheck
+                .findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag,
+                        acceptableBoundsFlag) : mVerticalBoundCheck
+                .findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag,
+                        acceptableBoundsFlag);
+    }
+
+    View findOnePartiallyOrCompletelyInvisibleChild(int fromIndex, int toIndex) {
+        ensureLayoutState();
+        final int next = toIndex > fromIndex ? 1 : (toIndex < fromIndex ? -1 : 0);
+        if (next == 0) {
+            return getChildAt(fromIndex);
+        }
+        @ViewBoundsCheck.ViewBounds int preferredBoundsFlag = 0;
+        @ViewBoundsCheck.ViewBounds int acceptableBoundsFlag = 0;
+        if (mOrientationHelper.getDecoratedStart(getChildAt(fromIndex))
+                < mOrientationHelper.getStartAfterPadding()) {
+            preferredBoundsFlag = (ViewBoundsCheck.FLAG_CVS_LT_PVS | ViewBoundsCheck.FLAG_CVE_LT_PVE
+                    | ViewBoundsCheck.FLAG_CVE_GT_PVS);
+            acceptableBoundsFlag = (ViewBoundsCheck.FLAG_CVS_LT_PVS
+                    | ViewBoundsCheck.FLAG_CVE_LT_PVE);
+        } else {
+            preferredBoundsFlag = (ViewBoundsCheck.FLAG_CVE_GT_PVE | ViewBoundsCheck.FLAG_CVS_GT_PVS
+                    | ViewBoundsCheck.FLAG_CVS_LT_PVE);
+            acceptableBoundsFlag = (ViewBoundsCheck.FLAG_CVE_GT_PVE
+                    | ViewBoundsCheck.FLAG_CVS_GT_PVS);
+        }
+        return (mOrientation == HORIZONTAL) ? mHorizontalBoundCheck
+                .findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag,
+                        acceptableBoundsFlag) : mVerticalBoundCheck
+                .findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag,
+                        acceptableBoundsFlag);
     }
 
     @Override
@@ -1912,35 +1964,38 @@
             return null;
         }
         ensureLayoutState();
-        final View referenceChild;
-        if (layoutDir == LayoutState.LAYOUT_START) {
-            referenceChild = findReferenceChildClosestToStart(recycler, state);
-        } else {
-            referenceChild = findReferenceChildClosestToEnd(recycler, state);
-        }
-        if (referenceChild == null) {
-            if (DEBUG) {
-                Log.d(TAG,
-                        "Cannot find a child with a valid position to be used for focus search.");
-            }
-            return null;
-        }
         ensureLayoutState();
         final int maxScroll = (int) (MAX_SCROLL_FACTOR * mOrientationHelper.getTotalSpace());
         updateLayoutState(layoutDir, maxScroll, false, state);
         mLayoutState.mScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN;
         mLayoutState.mRecycle = false;
         fill(recycler, mLayoutState, state, true);
+
+        // nextCandidate is the first child view in the layout direction that's partially
+        // within RV's bounds, i.e. part of it is visible or it's completely invisible but still
+        // touching RV's bounds. This will be the unfocusable candidate view to become visible onto
+        // the screen if no focusable views are found in the given layout direction.
+        final View nextCandidate;
+        if (layoutDir == LayoutState.LAYOUT_START) {
+            nextCandidate = findPartiallyOrCompletelyInvisibleChildClosestToStart(recycler, state);
+        } else {
+            nextCandidate = findPartiallyOrCompletelyInvisibleChildClosestToEnd(recycler, state);
+        }
+        // nextFocus is meaningful only if it refers to a focusable child, in which case it
+        // indicates the next view to gain focus.
         final View nextFocus;
         if (layoutDir == LayoutState.LAYOUT_START) {
             nextFocus = getChildClosestToStart();
         } else {
             nextFocus = getChildClosestToEnd();
         }
-        if (nextFocus == referenceChild || !nextFocus.isFocusable()) {
-            return null;
+        if (nextFocus.isFocusable()) {
+            if (nextCandidate == null) {
+                return null;
+            }
+            return nextFocus;
         }
-        return nextFocus;
+        return nextCandidate;
     }
 
     /**
@@ -1981,8 +2036,8 @@
                 int screenLoc = mOrientationHelper.getDecoratedStart(child);
                 if (pos < lastPos) {
                     logChildren();
-                    throw new RuntimeException("detected invalid position. loc invalid? " +
-                            (screenLoc < lastScreenLoc));
+                    throw new RuntimeException("detected invalid position. loc invalid? "
+                            + (screenLoc < lastScreenLoc));
                 }
                 if (screenLoc > lastScreenLoc) {
                     logChildren();
@@ -1996,8 +2051,8 @@
                 int screenLoc = mOrientationHelper.getDecoratedStart(child);
                 if (pos < lastPos) {
                     logChildren();
-                    throw new RuntimeException("detected invalid position. loc invalid? " +
-                            (screenLoc < lastScreenLoc));
+                    throw new RuntimeException("detected invalid position. loc invalid? "
+                            + (screenLoc < lastScreenLoc));
                 }
                 if (screenLoc < lastScreenLoc) {
                     logChildren();
@@ -2023,26 +2078,26 @@
         resolveShouldLayoutReverse();
         final int myPos = getPosition(view);
         final int targetPos = getPosition(target);
-        final int dropDirection = myPos < targetPos ? LayoutState.ITEM_DIRECTION_TAIL :
-                LayoutState.ITEM_DIRECTION_HEAD;
+        final int dropDirection = myPos < targetPos ? LayoutState.ITEM_DIRECTION_TAIL
+                : LayoutState.ITEM_DIRECTION_HEAD;
         if (mShouldReverseLayout) {
             if (dropDirection == LayoutState.ITEM_DIRECTION_TAIL) {
                 scrollToPositionWithOffset(targetPos,
-                        mOrientationHelper.getEndAfterPadding() -
-                                (mOrientationHelper.getDecoratedStart(target) +
-                                mOrientationHelper.getDecoratedMeasurement(view)));
+                        mOrientationHelper.getEndAfterPadding()
+                                - (mOrientationHelper.getDecoratedStart(target)
+                                + mOrientationHelper.getDecoratedMeasurement(view)));
             } else {
                 scrollToPositionWithOffset(targetPos,
-                        mOrientationHelper.getEndAfterPadding() -
-                                mOrientationHelper.getDecoratedEnd(target));
+                        mOrientationHelper.getEndAfterPadding()
+                                - mOrientationHelper.getDecoratedEnd(target));
             }
         } else {
             if (dropDirection == LayoutState.ITEM_DIRECTION_HEAD) {
                 scrollToPositionWithOffset(targetPos, mOrientationHelper.getDecoratedStart(target));
             } else {
                 scrollToPositionWithOffset(targetPos,
-                        mOrientationHelper.getDecoratedEnd(target) -
-                                mOrientationHelper.getDecoratedMeasurement(view));
+                        mOrientationHelper.getDecoratedEnd(target)
+                                - mOrientationHelper.getDecoratedMeasurement(view));
             }
         }
     }
@@ -2053,19 +2108,19 @@
      */
     static class LayoutState {
 
-        final static String TAG = "LLM#LayoutState";
+        static final String TAG = "LLM#LayoutState";
 
-        final static int LAYOUT_START = -1;
+        static final int LAYOUT_START = -1;
 
-        final static int LAYOUT_END = 1;
+        static final int LAYOUT_END = 1;
 
-        final static int INVALID_LAYOUT = Integer.MIN_VALUE;
+        static final int INVALID_LAYOUT = Integer.MIN_VALUE;
 
-        final static int ITEM_DIRECTION_HEAD = -1;
+        static final int ITEM_DIRECTION_HEAD = -1;
 
-        final static int ITEM_DIRECTION_TAIL = 1;
+        static final int ITEM_DIRECTION_TAIL = 1;
 
-        final static int SCROLLING_OFFSET_NaN = Integer.MIN_VALUE;
+        static final int SCROLLING_OFFSET_NaN = Integer.MIN_VALUE;
 
         /**
          * We may not want to recycle children in some cases (e.g. layout)
@@ -2209,8 +2264,8 @@
                 if (view == ignore || lp.isItemRemoved()) {
                     continue;
                 }
-                final int distance = (lp.getViewLayoutPosition() - mCurrentPosition) *
-                        mItemDirection;
+                final int distance = (lp.getViewLayoutPosition() - mCurrentPosition)
+                        * mItemDirection;
                 if (distance < 0) {
                     continue; // item is not in current direction
                 }
@@ -2226,8 +2281,8 @@
         }
 
         void log() {
-            Log.d(TAG, "avail:" + mAvailable + ", ind:" + mCurrentPosition + ", dir:" +
-                    mItemDirection + ", offset:" + mOffset + ", layoutDir:" + mLayoutDirection);
+            Log.d(TAG, "avail:" + mAvailable + ", ind:" + mCurrentPosition + ", dir:"
+                    + mItemDirection + ", offset:" + mOffset + ", layoutDir:" + mLayoutDirection);
         }
     }
 
@@ -2279,18 +2334,18 @@
             dest.writeInt(mAnchorLayoutFromEnd ? 1 : 0);
         }
 
-        public static final Parcelable.Creator<SavedState> CREATOR
-                = new Parcelable.Creator<SavedState>() {
-            @Override
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+                    @Override
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
 
-            @Override
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
+                    @Override
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
     }
 
     /**
@@ -2325,12 +2380,12 @@
 
         @Override
         public String toString() {
-            return "AnchorInfo{" +
-                    "mPosition=" + mPosition +
-                    ", mCoordinate=" + mCoordinate +
-                    ", mLayoutFromEnd=" + mLayoutFromEnd +
-                    ", mValid=" + mValid +
-                    '}';
+            return "AnchorInfo{"
+                    + "mPosition=" + mPosition
+                    + ", mCoordinate=" + mCoordinate
+                    + ", mLayoutFromEnd=" + mLayoutFromEnd
+                    + ", mValid=" + mValid
+                    + '}';
         }
 
         boolean isViewValidAsAnchor(View child, RecyclerView.State state) {
@@ -2352,12 +2407,12 @@
                 final int previousEndMargin = prevLayoutEnd - childEnd;
                 mCoordinate = mOrientationHelper.getEndAfterPadding() - previousEndMargin;
                 // ensure we did not push child's top out of bounds because of this
-                if (previousEndMargin > 0) {// we have room to shift bottom if necessary
+                if (previousEndMargin > 0) { // we have room to shift bottom if necessary
                     final int childSize = mOrientationHelper.getDecoratedMeasurement(child);
                     final int estimatedChildStart = mCoordinate - childSize;
                     final int layoutStart = mOrientationHelper.getStartAfterPadding();
-                    final int previousStartMargin = mOrientationHelper.getDecoratedStart(child) -
-                            layoutStart;
+                    final int previousStartMargin = mOrientationHelper.getDecoratedStart(child)
+                            - layoutStart;
                     final int startReference = layoutStart + Math.min(previousStartMargin, 0);
                     final int startMargin = estimatedChildStart - startReference;
                     if (startMargin < 0) {
@@ -2370,14 +2425,14 @@
                 final int startMargin = childStart - mOrientationHelper.getStartAfterPadding();
                 mCoordinate = childStart;
                 if (startMargin > 0) { // we have room to fix end as well
-                    final int estimatedEnd = childStart +
-                            mOrientationHelper.getDecoratedMeasurement(child);
-                    final int previousLayoutEnd = mOrientationHelper.getEndAfterPadding() -
-                            spaceChange;
-                    final int previousEndMargin = previousLayoutEnd -
-                            mOrientationHelper.getDecoratedEnd(child);
-                    final int endReference = mOrientationHelper.getEndAfterPadding() -
-                            Math.min(0, previousEndMargin);
+                    final int estimatedEnd = childStart
+                            + mOrientationHelper.getDecoratedMeasurement(child);
+                    final int previousLayoutEnd = mOrientationHelper.getEndAfterPadding()
+                            - spaceChange;
+                    final int previousEndMargin = previousLayoutEnd
+                            - mOrientationHelper.getDecoratedEnd(child);
+                    final int endReference = mOrientationHelper.getEndAfterPadding()
+                            - Math.min(0, previousEndMargin);
                     final int endMargin = endReference - estimatedEnd;
                     if (endMargin < 0) {
                         mCoordinate -= Math.min(startMargin, -endMargin);
@@ -2388,8 +2443,8 @@
 
         public void assignFromView(View child) {
             if (mLayoutFromEnd) {
-                mCoordinate = mOrientationHelper.getDecoratedEnd(child) +
-                        mOrientationHelper.getTotalSpaceChange();
+                mCoordinate = mOrientationHelper.getDecoratedEnd(child)
+                        + mOrientationHelper.getTotalSpaceChange();
             } else {
                 mCoordinate = mOrientationHelper.getDecoratedStart(child);
             }
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearSmoothScroller.java b/v7/recyclerview/src/android/support/v7/widget/LinearSmoothScroller.java
index 78250c1..74d6a3b 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LinearSmoothScroller.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LinearSmoothScroller.java
@@ -245,9 +245,9 @@
         // To avoid UI hiccups, trigger a smooth scroll to a distance little further than the
         // interim target. Since we track the distance travelled in onSeekTargetStep callback, it
         // won't actually scroll more than what we need.
-        action.update((int) (mInterimTargetDx * TARGET_SEEK_EXTRA_SCROLL_RATIO)
-                , (int) (mInterimTargetDy * TARGET_SEEK_EXTRA_SCROLL_RATIO)
-                , (int) (time * TARGET_SEEK_EXTRA_SCROLL_RATIO), mLinearInterpolator);
+        action.update((int) (mInterimTargetDx * TARGET_SEEK_EXTRA_SCROLL_RATIO),
+                (int) (mInterimTargetDy * TARGET_SEEK_EXTRA_SCROLL_RATIO),
+                (int) (time * TARGET_SEEK_EXTRA_SCROLL_RATIO), mLinearInterpolator);
     }
 
     private int clampApplyScroll(int tmpDt, int dt) {
@@ -354,8 +354,8 @@
             return ((ScrollVectorProvider) layoutManager)
                     .computeScrollVectorForPosition(targetPosition);
         }
-        Log.w(TAG, "You should override computeScrollVectorForPosition when the LayoutManager" +
-                " does not implement " + ScrollVectorProvider.class.getCanonicalName());
+        Log.w(TAG, "You should override computeScrollVectorForPosition when the LayoutManager"
+                + " does not implement " + ScrollVectorProvider.class.getCanonicalName());
         return null;
     }
 }
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java b/v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java
index 9e262db..0d41e6d 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java
@@ -10,7 +10,7 @@
  * 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 languag`e governing permissions and
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
@@ -139,8 +139,8 @@
 
     private int distanceToCenter(@NonNull RecyclerView.LayoutManager layoutManager,
             @NonNull View targetView, OrientationHelper helper) {
-        final int childCenter = helper.getDecoratedStart(targetView) +
-                (helper.getDecoratedMeasurement(targetView) / 2);
+        final int childCenter = helper.getDecoratedStart(targetView)
+                + (helper.getDecoratedMeasurement(targetView) / 2);
         final int containerCenter;
         if (layoutManager.getClipToPadding()) {
             containerCenter = helper.getStartAfterPadding() + helper.getTotalSpace() / 2;
@@ -205,8 +205,8 @@
 
         for (int i = 0; i < childCount; i++) {
             final View child = layoutManager.getChildAt(i);
-            int childCenter = helper.getDecoratedStart(child) +
-                    (helper.getDecoratedMeasurement(child) / 2);
+            int childCenter = helper.getDecoratedStart(child)
+                    + (helper.getDecoratedMeasurement(child) / 2);
             int absDistance = Math.abs(childCenter - center);
 
             /** if child center is closer than previous closest, set it as closest  **/
diff --git a/v7/recyclerview/src/android/support/v7/widget/OpReorderer.java b/v7/recyclerview/src/android/support/v7/widget/OpReorderer.java
index db01a0c..b288061 100644
--- a/v7/recyclerview/src/android/support/v7/widget/OpReorderer.java
+++ b/v7/recyclerview/src/android/support/v7/widget/OpReorderer.java
@@ -16,19 +16,20 @@
 
 package android.support.v7.widget;
 
-import java.util.List;
-
-import android.support.v7.widget.AdapterHelper.UpdateOp;
 import static android.support.v7.widget.AdapterHelper.UpdateOp.ADD;
 import static android.support.v7.widget.AdapterHelper.UpdateOp.MOVE;
 import static android.support.v7.widget.AdapterHelper.UpdateOp.REMOVE;
 import static android.support.v7.widget.AdapterHelper.UpdateOp.UPDATE;
 
+import android.support.v7.widget.AdapterHelper.UpdateOp;
+
+import java.util.List;
+
 class OpReorderer {
 
     final Callback mCallback;
 
-    public OpReorderer(Callback callback) {
+    OpReorderer(Callback callback) {
         mCallback = callback;
     }
 
@@ -72,8 +73,8 @@
             }
         } else {
             moveIsBackwards = true;
-            if (removeOp.positionStart == moveOp.itemCount + 1 &&
-                    removeOp.itemCount == moveOp.positionStart - moveOp.itemCount) {
+            if (removeOp.positionStart == moveOp.itemCount + 1
+                    && removeOp.itemCount == moveOp.positionStart - moveOp.itemCount) {
                 revertedMove = true;
             }
         }
@@ -83,7 +84,7 @@
             removeOp.positionStart--;
         } else if (moveOp.itemCount < removeOp.positionStart + removeOp.itemCount) {
             // move is removed.
-            removeOp.itemCount --;
+            removeOp.itemCount--;
             moveOp.cmd = REMOVE;
             moveOp.itemCount = 1;
             if (removeOp.itemCount == 0) {
@@ -229,7 +230,7 @@
         return -1;
     }
 
-    static interface Callback {
+    interface Callback {
 
         UpdateOp obtainUpdateOp(int cmd, int startPosition, int itemCount, Object payload);
 
diff --git a/v7/recyclerview/src/android/support/v7/widget/PositionMap.java b/v7/recyclerview/src/android/support/v7/widget/PositionMap.java
index 3777937..8225da4 100644
--- a/v7/recyclerview/src/android/support/v7/widget/PositionMap.java
+++ b/v7/recyclerview/src/android/support/v7/widget/PositionMap.java
@@ -33,7 +33,7 @@
     /**
      * Creates a new SparseArray containing no mappings.
      */
-    public PositionMap() {
+    PositionMap() {
         this(10);
     }
 
@@ -44,7 +44,7 @@
      * sparse array will be initialized with a light-weight representation
      * not requiring any additional array allocations.
      */
-    public PositionMap(int initialCapacity) {
+    PositionMap(int initialCapacity) {
         if (initialCapacity == 0) {
             mKeys = ContainerHelpers.EMPTY_INTS;
             mValues = ContainerHelpers.EMPTY_OBJECTS;
@@ -305,9 +305,11 @@
             gc();
         }
 
-        for (int i = 0; i < mSize; i++)
-            if (mValues[i] == value)
+        for (int i = 0; i < mSize; i++) {
+            if (mValues[i] == value) {
                 return i;
+            }
+        }
 
         return -1;
     }
@@ -376,7 +378,7 @@
 
         StringBuilder buffer = new StringBuilder(mSize * 28);
         buffer.append('{');
-        for (int i=0; i<mSize; i++) {
+        for (int i = 0; i < mSize; i++) {
             if (i > 0) {
                 buffer.append(", ");
             }
@@ -395,9 +397,11 @@
     }
 
     static int idealByteArraySize(int need) {
-        for (int i = 4; i < 32; i++)
-            if (need <= (1 << i) - 12)
+        for (int i = 4; i < 32; i++) {
+            if (need <= (1 << i) - 12) {
                 return (1 << i) - 12;
+            }
+        }
 
         return need;
     }
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index 479d684..ba01513 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -43,17 +43,14 @@
 import android.support.v4.os.TraceCompat;
 import android.support.v4.view.AbsSavedState;
 import android.support.v4.view.InputDeviceCompat;
-import android.support.v4.view.MotionEventCompat;
 import android.support.v4.view.NestedScrollingChild;
 import android.support.v4.view.NestedScrollingChildHelper;
 import android.support.v4.view.ScrollingView;
-import android.support.v4.view.VelocityTrackerCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
 import android.support.v4.view.accessibility.AccessibilityRecordCompat;
 import android.support.v4.widget.EdgeEffectCompat;
-import android.support.v4.widget.ScrollerCompat;
 import android.support.v7.recyclerview.R;
 import android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo;
 import android.util.AttributeSet;
@@ -71,6 +68,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Interpolator;
+import android.widget.OverScroller;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -156,8 +154,8 @@
 
     static final boolean VERBOSE_TRACING = false;
 
-    private static final int[]  NESTED_SCROLLING_ATTRS
-            = {16843830 /* android.R.attr.nestedScrollingEnabled */};
+    private static final int[]  NESTED_SCROLLING_ATTRS =
+            {16843830 /* android.R.attr.nestedScrollingEnabled */};
 
     private static final int[] CLIP_TO_PADDING_ATTR = {android.R.attr.clipToPadding};
 
@@ -509,38 +507,39 @@
      */
     private final ViewInfoStore.ProcessCallback mViewInfoProcessCallback =
             new ViewInfoStore.ProcessCallback() {
-        @Override
-        public void processDisappeared(ViewHolder viewHolder, @NonNull ItemHolderInfo info,
-                @Nullable ItemHolderInfo postInfo) {
-            mRecycler.unscrapView(viewHolder);
-            animateDisappearance(viewHolder, info, postInfo);
-        }
-        @Override
-        public void processAppeared(ViewHolder viewHolder,
-                ItemHolderInfo preInfo, ItemHolderInfo info) {
-            animateAppearance(viewHolder, preInfo, info);
-        }
-
-        @Override
-        public void processPersistent(ViewHolder viewHolder,
-                @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) {
-            viewHolder.setIsRecyclable(false);
-            if (mDataSetHasChangedAfterLayout) {
-                // since it was rebound, use change instead as we'll be mapping them from
-                // stable ids. If stable ids were false, we would not be running any
-                // animations
-                if (mItemAnimator.animateChange(viewHolder, viewHolder, preInfo, postInfo)) {
-                    postAnimationRunner();
+                @Override
+                public void processDisappeared(ViewHolder viewHolder, @NonNull ItemHolderInfo info,
+                        @Nullable ItemHolderInfo postInfo) {
+                    mRecycler.unscrapView(viewHolder);
+                    animateDisappearance(viewHolder, info, postInfo);
                 }
-            } else if (mItemAnimator.animatePersistence(viewHolder, preInfo, postInfo)) {
-                postAnimationRunner();
-            }
-        }
-        @Override
-        public void unused(ViewHolder viewHolder) {
-            mLayout.removeAndRecycleView(viewHolder.itemView, mRecycler);
-        }
-    };
+                @Override
+                public void processAppeared(ViewHolder viewHolder,
+                        ItemHolderInfo preInfo, ItemHolderInfo info) {
+                    animateAppearance(viewHolder, preInfo, info);
+                }
+
+                @Override
+                public void processPersistent(ViewHolder viewHolder,
+                        @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) {
+                    viewHolder.setIsRecyclable(false);
+                    if (mDataSetHasChangedAfterLayout) {
+                        // since it was rebound, use change instead as we'll be mapping them from
+                        // stable ids. If stable ids were false, we would not be running any
+                        // animations
+                        if (mItemAnimator.animateChange(viewHolder, viewHolder, preInfo,
+                                postInfo)) {
+                            postAnimationRunner();
+                        }
+                    } else if (mItemAnimator.animatePersistence(viewHolder, preInfo, postInfo)) {
+                        postAnimationRunner();
+                    }
+                }
+                @Override
+                public void unused(ViewHolder viewHolder) {
+                    mLayout.removeAndRecycleView(viewHolder.itemView, mRecycler);
+                }
+            };
 
     public RecyclerView(Context context) {
         this(context, null);
@@ -659,8 +658,8 @@
                             constructor = layoutManagerClass.getConstructor();
                         } catch (NoSuchMethodException e1) {
                             e1.initCause(e);
-                            throw new IllegalStateException(attrs.getPositionDescription() +
-                                    ": Error creating LayoutManager " + className, e1);
+                            throw new IllegalStateException(attrs.getPositionDescription()
+                                    + ": Error creating LayoutManager " + className, e1);
                         }
                     }
                     constructor.setAccessible(true);
@@ -742,7 +741,7 @@
             @Override
             public void removeAllViews() {
                 final int count = getChildCount();
-                for (int i = 0; i < count; i ++) {
+                for (int i = 0; i < count; i++) {
                     dispatchChildDetached(getChildAt(i));
                 }
                 RecyclerView.this.removeAllViews();
@@ -834,11 +833,13 @@
             }
 
             @Override
-            public void offsetPositionsForRemovingLaidOutOrNewView(int positionStart, int itemCount) {
+            public void offsetPositionsForRemovingLaidOutOrNewView(
+                    int positionStart, int itemCount) {
                 offsetPositionRecordsForRemove(positionStart, itemCount, false);
                 mItemsAddedOrRemoved = true;
             }
 
+
             @Override
             public void markViewHoldersUpdated(int positionStart, int itemCount, Object payload) {
                 viewRangeUpdate(positionStart, itemCount, payload);
@@ -954,7 +955,7 @@
         switch (slopConstant) {
             default:
                 Log.w(TAG, "setScrollingTouchSlop(): bad argument constant "
-                      + slopConstant + "; using default value");
+                        + slopConstant + "; using default value");
                 // fall-through
             case TOUCH_SLOP_DEFAULT:
                 mTouchSlop = vc.getScaledTouchSlop();
@@ -1178,8 +1179,8 @@
         mLayout = layout;
         if (layout != null) {
             if (layout.mRecyclerView != null) {
-                throw new IllegalArgumentException("LayoutManager " + layout +
-                        " is already attached to a RecyclerView: " + layout.mRecyclerView);
+                throw new IllegalArgumentException("LayoutManager " + layout
+                        + " is already attached to a RecyclerView: " + layout.mRecyclerView);
             }
             mLayout.setRecyclerView(this);
             if (mIsAttached) {
@@ -1271,7 +1272,7 @@
         if (viewHolder.isTmpDetached()) {
             // re-attach
             mChildHelper.attachViewToParent(view, -1, view.getLayoutParams(), true);
-        } else if(!alreadyParented) {
+        } else if (!alreadyParented) {
             mChildHelper.addView(view, true);
         } else {
             mChildHelper.hide(view);
@@ -1537,8 +1538,8 @@
         }
         stopScroll();
         if (mLayout == null) {
-            Log.e(TAG, "Cannot scroll to position a LayoutManager set. " +
-                    "Call setLayoutManager with a non-null argument.");
+            Log.e(TAG, "Cannot scroll to position a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
             return;
         }
         mLayout.scrollToPosition(position);
@@ -1573,8 +1574,8 @@
             return;
         }
         if (mLayout == null) {
-            Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. " +
-                    "Call setLayoutManager with a non-null argument.");
+            Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
             return;
         }
         mLayout.smoothScrollToPosition(this, mState, position);
@@ -1589,8 +1590,8 @@
     @Override
     public void scrollBy(int x, int y) {
         if (mLayout == null) {
-            Log.e(TAG, "Cannot scroll without a LayoutManager set. " +
-                    "Call setLayoutManager with a non-null argument.");
+            Log.e(TAG, "Cannot scroll without a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
             return;
         }
         if (mLayoutFrozen) {
@@ -1902,8 +1903,8 @@
         }
         if (mEatRequestLayout == 1) {
             // when layout is frozen we should delay dispatchLayout()
-            if (performLayoutChildren && mLayoutRequestEaten && !mLayoutFrozen &&
-                    mLayout != null && mAdapter != null) {
+            if (performLayoutChildren && mLayoutRequestEaten && !mLayoutFrozen
+                    && mLayout != null && mAdapter != null) {
                 dispatchLayout();
             }
             if (!mLayoutFrozen) {
@@ -1986,8 +1987,8 @@
      */
     public void smoothScrollBy(int dx, int dy, Interpolator interpolator) {
         if (mLayout == null) {
-            Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. " +
-                    "Call setLayoutManager with a non-null argument.");
+            Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
             return;
         }
         if (mLayoutFrozen) {
@@ -2019,8 +2020,8 @@
      */
     public boolean fling(int velocityX, int velocityY) {
         if (mLayout == null) {
-            Log.e(TAG, "Cannot fling without a LayoutManager set. " +
-                    "Call setLayoutManager with a non-null argument.");
+            Log.e(TAG, "Cannot fling without a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
             return false;
         }
         if (mLayoutFrozen) {
@@ -2332,6 +2333,13 @@
                 resumeRequestLayout(false);
             }
         }
+        if (result != null && !result.hasFocusable()) {
+            // If the next view returned by onFocusSearchFailed in layout manager has no focusable
+            // views, we still scroll to that view in order to make it visible on the screen.
+            // If it's focusable, framework already calls RV's requestChildFocus which handles
+            // bringing this newly focused item onto the screen.
+            requestChildOnScreen(result, null);
+        }
         return isPreferredNextFocus(focused, result, direction)
                 ? result : super.focusSearch(focused, direction);
     }
@@ -2352,7 +2360,7 @@
             return true;
         }
 
-        if(direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD) {
+        if (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD) {
             final boolean rtl = mLayout.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL;
             final int absHorizontal = (direction == View.FOCUS_FORWARD) ^ rtl
                     ? View.FOCUS_RIGHT : View.FOCUS_LEFT;
@@ -2402,31 +2410,48 @@
     @Override
     public void requestChildFocus(View child, View focused) {
         if (!mLayout.onRequestChildFocus(this, mState, child, focused) && focused != null) {
-            mTempRect.set(0, 0, focused.getWidth(), focused.getHeight());
-
-            // get item decor offsets w/o refreshing. If they are invalid, there will be another
-            // layout pass to fix them, then it is LayoutManager's responsibility to keep focused
-            // View in viewport.
-            final ViewGroup.LayoutParams focusedLayoutParams = focused.getLayoutParams();
-            if (focusedLayoutParams instanceof LayoutParams) {
-                // if focused child has item decors, use them. Otherwise, ignore.
-                final LayoutParams lp = (LayoutParams) focusedLayoutParams;
-                if (!lp.mInsetsDirty) {
-                    final Rect insets = lp.mDecorInsets;
-                    mTempRect.left -= insets.left;
-                    mTempRect.right += insets.right;
-                    mTempRect.top -= insets.top;
-                    mTempRect.bottom += insets.bottom;
-                }
-            }
-
-            offsetDescendantRectToMyCoords(focused, mTempRect);
-            offsetRectIntoDescendantCoords(child, mTempRect);
-            requestChildRectangleOnScreen(child, mTempRect, !mFirstLayoutComplete);
+            requestChildOnScreen(child, focused);
         }
         super.requestChildFocus(child, focused);
     }
 
+    /**
+     * Requests that the given child of the RecyclerView be positioned onto the screen. This method
+     * can be called for both unfocusable and focusable child views. For unfocusable child views,
+     * the {@param focused} parameter passed is null, whereas for a focusable child, this parameter
+     * indicates the actual descendant view within this child view that holds the focus.
+     * @param child The child view of this RecyclerView that wants to come onto the screen.
+     * @param focused The descendant view that actually has the focus if child is focusable, null
+     *                otherwise.
+     */
+    private void requestChildOnScreen(@NonNull View child, @Nullable View focused) {
+        View rectView = (focused != null) ? focused : child;
+        mTempRect.set(0, 0, rectView.getWidth(), rectView.getHeight());
+
+        // get item decor offsets w/o refreshing. If they are invalid, there will be another
+        // layout pass to fix them, then it is LayoutManager's responsibility to keep focused
+        // View in viewport.
+        final ViewGroup.LayoutParams focusedLayoutParams = rectView.getLayoutParams();
+        if (focusedLayoutParams instanceof LayoutParams) {
+            // if focused child has item decors, use them. Otherwise, ignore.
+            final LayoutParams lp = (LayoutParams) focusedLayoutParams;
+            if (!lp.mInsetsDirty) {
+                final Rect insets = lp.mDecorInsets;
+                mTempRect.left -= insets.left;
+                mTempRect.right += insets.right;
+                mTempRect.top -= insets.top;
+                mTempRect.bottom += insets.bottom;
+            }
+        }
+
+        if (focused != null) {
+            offsetDescendantRectToMyCoords(focused, mTempRect);
+            offsetRectIntoDescendantCoords(child, mTempRect);
+        }
+        mLayout.requestChildRectangleOnScreen(this, child, mTempRect, !mFirstLayoutComplete,
+                (focused == null));
+    }
+
     @Override
     public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
         return mLayout.requestChildRectangleOnScreen(this, child, rect, immediate);
@@ -2547,10 +2572,11 @@
             throw new IllegalStateException(message);
         }
         if (mDispatchScrollCounter > 0) {
-            Log.w(TAG, "Cannot call this method in a scroll callback. Scroll callbacks might be run"
-                    + " during a measure & layout pass where you cannot change the RecyclerView"
-                    + " data. Any method call that might change the structure of the RecyclerView"
-                    + " or the adapter contents should be postponed to the next frame.",
+            Log.w(TAG, "Cannot call this method in a scroll callback. Scroll callbacks might"
+                            + "be run during a measure & layout pass where you cannot change the"
+                            + "RecyclerView data. Any method call that might change the structure"
+                            + "of the RecyclerView or the adapter contents should be postponed to"
+                            + "the next frame.",
                     new IllegalStateException(""));
         }
     }
@@ -2656,8 +2682,8 @@
         }
         mVelocityTracker.addMovement(e);
 
-        final int action = MotionEventCompat.getActionMasked(e);
-        final int actionIndex = MotionEventCompat.getActionIndex(e);
+        final int action = e.getActionMasked();
+        final int actionIndex = e.getActionIndex();
 
         switch (action) {
             case MotionEvent.ACTION_DOWN:
@@ -2686,7 +2712,7 @@
                 startNestedScroll(nestedScrollAxis);
                 break;
 
-            case MotionEventCompat.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_POINTER_DOWN:
                 mScrollPointerId = e.getPointerId(actionIndex);
                 mInitialTouchX = mLastTouchX = (int) (e.getX(actionIndex) + 0.5f);
                 mInitialTouchY = mLastTouchY = (int) (e.getY(actionIndex) + 0.5f);
@@ -2695,8 +2721,8 @@
             case MotionEvent.ACTION_MOVE: {
                 final int index = e.findPointerIndex(mScrollPointerId);
                 if (index < 0) {
-                    Log.e(TAG, "Error processing scroll; pointer index for id " +
-                            mScrollPointerId + " not found. Did any MotionEvents get skipped?");
+                    Log.e(TAG, "Error processing scroll; pointer index for id "
+                            + mScrollPointerId + " not found. Did any MotionEvents get skipped?");
                     return false;
                 }
 
@@ -2720,7 +2746,7 @@
                 }
             } break;
 
-            case MotionEventCompat.ACTION_POINTER_UP: {
+            case MotionEvent.ACTION_POINTER_UP: {
                 onPointerUp(e);
             } break;
 
@@ -2769,8 +2795,8 @@
         boolean eventAddedToVelocityTracker = false;
 
         final MotionEvent vtev = MotionEvent.obtain(e);
-        final int action = MotionEventCompat.getActionMasked(e);
-        final int actionIndex = MotionEventCompat.getActionIndex(e);
+        final int action = e.getActionMasked();
+        final int actionIndex = e.getActionIndex();
 
         if (action == MotionEvent.ACTION_DOWN) {
             mNestedOffsets[0] = mNestedOffsets[1] = 0;
@@ -2793,7 +2819,7 @@
                 startNestedScroll(nestedScrollAxis);
             } break;
 
-            case MotionEventCompat.ACTION_POINTER_DOWN: {
+            case MotionEvent.ACTION_POINTER_DOWN: {
                 mScrollPointerId = e.getPointerId(actionIndex);
                 mInitialTouchX = mLastTouchX = (int) (e.getX(actionIndex) + 0.5f);
                 mInitialTouchY = mLastTouchY = (int) (e.getY(actionIndex) + 0.5f);
@@ -2802,8 +2828,8 @@
             case MotionEvent.ACTION_MOVE: {
                 final int index = e.findPointerIndex(mScrollPointerId);
                 if (index < 0) {
-                    Log.e(TAG, "Error processing scroll; pointer index for id " +
-                            mScrollPointerId + " not found. Did any MotionEvents get skipped?");
+                    Log.e(TAG, "Error processing scroll; pointer index for id "
+                            + mScrollPointerId + " not found. Did any MotionEvents get skipped?");
                     return false;
                 }
 
@@ -2860,7 +2886,7 @@
                 }
             } break;
 
-            case MotionEventCompat.ACTION_POINTER_UP: {
+            case MotionEvent.ACTION_POINTER_UP: {
                 onPointerUp(e);
             } break;
 
@@ -2868,10 +2894,10 @@
                 mVelocityTracker.addMovement(vtev);
                 eventAddedToVelocityTracker = true;
                 mVelocityTracker.computeCurrentVelocity(1000, mMaxFlingVelocity);
-                final float xvel = canScrollHorizontally ?
-                        -VelocityTrackerCompat.getXVelocity(mVelocityTracker, mScrollPointerId) : 0;
-                final float yvel = canScrollVertically ?
-                        -VelocityTrackerCompat.getYVelocity(mVelocityTracker, mScrollPointerId) : 0;
+                final float xvel = canScrollHorizontally
+                        ? -mVelocityTracker.getXVelocity(mScrollPointerId) : 0;
+                final float yvel = canScrollVertically
+                        ? -mVelocityTracker.getYVelocity(mScrollPointerId) : 0;
                 if (!((xvel != 0 || yvel != 0) && fling((int) xvel, (int) yvel))) {
                     setScrollState(SCROLL_STATE_IDLE);
                 }
@@ -2905,7 +2931,7 @@
     }
 
     private void onPointerUp(MotionEvent e) {
-        final int actionIndex = MotionEventCompat.getActionIndex(e);
+        final int actionIndex = e.getActionIndex();
         if (e.getPointerId(actionIndex) == mScrollPointerId) {
             // Pick a new pointer to pick up the slack.
             final int newIndex = actionIndex == 0 ? 1 : 0;
@@ -2924,19 +2950,17 @@
             return false;
         }
         if ((event.getSource() & InputDeviceCompat.SOURCE_CLASS_POINTER) != 0) {
-            if (event.getAction() == MotionEventCompat.ACTION_SCROLL) {
+            if (event.getAction() == MotionEvent.ACTION_SCROLL) {
                 final float vScroll, hScroll;
                 if (mLayout.canScrollVertically()) {
                     // Inverse the sign of the vertical scroll to align the scroll orientation
                     // with AbsListView.
-                    vScroll = -MotionEventCompat
-                            .getAxisValue(event, MotionEventCompat.AXIS_VSCROLL);
+                    vScroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
                 } else {
                     vScroll = 0f;
                 }
                 if (mLayout.canScrollHorizontally()) {
-                    hScroll = MotionEventCompat
-                            .getAxisValue(event, MotionEventCompat.AXIS_HSCROLL);
+                    hScroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
                 } else {
                     hScroll = 0f;
                 }
@@ -3089,11 +3113,11 @@
     }
 
     void onEnterLayoutOrScroll() {
-        mLayoutOrScrollCounter ++;
+        mLayoutOrScrollCounter++;
     }
 
     void onExitLayoutOrScroll() {
-        mLayoutOrScrollCounter --;
+        mLayoutOrScrollCounter--;
         if (mLayoutOrScrollCounter < 1) {
             if (DEBUG && mLayoutOrScrollCounter < 0) {
                 throw new IllegalStateException("layout or scroll counter cannot go below zero."
@@ -3227,10 +3251,10 @@
         mState.mRunSimpleAnimations = mFirstLayoutComplete
                 && mItemAnimator != null
                 && (mDataSetHasChangedAfterLayout
-                        || animationTypeSupported
-                        || mLayout.mRequestedSimpleAnimations)
+                || animationTypeSupported
+                || mLayout.mRequestedSimpleAnimations)
                 && (!mDataSetHasChangedAfterLayout
-                        || mAdapter.hasStableIds());
+                || mAdapter.hasStableIds());
         mState.mRunPredictiveAnimations = mState.mRunSimpleAnimations
                 && animationTypeSupported
                 && !mDataSetHasChangedAfterLayout
@@ -3278,8 +3302,8 @@
             dispatchLayoutStep1();
             mLayout.setExactMeasureSpecsFrom(this);
             dispatchLayoutStep2();
-        } else if (mAdapterHelper.hasUpdates() || mLayout.getWidth() != getWidth() ||
-                mLayout.getHeight() != getHeight()) {
+        } else if (mAdapterHelper.hasUpdates() || mLayout.getWidth() != getWidth()
+                || mLayout.getHeight() != getHeight()) {
             // First 2 steps are done in onMeasure but looks like we have to run again due to
             // changed size.
             mLayout.setExactMeasureSpecsFrom(this);
@@ -3305,8 +3329,8 @@
             // mFocusedItemPosition should hold the current adapter position of the previously
             // focused item. If the item is removed, we store the previous adapter position of the
             // removed item.
-            mState.mFocusedItemPosition = mDataSetHasChangedAfterLayout ? NO_POSITION :
-                    (focusedVh.isRemoved() ? focusedVh.mOldPosition
+            mState.mFocusedItemPosition = mDataSetHasChangedAfterLayout ? NO_POSITION
+                    : (focusedVh.isRemoved() ? focusedVh.mOldPosition
                             : focusedVh.getAdapterPosition());
             mState.mFocusedSubChildId = getDeepestFocusedViewWithId(focusedVh.itemView);
         }
@@ -3739,8 +3763,8 @@
 
     private boolean didChildRangeChange(int minPositionPreLayout, int maxPositionPreLayout) {
         findMinMaxChildLayoutPositions(mMinMaxLayoutPositions);
-        return mMinMaxLayoutPositions[0] != minPositionPreLayout ||
-                mMinMaxLayoutPositions[1] != maxPositionPreLayout;
+        return mMinMaxLayoutPositions[0] != minPositionPreLayout
+                || mMinMaxLayoutPositions[1] != maxPositionPreLayout;
     }
 
     @Override
@@ -3883,8 +3907,8 @@
         // If some views are animating, ItemDecorators are likely to move/change with them.
         // Invalidate RecyclerView to re-draw decorators. This is still efficient because children's
         // display lists are not invalidated.
-        if (!needsInvalidate && mItemAnimator != null && mItemDecorations.size() > 0 &&
-                mItemAnimator.isRunning()) {
+        if (!needsInvalidate && mItemAnimator != null && mItemDecorations.size() > 0
+                && mItemAnimator.isRunning()) {
             needsInvalidate = true;
         }
 
@@ -3988,8 +4012,8 @@
                 continue;
             }
             if (DEBUG) {
-                Log.d(TAG, "offsetPositionRecordsForMove attached child " + i + " holder " +
-                        holder);
+                Log.d(TAG, "offsetPositionRecordsForMove attached child " + i + " holder "
+                        + holder);
             }
             if (holder.mPosition == from) {
                 holder.offsetPosition(to - from, false);
@@ -4009,8 +4033,8 @@
             final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
             if (holder != null && !holder.shouldIgnore() && holder.mPosition >= positionStart) {
                 if (DEBUG) {
-                    Log.d(TAG, "offsetPositionRecordsForInsert attached child " + i + " holder " +
-                            holder + " now at position " + (holder.mPosition + itemCount));
+                    Log.d(TAG, "offsetPositionRecordsForInsert attached child " + i + " holder "
+                            + holder + " now at position " + (holder.mPosition + itemCount));
                 }
                 holder.offsetPosition(itemCount, false);
                 mState.mStructureChanged = true;
@@ -4029,16 +4053,16 @@
             if (holder != null && !holder.shouldIgnore()) {
                 if (holder.mPosition >= positionEnd) {
                     if (DEBUG) {
-                        Log.d(TAG, "offsetPositionRecordsForRemove attached child " + i +
-                                " holder " + holder + " now at position " +
-                                (holder.mPosition - itemCount));
+                        Log.d(TAG, "offsetPositionRecordsForRemove attached child " + i
+                                + " holder " + holder + " now at position "
+                                + (holder.mPosition - itemCount));
                     }
                     holder.offsetPosition(-itemCount, applyToPreLayout);
                     mState.mStructureChanged = true;
                 } else if (holder.mPosition >= positionStart) {
                     if (DEBUG) {
-                        Log.d(TAG, "offsetPositionRecordsForRemove attached child " + i +
-                                " holder " + holder + " now REMOVED");
+                        Log.d(TAG, "offsetPositionRecordsForRemove attached child " + i
+                                + " holder " + holder + " now REMOVED");
                     }
                     holder.flagRemovedAndOffsetPosition(positionStart - 1, -itemCount,
                             applyToPreLayout);
@@ -4189,8 +4213,8 @@
     public ViewHolder getChildViewHolder(View child) {
         final ViewParent parent = child.getParent();
         if (parent != null && parent != this) {
-            throw new IllegalArgumentException("View " + child + " is not a direct child of " +
-                    this);
+            throw new IllegalArgumentException("View " + child + " is not a direct child of "
+                    + this);
         }
         return getChildViewHolderInt(child);
     }
@@ -4347,7 +4371,8 @@
         ViewHolder hidden = null;
         for (int i = 0; i < childCount; i++) {
             final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
-            if (holder != null && !holder.isRemoved() && getAdapterPositionFor(holder) == position) {
+            if (holder != null && !holder.isRemoved()
+                    && getAdapterPositionFor(holder) == position) {
                 if (mChildHelper.isHidden(holder.itemView)) {
                     hidden = holder;
                 } else {
@@ -4428,12 +4453,12 @@
         final int count = mChildHelper.getChildCount();
         for (int i = count - 1; i >= 0; i--) {
             final View child = mChildHelper.getChildAt(i);
-            final float translationX = ViewCompat.getTranslationX(child);
-            final float translationY = ViewCompat.getTranslationY(child);
-            if (x >= child.getLeft() + translationX &&
-                    x <= child.getRight() + translationX &&
-                    y >= child.getTop() + translationY &&
-                    y <= child.getBottom() + translationY) {
+            final float translationX = child.getTranslationX();
+            final float translationY = child.getTranslationY();
+            if (x >= child.getLeft() + translationX
+                    && x <= child.getRight() + translationX
+                    && y >= child.getTop() + translationY
+                    && y <= child.getBottom() + translationY) {
                 return child;
             }
         }
@@ -4566,7 +4591,7 @@
     }
 
     void dispatchOnScrolled(int hresult, int vresult) {
-        mDispatchScrollCounter ++;
+        mDispatchScrollCounter++;
         // Pass the current scrollX/scrollY values; no actual change in these properties occurred
         // but some general-purpose code may choose to respond to changes this way.
         final int scrollX = getScrollX();
@@ -4586,7 +4611,7 @@
                 mScrollListeners.get(i).onScrolled(this, hresult, vresult);
             }
         }
-        mDispatchScrollCounter --;
+        mDispatchScrollCounter--;
     }
 
     /**
@@ -4646,7 +4671,7 @@
     class ViewFlinger implements Runnable {
         private int mLastFlingX;
         private int mLastFlingY;
-        private ScrollerCompat mScroller;
+        private OverScroller mScroller;
         Interpolator mInterpolator = sQuinticInterpolator;
 
 
@@ -4656,8 +4681,8 @@
         // Tracks if postAnimationCallback should be re-attached when it is done
         private boolean mReSchedulePostAnimationCallback = false;
 
-        public ViewFlinger() {
-            mScroller = ScrollerCompat.create(getContext(), sQuinticInterpolator);
+        ViewFlinger() {
+            mScroller = new OverScroller(getContext(), sQuinticInterpolator);
         }
 
         @Override
@@ -4670,7 +4695,7 @@
             consumePendingUpdateOperations();
             // keep a local reference so that if it is changed during onAnimation method, it won't
             // cause unexpected behaviors
-            final ScrollerCompat scroller = mScroller;
+            final OverScroller scroller = mScroller;
             final SmoothScroller smoothScroller = mLayout.mSmoothScroller;
             if (scroller.computeScrollOffset()) {
                 final int x = scroller.getCurrX();
@@ -4700,8 +4725,8 @@
                     onExitLayoutOrScroll();
                     resumeRequestLayout(false);
 
-                    if (smoothScroller != null && !smoothScroller.isPendingInitialRun() &&
-                            smoothScroller.isRunning()) {
+                    if (smoothScroller != null && !smoothScroller.isPendingInitialRun()
+                            && smoothScroller.isRunning()) {
                         final int adapterSize = mState.getItemCount();
                         if (adapterSize == 0) {
                             smoothScroller.stop();
@@ -4735,8 +4760,8 @@
                     if (getOverScrollMode() != View.OVER_SCROLL_NEVER) {
                         absorbGlows(velX, velY);
                     }
-                    if ((velX != 0 || overscrollX == x || scroller.getFinalX() == 0) &&
-                            (velY != 0 || overscrollY == y || scroller.getFinalY() == 0)) {
+                    if ((velX != 0 || overscrollX == x || scroller.getFinalX() == 0)
+                            && (velY != 0 || overscrollY == y || scroller.getFinalY() == 0)) {
                         scroller.abortAnimation();
                     }
                 }
@@ -4831,8 +4856,8 @@
             final int containerSize = horizontal ? getWidth() : getHeight();
             final int halfContainerSize = containerSize / 2;
             final float distanceRatio = Math.min(1.f, 1.f * delta / containerSize);
-            final float distance = halfContainerSize + halfContainerSize *
-                    distanceInfluenceForSnapDuration(distanceRatio);
+            final float distance = halfContainerSize + halfContainerSize
+                    * distanceInfluenceForSnapDuration(distanceRatio);
 
             final int duration;
             if (velocity > 0) {
@@ -4856,7 +4881,7 @@
         public void smoothScrollBy(int dx, int dy, int duration, Interpolator interpolator) {
             if (mInterpolator != interpolator) {
                 mInterpolator = interpolator;
-                mScroller = ScrollerCompat.create(getContext(), interpolator);
+                mScroller = new OverScroller(getContext(), interpolator);
             }
             setScrollState(SCROLL_STATE_SETTLING);
             mLastFlingX = mLastFlingY = 0;
@@ -4881,8 +4906,7 @@
                 View shadowingView = holder.mShadowingHolder.itemView;
                 int left = view.getLeft();
                 int top = view.getTop();
-                if (left != shadowingView.getLeft() ||
-                        top != shadowingView.getTop()) {
+                if (left != shadowingView.getLeft() ||  top != shadowingView.getTop()) {
                     shadowingView.layout(left, top,
                             left + shadowingView.getWidth(),
                             top + shadowingView.getHeight());
@@ -5020,7 +5044,7 @@
 
         int size() {
             int count = 0;
-            for (int i = 0; i < mScrap.size(); i ++) {
+            for (int i = 0; i < mScrap.size(); i++) {
                 ArrayList<ViewHolder> viewHolders = mScrap.valueAt(i).mScrapHeap;
                 if (viewHolders != null) {
                     count += viewHolders.size();
@@ -5584,8 +5608,8 @@
 
         private void attachAccessibilityDelegate(View itemView) {
             if (isAccessibilityEnabled()) {
-                if (ViewCompat.getImportantForAccessibility(itemView) ==
-                        ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+                if (ViewCompat.getImportantForAccessibility(itemView)
+                        == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
                     ViewCompat.setImportantForAccessibility(itemView,
                             ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
                 }
@@ -5642,7 +5666,7 @@
             }
             if (holder.isScrap()) {
                 holder.unScrap();
-            } else if (holder.wasReturnedFromScrap()){
+            } else if (holder.wasReturnedFromScrap()) {
                 holder.clearReturnedFromScrapFlag();
             }
             recycleViewHolderInternal(holder);
@@ -5722,15 +5746,15 @@
             boolean cached = false;
             boolean recycled = false;
             if (DEBUG && mCachedViews.contains(holder)) {
-                throw new IllegalArgumentException("cached view received recycle internal? " +
-                        holder);
+                throw new IllegalArgumentException("cached view received recycle internal? "
+                        + holder);
             }
             if (forceRecycle || holder.isRecyclable()) {
                 if (mViewCacheMax > 0
                         && !holder.hasAnyOfTheFlags(ViewHolder.FLAG_INVALID
-                                | ViewHolder.FLAG_REMOVED
-                                | ViewHolder.FLAG_UPDATE
-                                | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)) {
+                        | ViewHolder.FLAG_REMOVED
+                        | ViewHolder.FLAG_UPDATE
+                        | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)) {
                     // Retire oldest cached view
                     int cachedViewSize = mCachedViews.size();
                     if (cachedViewSize >= mViewCacheMax && cachedViewSize > 0) {
@@ -5981,8 +6005,8 @@
                             // because item was invisible to us and we don't know what happened in
                             // between.
                             if (!mState.isPreLayout()) {
-                                holder.setFlags(ViewHolder.FLAG_UPDATE, ViewHolder.FLAG_UPDATE |
-                                        ViewHolder.FLAG_INVALID | ViewHolder.FLAG_REMOVED);
+                                holder.setFlags(ViewHolder.FLAG_UPDATE, ViewHolder.FLAG_UPDATE
+                                        | ViewHolder.FLAG_INVALID | ViewHolder.FLAG_REMOVED);
                             }
                         }
                         return holder;
@@ -6058,8 +6082,8 @@
                     holder.offsetPosition(inBetweenOffset, false);
                 }
                 if (DEBUG) {
-                    Log.d(TAG, "offsetPositionRecordsForMove cached child " + i + " holder " +
-                            holder);
+                    Log.d(TAG, "offsetPositionRecordsForMove cached child " + i + " holder "
+                            + holder);
                 }
             }
         }
@@ -6070,8 +6094,8 @@
                 final ViewHolder holder = mCachedViews.get(i);
                 if (holder != null && holder.mPosition >= insertedAt) {
                     if (DEBUG) {
-                        Log.d(TAG, "offsetPositionRecordsForInsert cached " + i + " holder " +
-                                holder + " now at position " + (holder.mPosition + count));
+                        Log.d(TAG, "offsetPositionRecordsForInsert cached " + i + " holder "
+                                + holder + " now at position " + (holder.mPosition + count));
                     }
                     holder.offsetPosition(count, true);
                 }
@@ -6092,9 +6116,9 @@
                 if (holder != null) {
                     if (holder.mPosition >= removedEnd) {
                         if (DEBUG) {
-                            Log.d(TAG, "offsetPositionRecordsForRemove cached " + i +
-                                    " holder " + holder + " now at position " +
-                                    (holder.mPosition - count));
+                            Log.d(TAG, "offsetPositionRecordsForRemove cached " + i
+                                    + " holder " + holder + " now at position "
+                                    + (holder.mPosition - count));
                         }
                         holder.offsetPosition(-count, applyToPreLayout);
                     } else if (holder.mPosition >= removedFrom) {
@@ -6233,7 +6257,7 @@
          * @return A View that is bound to the given position or NULL if there is no View to re-use
          * @see LayoutManager#ignoreView(View)
          */
-        abstract public View getViewForPositionAndType(Recycler recycler, int position, int type);
+        public abstract View getViewForPositionAndType(Recycler recycler, int position, int type);
     }
 
     /**
@@ -6241,8 +6265,10 @@
      *
      * <p>Adapters provide a binding from an app-specific data set to views that are displayed
      * within a {@link RecyclerView}.</p>
+     *
+     * @param <VH> A class that extends ViewHolder that will be used by the adapter.
      */
-    public static abstract class Adapter<VH extends ViewHolder> {
+    public abstract static class Adapter<VH extends ViewHolder> {
         private final AdapterDataObservable mObservable = new AdapterDataObservable();
         private boolean mHasStableIds = false;
 
@@ -6389,8 +6415,8 @@
          */
         public void setHasStableIds(boolean hasStableIds) {
             if (hasObservers()) {
-                throw new IllegalStateException("Cannot change whether this adapter has " +
-                        "stable IDs while the adapter has registered observers.");
+                throw new IllegalStateException("Cannot change whether this adapter has "
+                        + "stable IDs while the adapter has registered observers.");
             }
             mHasStableIds = hasStableIds;
         }
@@ -6621,8 +6647,8 @@
         }
 
         /**
-         * Notify any registered observers that the item at <code>position</code> has changed with an
-         * optional payload object.
+         * Notify any registered observers that the item at <code>position</code> has changed with
+         * an optional payload object.
          *
          * <p>This is an item change event, not a structural change event. It indicates that any
          * reflection of the data at <code>position</code> is out of date and should be updated.
@@ -6826,10 +6852,113 @@
      * precedence.
      *
      */
-    public static abstract class LayoutManager {
+    public abstract static class LayoutManager {
         ChildHelper mChildHelper;
         RecyclerView mRecyclerView;
 
+        /**
+         * The callback used for retrieving information about a RecyclerView and its children in the
+         * horizontal direction.
+         */
+        private final ViewBoundsCheck.Callback mHorizontalBoundCheckCallback =
+                new ViewBoundsCheck.Callback() {
+                    @Override
+                    public int getChildCount() {
+                        return LayoutManager.this.getChildCount();
+                    }
+
+                    @Override
+                    public View getParent() {
+                        return mRecyclerView;
+                    }
+
+                    @Override
+                    public View getChildAt(int index) {
+                        return LayoutManager.this.getChildAt(index);
+                    }
+
+                    @Override
+                    public int getParentStart() {
+                        return LayoutManager.this.getPaddingLeft();
+                    }
+
+                    @Override
+                    public int getParentEnd() {
+                        return LayoutManager.this.getWidth() - LayoutManager.this.getPaddingRight();
+                    }
+
+                    @Override
+                    public int getChildStart(View view) {
+                        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                                view.getLayoutParams();
+                        return LayoutManager.this.getDecoratedLeft(view) - params.leftMargin;
+                    }
+
+                    @Override
+                    public int getChildEnd(View view) {
+                        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                                view.getLayoutParams();
+                        return LayoutManager.this.getDecoratedRight(view) + params.rightMargin;
+                    }
+                };
+
+        /**
+         * The callback used for retrieving information about a RecyclerView and its children in the
+         * vertical direction.
+         */
+        private final ViewBoundsCheck.Callback mVerticalBoundCheckCallback =
+                new ViewBoundsCheck.Callback() {
+                    @Override
+                    public int getChildCount() {
+                        return LayoutManager.this.getChildCount();
+                    }
+
+                    @Override
+                    public View getParent() {
+                        return mRecyclerView;
+                    }
+
+                    @Override
+                    public View getChildAt(int index) {
+                        return LayoutManager.this.getChildAt(index);
+                    }
+
+                    @Override
+                    public int getParentStart() {
+                        return LayoutManager.this.getPaddingTop();
+                    }
+
+                    @Override
+                    public int getParentEnd() {
+                        return LayoutManager.this.getHeight()
+                                - LayoutManager.this.getPaddingBottom();
+                    }
+
+                    @Override
+                    public int getChildStart(View view) {
+                        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                                view.getLayoutParams();
+                        return LayoutManager.this.getDecoratedTop(view) - params.topMargin;
+                    }
+
+                    @Override
+                    public int getChildEnd(View view) {
+                        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                                view.getLayoutParams();
+                        return LayoutManager.this.getDecoratedBottom(view) + params.bottomMargin;
+                    }
+                };
+
+        /**
+         * Utility objects used to check the boundaries of children against their parent
+         * RecyclerView.
+         * @see #isViewPartiallyVisible(View, boolean, boolean),
+         * {@link LinearLayoutManager#findOneVisibleChild(int, int, boolean, boolean)},
+         * and {@link LinearLayoutManager#findOnePartiallyOrCompletelyInvisibleChild(int, int)}.
+         */
+        ViewBoundsCheck mHorizontalBoundCheck = new ViewBoundsCheck(mHorizontalBoundCheckCallback);
+        ViewBoundsCheck mVerticalBoundCheck = new ViewBoundsCheck(mVerticalBoundCheckCallback);
+
         @Nullable
         SmoothScroller mSmoothScroller;
 
@@ -7003,7 +7132,7 @@
          * Calls {@code RecyclerView#requestLayout} on the underlying RecyclerView
          */
         public void requestLayout() {
-            if(mRecyclerView != null) {
+            if (mRecyclerView != null) {
                 mRecyclerView.requestLayout();
             }
         }
@@ -7210,9 +7339,9 @@
          * which positions the LayoutManager will soon need, given upcoming movement in subsequent
          * traversals.</p>
          *
-         * <p>The LayoutManager should call {@link LayoutPrefetchRegistry#addPosition(int, int)} for each
-         * item to be prepared, and these positions will have their ViewHolders created and bound,
-         * if there is sufficient time available, in advance of being needed by a
+         * <p>The LayoutManager should call {@link LayoutPrefetchRegistry#addPosition(int, int)} for
+         * each item to be prepared, and these positions will have their ViewHolders created and
+         * bound, if there is sufficient time available, in advance of being needed by a
          * scroll or layout.</p>
          *
          * @param dx X movement component.
@@ -7240,9 +7369,9 @@
          * vertically scrolling LayoutManager, this method would be called when the horizontal list
          * is about to come onscreen.</p>
          *
-         * <p>The LayoutManager should call {@link LayoutPrefetchRegistry#addPosition(int, int)} for each
-         * item to be prepared, and these positions will have their ViewHolders created and bound,
-         * if there is sufficient time available, in advance of being needed by a
+         * <p>The LayoutManager should call {@link LayoutPrefetchRegistry#addPosition(int, int)} for
+         * each item to be prepared, and these positions will have their ViewHolders created and
+         * bound, if there is sufficient time available, in advance of being needed by a
          * scroll or layout.</p>
          *
          * @param adapterItemCount number of items in the associated adapter.
@@ -7875,8 +8004,8 @@
                 if (vh == null) {
                     continue;
                 }
-                if (vh.getLayoutPosition() == position && !vh.shouldIgnore() &&
-                        (mRecyclerView.mState.isPreLayout() || !vh.isRemoved())) {
+                if (vh.getLayoutPosition() == position && !vh.shouldIgnore()
+                        && (mRecyclerView.mState.isPreLayout() || !vh.isRemoved())) {
                     return child;
                 }
             }
@@ -8219,9 +8348,11 @@
         /**
          * Returns the number of items in the adapter bound to the parent RecyclerView.
          * <p>
-         * Note that this number is not necessarily equal to {@link State#getItemCount()}. In
-         * methods where State is available, you should use {@link State#getItemCount()} instead.
-         * For more details, check the documentation for {@link State#getItemCount()}.
+         * Note that this number is not necessarily equal to
+         * {@link State#getItemCount() State#getItemCount()}. In methods where {@link State} is
+         * available, you should use {@link State#getItemCount() State#getItemCount()} instead.
+         * For more details, check the documentation for
+         * {@link State#getItemCount() State#getItemCount()}.
          *
          * @return The number of items in the bound adapter
          * @see State#getItemCount()
@@ -8321,8 +8452,8 @@
                 }
                 return;
             }
-            if (viewHolder.isInvalid() && !viewHolder.isRemoved() &&
-                    !mRecyclerView.mAdapter.hasStableIds()) {
+            if (viewHolder.isInvalid() && !viewHolder.isRemoved()
+                    && !mRecyclerView.mAdapter.hasStableIds()) {
                 removeViewAt(index);
                 recycler.recycleViewHolderInternal(viewHolder);
             } else {
@@ -8490,12 +8621,12 @@
             heightUsed += insets.top + insets.bottom;
 
             final int widthSpec = getChildMeasureSpec(getWidth(), getWidthMode(),
-                    getPaddingLeft() + getPaddingRight() +
-                            lp.leftMargin + lp.rightMargin + widthUsed, lp.width,
+                    getPaddingLeft() + getPaddingRight()
+                            + lp.leftMargin + lp.rightMargin + widthUsed, lp.width,
                     canScrollHorizontally());
             final int heightSpec = getChildMeasureSpec(getHeight(), getHeightMode(),
-                    getPaddingTop() + getPaddingBottom() +
-                            lp.topMargin + lp.bottomMargin + heightUsed, lp.height,
+                    getPaddingTop() + getPaddingBottom()
+                            + lp.topMargin + lp.bottomMargin + heightUsed, lp.height,
                     canScrollVertically());
             if (shouldMeasureChild(child, widthSpec, heightSpec, lp)) {
                 child.measure(widthSpec, heightSpec);
@@ -8727,7 +8858,7 @@
             }
 
             if (mRecyclerView != null) {
-                final Matrix childMatrix = ViewCompat.getMatrix(child);
+                final Matrix childMatrix = child.getMatrix();
                 if (childMatrix != null && !childMatrix.isIdentity()) {
                     final RectF tempRectF = mRecyclerView.mTempRectF;
                     tempRectF.set(out);
@@ -8894,7 +9025,11 @@
          *
          * <p>This is the LayoutManager's opportunity to populate views in the given direction
          * to fulfill the request if it can. The LayoutManager should attach and return
-         * the view to be focused. The default implementation returns null.</p>
+         * the view to be focused, if a focusable view in the given direction is found.
+         * Otherwise, if all the existing (or the newly populated views) are unfocusable, it returns
+         * the next unfocusable view to become visible on the screen. This unfocusable view is
+         * typically the first view that's either partially or fully out of RV's padded bounded
+         * area in the given direction. The default implementation returns null.</p>
          *
          * @param focused   The currently focused view
          * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
@@ -8903,7 +9038,8 @@
          *                  or 0 for not applicable
          * @param recycler  The recycler to use for obtaining views for currently offscreen items
          * @param state     Transient state of RecyclerView
-         * @return The chosen view to be focused
+         * @return The chosen view to be focused if a focusable view is found, otherwise an
+         * unfocusable view to become visible onto the screen, else null.
          */
         @Nullable
         public View onFocusSearchFailed(View focused, int direction, Recycler recycler,
@@ -8932,22 +9068,20 @@
         }
 
         /**
-         * Called when a child of the RecyclerView wants a particular rectangle to be positioned
-         * onto the screen. See {@link ViewParent#requestChildRectangleOnScreen(android.view.View,
-         * android.graphics.Rect, boolean)} for more details.
-         *
-         * <p>The base implementation will attempt to perform a standard programmatic scroll
-         * to bring the given rect into view, within the padded area of the RecyclerView.</p>
-         *
+         * Returns the scroll amount that brings the given rect in child's coordinate system within
+         * the padded area of RecyclerView.
+         * @param parent The parent RecyclerView.
          * @param child The direct child making the request.
-         * @param rect  The rectangle in the child's coordinates the child
-         *              wishes to be on the screen.
+         * @param rect The rectangle in the child's coordinates the child
+         *             wishes to be on the screen.
          * @param immediate True to forbid animated or delayed scrolling,
          *                  false otherwise
-         * @return Whether the group scrolled to handle the operation
+         * @return The array containing the scroll amount in x and y directions that brings the
+         * given rect into RV's padded area.
          */
-        public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect,
-                boolean immediate) {
+        private int[] getChildRectangleOnScreenScrollAmount(RecyclerView parent, View child,
+                Rect rect, boolean immediate) {
+            int[] out = new int[2];
             final int parentLeft = getPaddingLeft();
             final int parentTop = getPaddingTop();
             final int parentRight = getWidth() - getPaddingRight();
@@ -8978,19 +9112,122 @@
             // we should scroll to make bottom visible, make sure top does not go out of bounds.
             final int dy = offScreenTop != 0 ? offScreenTop
                     : Math.min(childTop - parentTop, offScreenBottom);
+            out[0] = dx;
+            out[1] = dy;
+            return out;
+        }
+        /**
+         * Called when a child of the RecyclerView wants a particular rectangle to be positioned
+         * onto the screen. See {@link ViewParent#requestChildRectangleOnScreen(android.view.View,
+         * android.graphics.Rect, boolean)} for more details.
+         *
+         * <p>The base implementation will attempt to perform a standard programmatic scroll
+         * to bring the given rect into view, within the padded area of the RecyclerView.</p>
+         *
+         * @param child The direct child making the request.
+         * @param rect  The rectangle in the child's coordinates the child
+         *              wishes to be on the screen.
+         * @param immediate True to forbid animated or delayed scrolling,
+         *                  false otherwise
+         * @return Whether the group scrolled to handle the operation
+         */
+        public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect,
+                boolean immediate) {
+            return requestChildRectangleOnScreen(parent, child, rect, immediate, false);
+        }
 
-            if (dx != 0 || dy != 0) {
-                if (immediate) {
-                    parent.scrollBy(dx, dy);
-                } else {
-                    parent.smoothScrollBy(dx, dy);
+        /**
+         * Requests that the given child of the RecyclerView be positioned onto the screen. This
+         * method can be called for both unfocusable and focusable child views. For unfocusable
+         * child views, focusedChildVisible is typically true in which case, layout manager
+         * makes the child view visible only if the currently focused child stays in-bounds of RV.
+         * @param parent The parent RecyclerView.
+         * @param child The direct child making the request.
+         * @param rect The rectangle in the child's coordinates the child
+         *              wishes to be on the screen.
+         * @param immediate True to forbid animated or delayed scrolling,
+         *                  false otherwise
+         * @param focusedChildVisible Whether the currently focused view must stay visible.
+         * @return Whether the group scrolled to handle the operation
+         */
+        public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect,
+                boolean immediate,
+                boolean focusedChildVisible) {
+            int[] scrollAmount = getChildRectangleOnScreenScrollAmount(parent, child, rect,
+                    immediate);
+            int dx = scrollAmount[0];
+            int dy = scrollAmount[1];
+            if (!focusedChildVisible || isFocusedChildVisibleAfterScrolling(parent, dx, dy)) {
+                if (dx != 0 || dy != 0) {
+                    if (immediate) {
+                        parent.scrollBy(dx, dy);
+                    } else {
+                        parent.smoothScrollBy(dx, dy);
+                    }
+                    return true;
                 }
-                return true;
             }
             return false;
         }
 
         /**
+         * Returns whether the given child view is partially or fully visible within the padded
+         * bounded area of RecyclerView, depending on the input parameters.
+         * A view is partially visible if it has non-zero overlap with RV's padded bounded area.
+         * If acceptEndPointInclusion flag is set to true, it's also considered partially
+         * visible if it's located outside RV's bounds and it's hitting either RV's start or end
+         * bounds.
+         *
+         * @param child The child view to be examined.
+         * @param completelyVisible If true, the method returns true iff the child is completely
+         *                          visible. If false, the method returns true iff the child is only
+         *                          partially visible (that is it will return false if the child is
+         *                          either completely visible or out of RV's bounds).
+         * @param acceptEndPointInclusion If the view's endpoint intersection with RV's start of end
+         *                                bounds is enough to consider it partially visible,
+         *                                false otherwise.
+         * @return True if the given child is partially or fully visible, false otherwise.
+         */
+        public boolean isViewPartiallyVisible(@NonNull View child, boolean completelyVisible,
+                boolean acceptEndPointInclusion) {
+            int boundsFlag = (ViewBoundsCheck.FLAG_CVS_GT_PVS | ViewBoundsCheck.FLAG_CVS_EQ_PVS
+                    | ViewBoundsCheck.FLAG_CVE_LT_PVE | ViewBoundsCheck.FLAG_CVE_EQ_PVE);
+            boolean isViewFullyVisible = mHorizontalBoundCheck.isViewWithinBoundFlags(child,
+                    boundsFlag)
+                    && mVerticalBoundCheck.isViewWithinBoundFlags(child, boundsFlag);
+            if (completelyVisible) {
+                return isViewFullyVisible;
+            } else {
+                return !isViewFullyVisible;
+            }
+        }
+
+        /**
+         * Returns whether the currently focused child stays within RV's bounds with the given
+         * amount of scrolling.
+         * @param parent The parent RecyclerView.
+         * @param dx The scrolling in x-axis direction to be performed.
+         * @param dy The scrolling in y-axis direction to be performed.
+         * @return Whether after the given scrolling, the currently focused item in still visible
+         * (within RV's bounds).
+         */
+        private boolean isFocusedChildVisibleAfterScrolling(RecyclerView parent, int dx, int dy) {
+            final View focusedChild = parent.getFocusedChild();
+            final int parentLeft = getPaddingLeft();
+            final int parentTop = getPaddingTop();
+            final int parentRight = getWidth() - getPaddingRight();
+            final int parentBottom = getHeight() - getPaddingBottom();
+            final Rect bounds = mRecyclerView.mTempRect;
+            getDecoratedBoundsWithMargins(focusedChild, bounds);
+
+            if (bounds.left - dx >= parentRight || bounds.right - dx <= parentLeft
+                    || bounds.top - dy >= parentBottom || bounds.bottom - dy <= parentTop) {
+                return false;
+            }
+            return true;
+        }
+
+        /**
          * @deprecated Use {@link #onRequestChildFocus(RecyclerView, State, View, View)}
          */
         @Deprecated
@@ -9363,22 +9600,22 @@
          */
         public void onInitializeAccessibilityNodeInfo(Recycler recycler, State state,
                 AccessibilityNodeInfoCompat info) {
-            if (ViewCompat.canScrollVertically(mRecyclerView, -1) ||
-                    ViewCompat.canScrollHorizontally(mRecyclerView, -1)) {
+            if (ViewCompat.canScrollVertically(mRecyclerView, -1)
+                    || ViewCompat.canScrollHorizontally(mRecyclerView, -1)) {
                 info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
                 info.setScrollable(true);
             }
-            if (ViewCompat.canScrollVertically(mRecyclerView, 1) ||
-                    ViewCompat.canScrollHorizontally(mRecyclerView, 1)) {
+            if (ViewCompat.canScrollVertically(mRecyclerView, 1)
+                    || ViewCompat.canScrollHorizontally(mRecyclerView, 1)) {
                 info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
                 info.setScrollable(true);
             }
-            final AccessibilityNodeInfoCompat.CollectionInfoCompat collectionInfo
-                    = AccessibilityNodeInfoCompat.CollectionInfoCompat
-                    .obtain(getRowCountForAccessibility(recycler, state),
-                            getColumnCountForAccessibility(recycler, state),
-                            isLayoutHierarchical(recycler, state),
-                            getSelectionModeForAccessibility(recycler, state));
+            final AccessibilityNodeInfoCompat.CollectionInfoCompat collectionInfo =
+                    AccessibilityNodeInfoCompat.CollectionInfoCompat
+                            .obtain(getRowCountForAccessibility(recycler, state),
+                                    getColumnCountForAccessibility(recycler, state),
+                                    isLayoutHierarchical(recycler, state),
+                                    getSelectionModeForAccessibility(recycler, state));
             info.setCollectionInfo(collectionInfo);
         }
 
@@ -9443,9 +9680,9 @@
                 View host, AccessibilityNodeInfoCompat info) {
             int rowIndexGuess = canScrollVertically() ? getPosition(host) : 0;
             int columnIndexGuess = canScrollHorizontally() ? getPosition(host) : 0;
-            final AccessibilityNodeInfoCompat.CollectionItemInfoCompat itemInfo
-                    = AccessibilityNodeInfoCompat.CollectionItemInfoCompat.obtain(rowIndexGuess, 1,
-                    columnIndexGuess, 1, false, false);
+            final AccessibilityNodeInfoCompat.CollectionItemInfoCompat itemInfo =
+                    AccessibilityNodeInfoCompat.CollectionItemInfoCompat.obtain(rowIndexGuess, 1,
+                            columnIndexGuess, 1, false, false);
             info.setCollectionItemInfo(itemInfo);
         }
 
@@ -9622,7 +9859,8 @@
             Properties properties = new Properties();
             TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerView,
                     defStyleAttr, defStyleRes);
-            properties.orientation = a.getInt(R.styleable.RecyclerView_android_orientation, VERTICAL);
+            properties.orientation = a.getInt(R.styleable.RecyclerView_android_orientation,
+                    VERTICAL);
             properties.spanCount = a.getInt(R.styleable.RecyclerView_spanCount, 1);
             properties.reverseLayout = a.getBoolean(R.styleable.RecyclerView_reverseLayout, false);
             properties.stackFromEnd = a.getBoolean(R.styleable.RecyclerView_stackFromEnd, false);
@@ -9688,7 +9926,7 @@
      * and after the items (in {@link ItemDecoration#onDrawOver(Canvas, RecyclerView,
      * RecyclerView.State)}.</p>
      */
-    public static abstract class ItemDecoration {
+    public abstract static class ItemDecoration {
         /**
          * Draw any appropriate decorations into the Canvas supplied to the RecyclerView.
          * Any content drawn by this method will be drawn before the item views are drawn,
@@ -9779,7 +10017,7 @@
      *
      * @see SimpleOnItemTouchListener
      */
-    public static interface OnItemTouchListener {
+    public interface OnItemTouchListener {
         /**
          * Silently observe and/or take over touch events sent to the RecyclerView
          * before they are handled by either the RecyclerView itself or its child views.
@@ -9794,7 +10032,7 @@
          *         to continue with the current behavior and continue observing future events in
          *         the gesture.
          */
-        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e);
+        boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e);
 
         /**
          * Process a touch event as part of a gesture that was claimed by returning true from
@@ -9803,7 +10041,7 @@
          * @param e MotionEvent describing the touch event. All coordinates are in
          *          the RecyclerView's coordinate system.
          */
-        public void onTouchEvent(RecyclerView rv, MotionEvent e);
+        void onTouchEvent(RecyclerView rv, MotionEvent e);
 
         /**
          * Called when a child of RecyclerView does not want RecyclerView and its ancestors to
@@ -9814,12 +10052,12 @@
          *            intercept touch events.
          * @see ViewParent#requestDisallowInterceptTouchEvent(boolean)
          */
-        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
+        void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
     }
 
     /**
-     * An implementation of {@link RecyclerView.OnItemTouchListener} that has empty method bodies and
-     * default return values.
+     * An implementation of {@link RecyclerView.OnItemTouchListener} that has empty method bodies
+     * and default return values.
      * <p>
      * You may prefer to extend this class if you don't need to override all methods. Another
      * benefit of using this class is future compatibility. As the interface may change, we'll
@@ -9892,7 +10130,7 @@
          *
          * @param holder The ViewHolder containing the view that was recycled
          */
-        public void onViewRecycled(ViewHolder holder);
+        void onViewRecycled(ViewHolder holder);
     }
 
     /**
@@ -9906,14 +10144,14 @@
          *
          * @param view The View which is attached to the RecyclerView
          */
-        public void onChildViewAttachedToWindow(View view);
+        void onChildViewAttachedToWindow(View view);
 
         /**
          * Called when a view is detached from RecyclerView.
          *
          * @param view The View which is being detached from the RecyclerView
          */
-        public void onChildViewDetachedFromWindow(View view);
+        void onChildViewDetachedFromWindow(View view);
     }
 
     /**
@@ -9929,7 +10167,7 @@
      * to <code>ViewHolder</code> objects and that <code>RecyclerView</code> instances may hold
      * strong references to extra off-screen item views for caching purposes</p>
      */
-    public static abstract class ViewHolder {
+    public abstract static class ViewHolder {
         public final View itemView;
         WeakReference<RecyclerView> mNestedRecyclerView;
         int mPosition = NO_POSITION;
@@ -10348,9 +10586,9 @@
 
         @Override
         public String toString() {
-            final StringBuilder sb = new StringBuilder("ViewHolder{" +
-                    Integer.toHexString(hashCode()) + " position=" + mPosition + " id=" + mItemId +
-                    ", oldPos=" + mOldPosition + ", pLpos:" + mPreLayoutPosition);
+            final StringBuilder sb = new StringBuilder("ViewHolder{"
+                    + Integer.toHexString(hashCode()) + " position=" + mPosition + " id=" + mItemId
+                    + ", oldPos=" + mOldPosition + ", pLpos:" + mPreLayoutPosition);
             if (isScrap()) {
                 sb.append(" scrap ")
                         .append(mInChangeScrap ? "[changeScrap]" : "[attachedScrap]");
@@ -10387,11 +10625,11 @@
             if (mIsRecyclableCount < 0) {
                 mIsRecyclableCount = 0;
                 if (DEBUG) {
-                    throw new RuntimeException("isRecyclable decremented below 0: " +
-                            "unmatched pair of setIsRecyable() calls for " + this);
+                    throw new RuntimeException("isRecyclable decremented below 0: "
+                            + "unmatched pair of setIsRecyable() calls for " + this);
                 }
-                Log.e(VIEW_LOG_TAG, "isRecyclable decremented below 0: " +
-                        "unmatched pair of setIsRecyable() calls for " + this);
+                Log.e(VIEW_LOG_TAG, "isRecyclable decremented below 0: "
+                        + "unmatched pair of setIsRecyable() calls for " + this);
             } else if (!recyclable && mIsRecyclableCount == 1) {
                 mFlags |= FLAG_NOT_RECYCLABLE;
             } else if (recyclable && mIsRecyclableCount == 0) {
@@ -10408,8 +10646,8 @@
          * @see #setIsRecyclable(boolean)
          */
         public final boolean isRecyclable() {
-            return (mFlags & FLAG_NOT_RECYCLABLE) == 0 &&
-                    !ViewCompat.hasTransientState(itemView);
+            return (mFlags & FLAG_NOT_RECYCLABLE) == 0
+                    && !ViewCompat.hasTransientState(itemView);
         }
 
         /**
@@ -10449,7 +10687,7 @@
     }
 
     void dispatchPendingImportantForAccessibilityChanges() {
-        for (int i = mPendingAccessibilityImportanceChange.size() - 1; i >= 0; i --) {
+        for (int i = mPendingAccessibilityImportanceChange.size() - 1; i >= 0; i--) {
             ViewHolder viewHolder = mPendingAccessibilityImportanceChange.get(i);
             if (viewHolder.itemView.getParent() != this || viewHolder.shouldIgnore()) {
                 continue;
@@ -10466,8 +10704,8 @@
     }
 
     int getAdapterPositionFor(ViewHolder viewHolder) {
-        if (viewHolder.hasAnyOfTheFlags( ViewHolder.FLAG_INVALID |
-                ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)
+        if (viewHolder.hasAnyOfTheFlags(ViewHolder.FLAG_INVALID
+                | ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)
                 || !viewHolder.isBound()) {
             return RecyclerView.NO_POSITION;
         }
@@ -10635,7 +10873,7 @@
      * Observer base class for watching changes to an {@link Adapter}.
      * See {@link Adapter#registerAdapterDataObserver(AdapterDataObserver)}.
      */
-    public static abstract class AdapterDataObserver {
+    public abstract static class AdapterDataObserver {
         public void onChanged() {
             // Do nothing
         }
@@ -10669,7 +10907,7 @@
      *
      * @see LinearSmoothScroller
      */
-    public static abstract class SmoothScroller {
+    public abstract static class SmoothScroller {
 
         private int mTargetPosition = RecyclerView.NO_POSITION;
 
@@ -10734,7 +10972,7 @@
          * {@link #onTargetFound(android.view.View, RecyclerView.State, SmoothScroller.Action)} or
          * {@link #onSeekTargetStep(int, int, RecyclerView.State, SmoothScroller.Action)}.
          */
-        final protected void stop() {
+        protected final void stop() {
             if (!mRunning) {
                 return;
             }
@@ -10866,13 +11104,13 @@
         /**
          * Called when smooth scroll is started. This might be a good time to do setup.
          */
-        abstract protected void onStart();
+        protected abstract void onStart();
 
         /**
          * Called when smooth scroller is stopped. This is a good place to cleanup your state etc.
          * @see #stop()
          */
-        abstract protected void onStop();
+        protected abstract void onStop();
 
         /**
          * <p>RecyclerView will call this method each time it scrolls until it can find the target
@@ -10886,7 +11124,7 @@
          * @param action    If you want to trigger a new smooth scroll and cancel the previous one,
          *                  update this object.
          */
-        abstract protected void onSeekTargetStep(int dx, int dy, State state, Action action);
+        protected abstract void onSeekTargetStep(int dx, int dy, State state, Action action);
 
         /**
          * Called when the target position is laid out. This is the last callback SmoothScroller
@@ -10897,7 +11135,7 @@
          * @param action        Action instance that you should update to define final scroll action
          *                      towards the targetView
          */
-        abstract protected void onTargetFound(View targetView, State state, Action action);
+        protected abstract void onTargetFound(View targetView, State state, Action action);
 
         /**
          * Holds information about a smooth scroll request by a {@link SmoothScroller}.
@@ -10916,11 +11154,11 @@
 
             private Interpolator mInterpolator;
 
-            private boolean changed = false;
+            private boolean mChanged = false;
 
             // we track this variable to inform custom implementer if they are updating the action
             // in every animation callback
-            private int consecutiveUpdates = 0;
+            private int mConsecutiveUpdates = 0;
 
             /**
              * @param dx Pixels to scroll horizontally
@@ -10981,10 +11219,10 @@
                     final int position = mJumpToPosition;
                     mJumpToPosition = NO_POSITION;
                     recyclerView.jumpToPositionForSmoothScroller(position);
-                    changed = false;
+                    mChanged = false;
                     return;
                 }
-                if (changed) {
+                if (mChanged) {
                     validate();
                     if (mInterpolator == null) {
                         if (mDuration == UNDEFINED_DURATION) {
@@ -10993,18 +11231,19 @@
                             recyclerView.mViewFlinger.smoothScrollBy(mDx, mDy, mDuration);
                         }
                     } else {
-                        recyclerView.mViewFlinger.smoothScrollBy(mDx, mDy, mDuration, mInterpolator);
+                        recyclerView.mViewFlinger.smoothScrollBy(
+                                mDx, mDy, mDuration, mInterpolator);
                     }
-                    consecutiveUpdates ++;
-                    if (consecutiveUpdates > 10) {
+                    mConsecutiveUpdates++;
+                    if (mConsecutiveUpdates > 10) {
                         // A new action is being set in every animation step. This looks like a bad
                         // implementation. Inform developer.
                         Log.e(TAG, "Smooth Scroll action is being updated too frequently. Make sure"
                                 + " you are not changing it unless necessary");
                     }
-                    changed = false;
+                    mChanged = false;
                 } else {
-                    consecutiveUpdates = 0;
+                    mConsecutiveUpdates = 0;
                 }
             }
 
@@ -11022,7 +11261,7 @@
             }
 
             public void setDx(int dx) {
-                changed = true;
+                mChanged = true;
                 mDx = dx;
             }
 
@@ -11031,7 +11270,7 @@
             }
 
             public void setDy(int dy) {
-                changed = true;
+                mChanged = true;
                 mDy = dy;
             }
 
@@ -11040,7 +11279,7 @@
             }
 
             public void setDuration(int duration) {
-                changed = true;
+                mChanged = true;
                 mDuration = duration;
             }
 
@@ -11055,7 +11294,7 @@
              * @see #setDuration(int)
              */
             public void setInterpolator(Interpolator interpolator) {
-                changed = true;
+                mChanged = true;
                 mInterpolator = interpolator;
             }
 
@@ -11072,7 +11311,7 @@
                 mDy = dy;
                 mDuration = duration;
                 mInterpolator = interpolator;
-                changed = true;
+                mChanged = true;
             }
         }
 
@@ -11466,25 +11705,25 @@
          * @see LayoutManager#getItemCount()
          */
         public int getItemCount() {
-            return mInPreLayout ?
-                    (mPreviousLayoutItemCount - mDeletedInvisibleItemCountSincePreviousLayout) :
-                    mItemCount;
+            return mInPreLayout
+                    ? (mPreviousLayoutItemCount - mDeletedInvisibleItemCountSincePreviousLayout)
+                    : mItemCount;
         }
 
         @Override
         public String toString() {
-            return "State{" +
-                    "mTargetPosition=" + mTargetPosition +
-                    ", mData=" + mData +
-                    ", mItemCount=" + mItemCount +
-                    ", mPreviousLayoutItemCount=" + mPreviousLayoutItemCount +
-                    ", mDeletedInvisibleItemCountSincePreviousLayout="
-                    + mDeletedInvisibleItemCountSincePreviousLayout +
-                    ", mStructureChanged=" + mStructureChanged +
-                    ", mInPreLayout=" + mInPreLayout +
-                    ", mRunSimpleAnimations=" + mRunSimpleAnimations +
-                    ", mRunPredictiveAnimations=" + mRunPredictiveAnimations +
-                    '}';
+            return "State{"
+                    + "mTargetPosition=" + mTargetPosition
+                    + ", mData=" + mData
+                    + ", mItemCount=" + mItemCount
+                    + ", mPreviousLayoutItemCount=" + mPreviousLayoutItemCount
+                    + ", mDeletedInvisibleItemCountSincePreviousLayout="
+                    + mDeletedInvisibleItemCountSincePreviousLayout
+                    + ", mStructureChanged=" + mStructureChanged
+                    + ", mInPreLayout=" + mInPreLayout
+                    + ", mRunSimpleAnimations=" + mRunSimpleAnimations
+                    + ", mRunPredictiveAnimations=" + mRunPredictiveAnimations
+                    + '}';
         }
     }
 
@@ -11495,7 +11734,7 @@
      *
      * @see #setOnFlingListener(OnFlingListener)
      */
-    public static abstract class OnFlingListener {
+    public abstract static class OnFlingListener {
 
         /**
          * Override this to handle a fling given the velocities in both x and y directions.
@@ -11560,7 +11799,7 @@
      * @see #setItemAnimator(ItemAnimator)
      */
     @SuppressWarnings("UnusedParameters")
-    public static abstract class ItemAnimator {
+    public abstract static class ItemAnimator {
 
         /**
          * The Item represented by this ViewHolder is updated.
@@ -11603,14 +11842,14 @@
          * <p>
          * @see #recordPreLayoutInformation(State, ViewHolder, int, List)
          */
-        public static final int FLAG_APPEARED_IN_PRE_LAYOUT
-                = ViewHolder.FLAG_APPEARED_IN_PRE_LAYOUT;
+        public static final int FLAG_APPEARED_IN_PRE_LAYOUT =
+                ViewHolder.FLAG_APPEARED_IN_PRE_LAYOUT;
 
         /**
          * The set of flags that might be passed to
          * {@link #recordPreLayoutInformation(State, ViewHolder, int, List)}.
          */
-        @IntDef(flag=true, value={
+        @IntDef(flag = true, value = {
                 FLAG_CHANGED, FLAG_REMOVED, FLAG_MOVED, FLAG_INVALIDATED,
                 FLAG_APPEARED_IN_PRE_LAYOUT
         })
@@ -11952,7 +12191,7 @@
             if ((flags & FLAG_INVALIDATED) == 0) {
                 final int oldPos = viewHolder.getOldPosition();
                 final int pos = viewHolder.getAdapterPosition();
-                if (oldPos != NO_POSITION && pos != NO_POSITION && oldPos != pos){
+                if (oldPos != NO_POSITION && pos != NO_POSITION && oldPos != pos) {
                     flags |= FLAG_MOVED;
                 }
             }
@@ -11973,7 +12212,7 @@
          * called later to start the associated animations. runPendingAnimations() will be scheduled
          * to be run on the next frame.
          */
-        abstract public void runPendingAnimations();
+        public abstract void runPendingAnimations();
 
         /**
          * Method called when an animation on a view should be ended immediately.
@@ -11986,7 +12225,7 @@
          *
          * @param item The item for which an animation should be stopped.
          */
-        abstract public void endAnimation(ViewHolder item);
+        public abstract void endAnimation(ViewHolder item);
 
         /**
          * Method called when all item animations should be ended immediately.
@@ -11997,7 +12236,7 @@
          * Also, {@link #dispatchAnimationFinished(ViewHolder)} should be called for each finished
          * animation since the animations are effectively done when this method is called.
          */
-        abstract public void endAnimations();
+        public abstract void endAnimations();
 
         /**
          * Method which returns whether there are any item animations currently running.
@@ -12006,7 +12245,7 @@
          *
          * @return true if there are any item animations currently running, false otherwise.
          */
-        abstract public boolean isRunning();
+        public abstract boolean isRunning();
 
         /**
          * Method to be called by subclasses when an animation is finished.
@@ -12209,6 +12448,9 @@
          * @see #isRunning(ItemAnimatorFinishedListener)
          */
         public interface ItemAnimatorFinishedListener {
+            /**
+             * Notifies when all pending or running animations in an ItemAnimator are finished.
+             */
             void onAnimationsFinished();
         }
 
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java
index c44c802..ba7260d 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java
@@ -29,10 +29,12 @@
  */
 public class RecyclerViewAccessibilityDelegate extends AccessibilityDelegateCompat {
     final RecyclerView mRecyclerView;
+    final AccessibilityDelegateCompat mItemDelegate;
 
 
     public RecyclerViewAccessibilityDelegate(RecyclerView recyclerView) {
         mRecyclerView = recyclerView;
+        mItemDelegate = new ItemDelegate(this);
     }
 
     boolean shouldIgnore() {
@@ -81,13 +83,33 @@
         return mItemDelegate;
     }
 
-    final AccessibilityDelegateCompat mItemDelegate = new AccessibilityDelegateCompat() {
+    /**
+     * The default implementation of accessibility delegate for the individual items of the
+     * RecyclerView.
+     * <p>
+     * If you are overriding {@code RecyclerViewAccessibilityDelegate#getItemDelegate()} but still
+     * want to keep some default behavior, you can create an instance of this class and delegate to
+     * the parent as necessary.
+     */
+    public static class ItemDelegate extends AccessibilityDelegateCompat {
+        final RecyclerViewAccessibilityDelegate mRecyclerViewDelegate;
+
+        /**
+         * Creates an item delegate for the given {@code RecyclerViewAccessibilityDelegate}.
+         *
+         * @param recyclerViewDelegate The parent RecyclerView's accessibility delegate.
+         */
+        public ItemDelegate(RecyclerViewAccessibilityDelegate recyclerViewDelegate) {
+            mRecyclerViewDelegate = recyclerViewDelegate;
+        }
+
         @Override
         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
             super.onInitializeAccessibilityNodeInfo(host, info);
-            if (!shouldIgnore() && mRecyclerView.getLayoutManager() != null) {
-                mRecyclerView.getLayoutManager().
-                        onInitializeAccessibilityNodeInfoForItem(host, info);
+            if (!mRecyclerViewDelegate.shouldIgnore()
+                    && mRecyclerViewDelegate.mRecyclerView.getLayoutManager() != null) {
+                mRecyclerViewDelegate.mRecyclerView.getLayoutManager()
+                        .onInitializeAccessibilityNodeInfoForItem(host, info);
             }
         }
 
@@ -96,11 +118,13 @@
             if (super.performAccessibilityAction(host, action, args)) {
                 return true;
             }
-            if (!shouldIgnore() && mRecyclerView.getLayoutManager() != null) {
-                return mRecyclerView.getLayoutManager().
-                        performAccessibilityActionForItem(host, action, args);
+            if (!mRecyclerViewDelegate.shouldIgnore()
+                    && mRecyclerViewDelegate.mRecyclerView.getLayoutManager() != null) {
+                return mRecyclerViewDelegate.mRecyclerView.getLayoutManager()
+                        .performAccessibilityActionForItem(host, action, args);
             }
             return false;
         }
-    };
+    }
 }
+
diff --git a/v7/recyclerview/src/android/support/v7/widget/ScrollbarHelper.java b/v7/recyclerview/src/android/support/v7/widget/ScrollbarHelper.java
index 724fac8..ae42baa 100644
--- a/v7/recyclerview/src/android/support/v7/widget/ScrollbarHelper.java
+++ b/v7/recyclerview/src/android/support/v7/widget/ScrollbarHelper.java
@@ -29,8 +29,8 @@
     static int computeScrollOffset(RecyclerView.State state, OrientationHelper orientation,
             View startChild, View endChild, RecyclerView.LayoutManager lm,
             boolean smoothScrollbarEnabled, boolean reverseLayout) {
-        if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null ||
-                endChild == null) {
+        if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null
+                || endChild == null) {
             return 0;
         }
         final int minPosition = Math.min(lm.getPosition(startChild),
@@ -43,10 +43,10 @@
         if (!smoothScrollbarEnabled) {
             return itemsBefore;
         }
-        final int laidOutArea = Math.abs(orientation.getDecoratedEnd(endChild) -
-                orientation.getDecoratedStart(startChild));
-        final int itemRange = Math.abs(lm.getPosition(startChild) -
-                lm.getPosition(endChild)) + 1;
+        final int laidOutArea = Math.abs(orientation.getDecoratedEnd(endChild)
+                - orientation.getDecoratedStart(startChild));
+        final int itemRange = Math.abs(lm.getPosition(startChild)
+                - lm.getPosition(endChild)) + 1;
         final float avgSizePerRow = (float) laidOutArea / itemRange;
 
         return Math.round(itemsBefore * avgSizePerRow + (orientation.getStartAfterPadding()
@@ -60,8 +60,8 @@
     static int computeScrollExtent(RecyclerView.State state, OrientationHelper orientation,
             View startChild, View endChild, RecyclerView.LayoutManager lm,
             boolean smoothScrollbarEnabled) {
-        if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null ||
-                endChild == null) {
+        if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null
+                || endChild == null) {
             return 0;
         }
         if (!smoothScrollbarEnabled) {
@@ -79,18 +79,18 @@
     static int computeScrollRange(RecyclerView.State state, OrientationHelper orientation,
             View startChild, View endChild, RecyclerView.LayoutManager lm,
             boolean smoothScrollbarEnabled) {
-        if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null ||
-                endChild == null) {
+        if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null
+                || endChild == null) {
             return 0;
         }
         if (!smoothScrollbarEnabled) {
             return state.getItemCount();
         }
         // smooth scrollbar enabled. try to estimate better.
-        final int laidOutArea = orientation.getDecoratedEnd(endChild) -
-                orientation.getDecoratedStart(startChild);
-        final int laidOutRange = Math.abs(lm.getPosition(startChild) -
-                lm.getPosition(endChild))
+        final int laidOutArea = orientation.getDecoratedEnd(endChild)
+                - orientation.getDecoratedStart(startChild);
+        final int laidOutRange = Math.abs(lm.getPosition(startChild)
+                - lm.getPosition(endChild))
                 + 1;
         // estimate a size for full list.
         return (int) ((float) laidOutArea / laidOutRange * state.getItemCount());
diff --git a/v7/recyclerview/src/android/support/v7/widget/SimpleItemAnimator.java b/v7/recyclerview/src/android/support/v7/widget/SimpleItemAnimator.java
index 2db7541..fe704dc 100644
--- a/v7/recyclerview/src/android/support/v7/widget/SimpleItemAnimator.java
+++ b/v7/recyclerview/src/android/support/v7/widget/SimpleItemAnimator.java
@@ -1,15 +1,29 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package android.support.v7.widget;
 
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v7.widget.RecyclerView.Adapter;
-import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo;
+import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.util.Log;
 import android.view.View;
 
-import java.util.List;
-
 /**
  * A wrapper class for ItemAnimator that records View bounds and decides whether it should run
  * move, change, add or remove animations. This class also replicates the original ItemAnimator
@@ -20,7 +34,7 @@
  * extend this class, you can override {@link #obtainHolderInfo()} method to provide your own info
  * class that extends {@link ItemHolderInfo}.
  */
-abstract public class SimpleItemAnimator extends RecyclerView.ItemAnimator {
+public abstract class SimpleItemAnimator extends RecyclerView.ItemAnimator {
 
     private static final boolean DEBUG = false;
 
@@ -120,8 +134,8 @@
             @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) {
         if (preInfo.left != postInfo.left || preInfo.top != postInfo.top) {
             if (DEBUG) {
-                Log.d(TAG, "PERSISTENT: " + viewHolder +
-                        " with view " + viewHolder.itemView);
+                Log.d(TAG, "PERSISTENT: " + viewHolder
+                        + " with view " + viewHolder.itemView);
             }
             return animateMove(viewHolder,
                     preInfo.left, preInfo.top, postInfo.left, postInfo.top);
@@ -172,7 +186,7 @@
      * @return true if a later call to {@link #runPendingAnimations()} is requested,
      * false otherwise.
      */
-    abstract public boolean animateRemove(ViewHolder holder);
+    public abstract boolean animateRemove(ViewHolder holder);
 
     /**
      * Called when an item is added to the RecyclerView. Implementors can choose
@@ -197,7 +211,7 @@
      * @return true if a later call to {@link #runPendingAnimations()} is requested,
      * false otherwise.
      */
-    abstract public boolean animateAdd(ViewHolder holder);
+    public abstract boolean animateAdd(ViewHolder holder);
 
     /**
      * Called when an item is moved in the RecyclerView. Implementors can choose
@@ -217,7 +231,7 @@
      * @return true if a later call to {@link #runPendingAnimations()} is requested,
      * false otherwise.
      */
-    abstract public boolean animateMove(ViewHolder holder, int fromX, int fromY,
+    public abstract boolean animateMove(ViewHolder holder, int fromX, int fromY,
             int toX, int toY);
 
     /**
@@ -250,7 +264,7 @@
      * @return true if a later call to {@link #runPendingAnimations()} is requested,
      * false otherwise.
      */
-    abstract public boolean animateChange(ViewHolder oldHolder,
+    public abstract boolean animateChange(ViewHolder oldHolder,
             ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop);
 
     /**
@@ -440,3 +454,4 @@
     public void onChangeFinished(ViewHolder item, boolean oldItem) {
     }
 }
+
diff --git a/v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java
index 19f31f8..6a058af 100644
--- a/v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java
@@ -373,7 +373,7 @@
                     int myEnd = mPrimaryOrientation.getDecoratedEnd(child);
                     int nextEnd = mPrimaryOrientation.getDecoratedEnd(nextChild);
                     if (myEnd < nextEnd) {
-                        return child;//i should have a better position
+                        return child; //i should have a better position
                     } else if (myEnd == nextEnd) {
                         compareSpans = true;
                     }
@@ -381,7 +381,7 @@
                     int myStart = mPrimaryOrientation.getDecoratedStart(child);
                     int nextStart = mPrimaryOrientation.getDecoratedStart(nextChild);
                     if (myStart > nextStart) {
-                        return child;//i should have a better position
+                        return child; //i should have a better position
                     } else if (myStart == nextStart) {
                         compareSpans = true;
                     }
@@ -514,8 +514,8 @@
         if (gapStrategy == mGapStrategy) {
             return;
         }
-        if (gapStrategy != GAP_HANDLING_NONE &&
-                gapStrategy != GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS) {
+        if (gapStrategy != GAP_HANDLING_NONE
+                && gapStrategy != GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS) {
             throw new IllegalArgumentException("invalid gap strategy. Must be GAP_HANDLING_NONE "
                     + "or GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS");
         }
@@ -618,8 +618,8 @@
             }
         }
 
-        boolean recalculateAnchor = !anchorInfo.mValid || mPendingScrollPosition != NO_POSITION ||
-                mPendingSavedState != null;
+        boolean recalculateAnchor = !anchorInfo.mValid || mPendingScrollPosition != NO_POSITION
+                || mPendingSavedState != null;
         if (recalculateAnchor) {
             anchorInfo.reset();
             if (mPendingSavedState != null) {
@@ -632,15 +632,15 @@
             anchorInfo.mValid = true;
         }
         if (mPendingSavedState == null && mPendingScrollPosition == NO_POSITION) {
-            if (anchorInfo.mLayoutFromEnd != mLastLayoutFromEnd ||
-                    isLayoutRTL() != mLastLayoutRTL) {
+            if (anchorInfo.mLayoutFromEnd != mLastLayoutFromEnd
+                    || isLayoutRTL() != mLastLayoutRTL) {
                 mLazySpanLookup.clear();
                 anchorInfo.mInvalidateOffsets = true;
             }
         }
 
-        if (getChildCount() > 0 && (mPendingSavedState == null ||
-                mPendingSavedState.mSpanOffsetsSize < 1)) {
+        if (getChildCount() > 0 && (mPendingSavedState == null
+                || mPendingSavedState.mSpanOffsetsSize < 1)) {
             if (anchorInfo.mInvalidateOffsets) {
                 for (int i = 0; i < mSpanCount; i++) {
                     // Scroll to position is set, clear.
@@ -737,7 +737,7 @@
         }
         float maxSize = 0;
         final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i ++) {
+        for (int i = 0; i < childCount; i++) {
             View child = getChildAt(i);
             float size = mSecondaryOrientation.getDecoratedMeasurement(child);
             if (size < maxSize) {
@@ -758,7 +758,7 @@
         if (mSizePerSpan == before) {
             return; // nothing has changed
         }
-        for (int i = 0; i < childCount; i ++) {
+        for (int i = 0; i < childCount; i++) {
             View child = getChildAt(i);
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
             if (lp.mFullSpan) {
@@ -868,12 +868,12 @@
                         : getFirstChildPosition();
                 if (mPendingScrollPositionOffset != INVALID_OFFSET) {
                     if (anchorInfo.mLayoutFromEnd) {
-                        final int target = mPrimaryOrientation.getEndAfterPadding() -
-                                mPendingScrollPositionOffset;
+                        final int target = mPrimaryOrientation.getEndAfterPadding()
+                                - mPendingScrollPositionOffset;
                         anchorInfo.mOffset = target - mPrimaryOrientation.getDecoratedEnd(child);
                     } else {
-                        final int target = mPrimaryOrientation.getStartAfterPadding() +
-                                mPendingScrollPositionOffset;
+                        final int target = mPrimaryOrientation.getStartAfterPadding()
+                                + mPendingScrollPositionOffset;
                         anchorInfo.mOffset = target - mPrimaryOrientation.getDecoratedStart(child);
                     }
                     return true;
@@ -895,8 +895,8 @@
                     anchorInfo.mOffset = -startGap;
                     return true;
                 }
-                final int endGap = mPrimaryOrientation.getEndAfterPadding() -
-                        mPrimaryOrientation.getDecoratedEnd(child);
+                final int endGap = mPrimaryOrientation.getEndAfterPadding()
+                        - mPrimaryOrientation.getDecoratedEnd(child);
                 if (endGap < 0) {
                     anchorInfo.mOffset = endGap;
                     return true;
@@ -1329,7 +1329,7 @@
             final View child = getChildAt(i);
             final int childStart = mPrimaryOrientation.getDecoratedStart(child);
             final int childEnd = mPrimaryOrientation.getDecoratedEnd(child);
-            if(childEnd <= boundsStart || childStart >= boundsEnd) {
+            if (childEnd <= boundsStart || childStart >= boundsEnd) {
                 continue; // not visible at all
             }
             if (childStart >= boundsStart || !fullyVisible) {
@@ -1358,7 +1358,7 @@
             final View child = getChildAt(i);
             final int childStart = mPrimaryOrientation.getDecoratedStart(child);
             final int childEnd = mPrimaryOrientation.getDecoratedEnd(child);
-            if(childEnd <= boundsStart || childStart >= boundsEnd) {
+            if (childEnd <= boundsStart || childStart >= boundsEnd) {
                 continue; // not visible at all
             }
             if (childEnd <= boundsEnd || !fullyVisible) {
@@ -1438,14 +1438,14 @@
         }
         mLayoutState.mStopInFocusable = false;
         mLayoutState.mRecycle = true;
-        mLayoutState.mInfinite = mPrimaryOrientation.getMode() == View.MeasureSpec.UNSPECIFIED &&
-                mPrimaryOrientation.getEnd() == 0;
+        mLayoutState.mInfinite = mPrimaryOrientation.getMode() == View.MeasureSpec.UNSPECIFIED
+                && mPrimaryOrientation.getEnd() == 0;
     }
 
     private void setLayoutStateDirection(int direction) {
         mLayoutState.mLayoutDirection = direction;
-        mLayoutState.mItemDirection = (mShouldReverseLayout == (direction == LAYOUT_START)) ?
-                ITEM_DIRECTION_TAIL : ITEM_DIRECTION_HEAD;
+        mLayoutState.mItemDirection = (mShouldReverseLayout == (direction == LAYOUT_START))
+                ? ITEM_DIRECTION_TAIL : ITEM_DIRECTION_HEAD;
     }
 
     @Override
@@ -1496,8 +1496,8 @@
      */
     private void handleUpdate(int positionStart, int itemCountOrToPosition, int cmd) {
         int minPosition = mShouldReverseLayout ? getLastChildPosition() : getFirstChildPosition();
-        final int affectedRangeEnd;// exclusive
-        final int affectedRangeStart;// inclusive
+        final int affectedRangeEnd; // exclusive
+        final int affectedRangeStart; // inclusive
 
         if (cmd == AdapterHelper.UpdateOp.MOVE) {
             if (positionStart < itemCountOrToPosition) {
@@ -1560,8 +1560,8 @@
 
         updateAllRemainingSpans(layoutState.mLayoutDirection, targetLine);
         if (DEBUG) {
-            Log.d(TAG, "FILLING targetLine: " + targetLine + "," +
-                    "remaining spans:" + mRemainingSpans + ", state: " + layoutState);
+            Log.d(TAG, "FILLING targetLine: " + targetLine + ","
+                    + "remaining spans:" + mRemainingSpans + ", state: " + layoutState);
         }
 
         // the default coordinate to add new view.
@@ -1655,8 +1655,8 @@
                 otherStart = otherEnd - mSecondaryOrientation.getDecoratedMeasurement(view);
             } else {
                 otherStart = lp.mFullSpan ? mSecondaryOrientation.getStartAfterPadding()
-                        : currentSpan.mIndex * mSizePerSpan +
-                                mSecondaryOrientation.getStartAfterPadding();
+                        : currentSpan.mIndex * mSizePerSpan
+                                + mSecondaryOrientation.getStartAfterPadding();
                 otherEnd = otherStart + mSecondaryOrientation.getDecoratedMeasurement(view);
             }
 
@@ -1873,8 +1873,8 @@
     private void recycleFromStart(RecyclerView.Recycler recycler, int line) {
         while (getChildCount() > 0) {
             View child = getChildAt(0);
-            if (mPrimaryOrientation.getDecoratedEnd(child) <= line &&
-                    mPrimaryOrientation.getTransformedEndWithDecoration(child) <= line) {
+            if (mPrimaryOrientation.getDecoratedEnd(child) <= line
+                    && mPrimaryOrientation.getTransformedEndWithDecoration(child) <= line) {
                 LayoutParams lp = (LayoutParams) child.getLayoutParams();
                 // Don't recycle the last View in a span not to lose span's start/end lines
                 if (lp.mFullSpan) {
@@ -1894,7 +1894,7 @@
                 }
                 removeAndRecycleView(child, recycler);
             } else {
-                return;// done
+                return; // done
             }
         }
     }
@@ -1904,8 +1904,8 @@
         int i;
         for (i = childCount - 1; i >= 0; i--) {
             View child = getChildAt(i);
-            if (mPrimaryOrientation.getDecoratedStart(child) >= line &&
-                    mPrimaryOrientation.getTransformedStartWithDecoration(child) >= line) {
+            if (mPrimaryOrientation.getDecoratedStart(child) >= line
+                    && mPrimaryOrientation.getTransformedStartWithDecoration(child) >= line) {
                 LayoutParams lp = (LayoutParams) child.getLayoutParams();
                 // Don't recycle the last View in a span not to lose span's start/end lines
                 if (lp.mFullSpan) {
@@ -1925,7 +1925,7 @@
                 }
                 removeAndRecycleView(child, recycler);
             } else {
-                return;// done
+                return; // done
             }
         }
     }
@@ -2114,7 +2114,8 @@
 
         // then assign them in order to the next N views (where N = span count)
         for (int i = 0; i < itemPrefetchCount && mLayoutState.hasMore(state); i++) {
-            layoutPrefetchRegistry.addPosition(mLayoutState.mCurrentPosition, mPrefetchDistances[i]);
+            layoutPrefetchRegistry.addPosition(mLayoutState.mCurrentPosition,
+                    mPrefetchDistances[i]);
             mLayoutState.mCurrentPosition += mLayoutState.mItemDirection;
         }
     }
@@ -2284,23 +2285,62 @@
                 return view;
             }
         }
+
         // either could not find from the desired span or prev view is full span.
         // traverse all spans
         if (preferLastSpan(layoutDir)) {
-            for (int i = mSpanCount - 1; i >= 0; i --) {
+            for (int i = mSpanCount - 1; i >= 0; i--) {
                 View view = mSpans[i].getFocusableViewAfter(referenceChildPosition, layoutDir);
                 if (view != null && view != directChild) {
                     return view;
                 }
             }
         } else {
-            for (int i = 0; i < mSpanCount; i ++) {
+            for (int i = 0; i < mSpanCount; i++) {
                 View view = mSpans[i].getFocusableViewAfter(referenceChildPosition, layoutDir);
                 if (view != null && view != directChild) {
                     return view;
                 }
             }
         }
+
+        // Could not find any focusable views from any of the existing spans. Now start the search
+        // to find the best unfocusable candidate to become visible on the screen next. The search
+        // is done in the same fashion: first, check the views in the desired span and if no
+        // candidate is found, traverse the views in all the remaining spans.
+        boolean shouldSearchFromStart = !mReverseLayout == (layoutDir == LayoutState.LAYOUT_START);
+        View unfocusableCandidate = null;
+        if (!prevFocusFullSpan) {
+            unfocusableCandidate = findViewByPosition(shouldSearchFromStart
+                    ? prevFocusSpan.findFirstPartiallyVisibleItemPosition() :
+                    prevFocusSpan.findLastPartiallyVisibleItemPosition());
+            if (unfocusableCandidate != null && unfocusableCandidate != directChild) {
+                return unfocusableCandidate;
+            }
+        }
+
+        if (preferLastSpan(layoutDir)) {
+            for (int i = mSpanCount - 1; i >= 0; i--) {
+                if (i == prevFocusSpan.mIndex) {
+                    continue;
+                }
+                unfocusableCandidate = findViewByPosition(shouldSearchFromStart
+                        ? mSpans[i].findFirstPartiallyVisibleItemPosition() :
+                        mSpans[i].findLastPartiallyVisibleItemPosition());
+                if (unfocusableCandidate != null && unfocusableCandidate != directChild) {
+                    return unfocusableCandidate;
+                }
+            }
+        } else {
+            for (int i = 0; i < mSpanCount; i++) {
+                unfocusableCandidate = findViewByPosition(shouldSearchFromStart
+                        ? mSpans[i].findFirstPartiallyVisibleItemPosition() :
+                        mSpans[i].findLastPartiallyVisibleItemPosition());
+                if (unfocusableCandidate != null && unfocusableCandidate != directChild) {
+                    return unfocusableCandidate;
+                }
+            }
+        }
         return null;
     }
 
@@ -2547,8 +2587,8 @@
             if (reference == INVALID_LINE) {
                 return;
             }
-            if ((reverseLayout && reference < mPrimaryOrientation.getEndAfterPadding()) ||
-                    (!reverseLayout && reference > mPrimaryOrientation.getStartAfterPadding())) {
+            if ((reverseLayout && reference < mPrimaryOrientation.getEndAfterPadding())
+                    || (!reverseLayout && reference > mPrimaryOrientation.getStartAfterPadding())) {
                 return;
             }
             if (offset != INVALID_OFFSET) {
@@ -2622,6 +2662,12 @@
                     : findOneVisibleChild(0, mViews.size(), false);
         }
 
+        public int findFirstPartiallyVisibleItemPosition() {
+            return mReverseLayout
+                    ? findOnePartiallyVisibleChild(mViews.size() - 1, -1, true)
+                    : findOnePartiallyVisibleChild(0, mViews.size(), true);
+        }
+
         public int findFirstCompletelyVisibleItemPosition() {
             return mReverseLayout
                     ? findOneVisibleChild(mViews.size() - 1, -1, true)
@@ -2634,13 +2680,45 @@
                     : findOneVisibleChild(mViews.size() - 1, -1, false);
         }
 
+        public int findLastPartiallyVisibleItemPosition() {
+            return mReverseLayout
+                    ? findOnePartiallyVisibleChild(0, mViews.size(), true)
+                    : findOnePartiallyVisibleChild(mViews.size() - 1, -1, true);
+        }
+
         public int findLastCompletelyVisibleItemPosition() {
             return mReverseLayout
                     ? findOneVisibleChild(0, mViews.size(), true)
                     : findOneVisibleChild(mViews.size() - 1, -1, true);
         }
 
-        int findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible) {
+        /**
+         * Returns the first view within this span that is partially or fully visible. Partially
+         * visible refers to a view that overlaps but is not fully contained within RV's padded
+         * bounded area. This view returned can be defined to have an area of overlap strictly
+         * greater than zero if acceptEndPointInclusion is false. If true, the view's endpoint
+         * inclusion is enough to consider it partially visible. The latter case can then refer to
+         * an out-of-bounds view positioned right at the top (or bottom) boundaries of RV's padded
+         * area. This is used e.g. inside
+         * {@link #onFocusSearchFailed(View, int, RecyclerView.Recycler, RecyclerView.State)} for
+         * calculating the next unfocusable child to become visible on the screen.
+         * @param fromIndex The child position index to start the search from.
+         * @param toIndex The child position index to end the search at.
+         * @param completelyVisible True if we have to only consider completely visible views,
+         *                          false otherwise.
+         * @param acceptCompletelyVisible True if we can consider both partially or fully visible
+         *                                views, false, if only a partially visible child should be
+         *                                returned.
+         * @param acceptEndPointInclusion If the view's endpoint intersection with RV's padded
+         *                                bounded area is enough to consider it partially visible,
+         *                                false otherwise
+         * @return The adapter position of the first view that's either partially or fully visible.
+         * {@link RecyclerView#NO_POSITION} if no such view is found.
+         */
+        int findOnePartiallyOrCompletelyVisibleChild(int fromIndex, int toIndex,
+                boolean completelyVisible,
+                boolean acceptCompletelyVisible,
+                boolean acceptEndPointInclusion) {
             final int start = mPrimaryOrientation.getStartAfterPadding();
             final int end = mPrimaryOrientation.getEndAfterPadding();
             final int next = toIndex > fromIndex ? 1 : -1;
@@ -2648,12 +2726,22 @@
                 final View child = mViews.get(i);
                 final int childStart = mPrimaryOrientation.getDecoratedStart(child);
                 final int childEnd = mPrimaryOrientation.getDecoratedEnd(child);
-                if (childStart < end && childEnd > start) {
-                    if (completelyVisible) {
+                boolean childStartInclusion = acceptEndPointInclusion ? (childStart <= end)
+                        : (childStart < end);
+                boolean childEndInclusion = acceptEndPointInclusion ? (childEnd >= start)
+                        : (childEnd > start);
+                if (childStartInclusion && childEndInclusion) {
+                    if (completelyVisible && acceptCompletelyVisible) {
+                        // the child has to be completely visible to be returned.
                         if (childStart >= start && childEnd <= end) {
                             return getPosition(child);
                         }
-                    } else {
+                    } else if (acceptCompletelyVisible) {
+                        // can return either a partially or completely visible child.
+                        return getPosition(child);
+                    } else if (childStart < start || childEnd > end) {
+                        // should return a partially visible child if exists and a completely
+                        // visible child is not acceptable in this case.
                         return getPosition(child);
                     }
                 }
@@ -2661,6 +2749,17 @@
             return NO_POSITION;
         }
 
+        int findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible) {
+            return findOnePartiallyOrCompletelyVisibleChild(fromIndex, toIndex, completelyVisible,
+                    true, false);
+        }
+
+        int findOnePartiallyVisibleChild(int fromIndex, int toIndex,
+                boolean acceptEndPointInclusion) {
+            return findOnePartiallyOrCompletelyVisibleChild(fromIndex, toIndex, false, false,
+                    acceptEndPointInclusion);
+        }
+
         /**
          * Depending on the layout direction, returns the View that is after the given position.
          */
@@ -2670,8 +2769,11 @@
                 final int limit = mViews.size();
                 for (int i = 0; i < limit; i++) {
                     final View view = mViews.get(i);
-                    if (view.isFocusable() &&
-                            (getPosition(view) > referenceChildPosition == mReverseLayout) ) {
+                    if ((mReverseLayout && getPosition(view) <= referenceChildPosition)
+                            || (!mReverseLayout && getPosition(view) >= referenceChildPosition)) {
+                        break;
+                    }
+                    if (view.isFocusable()) {
                         candidate = view;
                     } else {
                         break;
@@ -2680,8 +2782,11 @@
             } else {
                 for (int i = mViews.size() - 1; i >= 0; i--) {
                     final View view = mViews.get(i);
-                    if (view.isFocusable() &&
-                            (getPosition(view) > referenceChildPosition == !mReverseLayout)) {
+                    if ((mReverseLayout && getPosition(view) >= referenceChildPosition)
+                            || (!mReverseLayout && getPosition(view) <= referenceChildPosition)) {
+                        break;
+                    }
+                    if (view.isFocusable()) {
                         candidate = view;
                     } else {
                         break;
@@ -2919,8 +3024,8 @@
                     return null;
                 }
                 if (fsi.mPosition >= minPos
-                        && (gapDir == 0 || fsi.mGapDir == gapDir ||
-                        (hasUnwantedGapAfter && fsi.mHasUnwantedGapAfter))) {
+                        && (gapDir == 0 || fsi.mGapDir == gapDir
+                        || (hasUnwantedGapAfter && fsi.mHasUnwantedGapAfter))) {
                     return fsi;
                 }
             }
@@ -2940,7 +3045,7 @@
             // view is still on the screen after scroll stops, we have to recalculate layout
             boolean mHasUnwantedGapAfter;
 
-            public FullSpanItem(Parcel in) {
+            FullSpanItem(Parcel in) {
                 mPosition = in.readInt();
                 mGapDir = in.readInt();
                 mHasUnwantedGapAfter = in.readInt() == 1;
@@ -2951,7 +3056,7 @@
                 }
             }
 
-            public FullSpanItem() {
+            FullSpanItem() {
             }
 
             int getGapForSpan(int spanIndex) {
@@ -2978,26 +3083,26 @@
 
             @Override
             public String toString() {
-                return "FullSpanItem{" +
-                        "mPosition=" + mPosition +
-                        ", mGapDir=" + mGapDir +
-                        ", mHasUnwantedGapAfter=" + mHasUnwantedGapAfter +
-                        ", mGapPerSpan=" + Arrays.toString(mGapPerSpan) +
-                        '}';
+                return "FullSpanItem{"
+                        + "mPosition=" + mPosition
+                        + ", mGapDir=" + mGapDir
+                        + ", mHasUnwantedGapAfter=" + mHasUnwantedGapAfter
+                        + ", mGapPerSpan=" + Arrays.toString(mGapPerSpan)
+                        + '}';
             }
 
-            public static final Parcelable.Creator<FullSpanItem> CREATOR
-                    = new Parcelable.Creator<FullSpanItem>() {
-                @Override
-                public FullSpanItem createFromParcel(Parcel in) {
-                    return new FullSpanItem(in);
-                }
+            public static final Parcelable.Creator<FullSpanItem> CREATOR =
+                    new Parcelable.Creator<FullSpanItem>() {
+                        @Override
+                        public FullSpanItem createFromParcel(Parcel in) {
+                            return new FullSpanItem(in);
+                        }
 
-                @Override
-                public FullSpanItem[] newArray(int size) {
-                    return new FullSpanItem[size];
-                }
-            };
+                        @Override
+                        public FullSpanItem[] newArray(int size) {
+                            return new FullSpanItem[size];
+                        }
+                    };
         }
     }
 
@@ -3094,18 +3199,18 @@
             dest.writeList(mFullSpanItems);
         }
 
-        public static final Parcelable.Creator<SavedState> CREATOR
-                = new Parcelable.Creator<SavedState>() {
-            @Override
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+                    @Override
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
 
-            @Override
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
+                    @Override
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
     }
 
     /**
@@ -3122,7 +3227,7 @@
         // measure steps
         int[] mSpanReferenceLines;
 
-        public AnchorInfo() {
+        AnchorInfo() {
             reset();
         }
 
diff --git a/v7/recyclerview/src/android/support/v7/widget/ViewBoundsCheck.java b/v7/recyclerview/src/android/support/v7/widget/ViewBoundsCheck.java
new file mode 100644
index 0000000..8a4f89c
--- /dev/null
+++ b/v7/recyclerview/src/android/support/v7/widget/ViewBoundsCheck.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.widget;
+
+import android.support.annotation.IntDef;
+import android.view.View;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A utility class used to check the boundaries of a given view within its parent view based on
+ * a set of boundary flags.
+ */
+class ViewBoundsCheck {
+
+    static final int GT = 1 << 0;
+    static final int EQ = 1 << 1;
+    static final int LT = 1 << 2;
+
+
+    static final int CVS_PVS_POS = 0;
+    /**
+     * The child view's start should be strictly greater than parent view's start.
+     */
+    static final int FLAG_CVS_GT_PVS = GT << CVS_PVS_POS;
+
+    /**
+     * The child view's start can be equal to its parent view's start. This flag follows with GT
+     * or LT indicating greater (less) than or equal relation.
+     */
+    static final int FLAG_CVS_EQ_PVS = EQ << CVS_PVS_POS;
+
+    /**
+     * The child view's start should be strictly less than parent view's start.
+     */
+    static final int FLAG_CVS_LT_PVS = LT << CVS_PVS_POS;
+
+
+    static final int CVS_PVE_POS = 4;
+    /**
+     * The child view's start should be strictly greater than parent view's end.
+     */
+    static final int FLAG_CVS_GT_PVE = GT << CVS_PVE_POS;
+
+    /**
+     * The child view's start can be equal to its parent view's end. This flag follows with GT
+     * or LT indicating greater (less) than or equal relation.
+     */
+    static final int FLAG_CVS_EQ_PVE = EQ << CVS_PVE_POS;
+
+    /**
+     * The child view's start should be strictly less than parent view's end.
+     */
+    static final int FLAG_CVS_LT_PVE = LT << CVS_PVE_POS;
+
+
+    static final int CVE_PVS_POS = 8;
+    /**
+     * The child view's end should be strictly greater than parent view's start.
+     */
+    static final int FLAG_CVE_GT_PVS = GT << CVE_PVS_POS;
+
+    /**
+     * The child view's end can be equal to its parent view's start. This flag follows with GT
+     * or LT indicating greater (less) than or equal relation.
+     */
+    static final int FLAG_CVE_EQ_PVS = EQ << CVE_PVS_POS;
+
+    /**
+     * The child view's end should be strictly less than parent view's start.
+     */
+    static final int FLAG_CVE_LT_PVS = LT << CVE_PVS_POS;
+
+
+    static final int CVE_PVE_POS = 12;
+    /**
+     * The child view's end should be strictly greater than parent view's end.
+     */
+    static final int FLAG_CVE_GT_PVE = GT << CVE_PVE_POS;
+
+    /**
+     * The child view's end can be equal to its parent view's end. This flag follows with GT
+     * or LT indicating greater (less) than or equal relation.
+     */
+    static final int FLAG_CVE_EQ_PVE = EQ << CVE_PVE_POS;
+
+    /**
+     * The child view's end should be strictly less than parent view's end.
+     */
+    static final int FLAG_CVE_LT_PVE = LT << CVE_PVE_POS;
+
+    static final int MASK = GT | EQ | LT;
+
+    final Callback mCallback;
+    BoundFlags mBoundFlags;
+    /**
+     * The set of flags that can be passed for checking the view boundary conditions.
+     * CVS in the flag name indicates the child view, and PV indicates the parent view.\
+     * The following S, E indicate a view's start and end points, respectively.
+     * GT and LT indicate a strictly greater and less than relationship.
+     * Greater than or equal (or less than or equal) can be specified by setting both GT and EQ (or
+     * LT and EQ) flags.
+     * For instance, setting both {@link #FLAG_CVS_GT_PVS} and {@link #FLAG_CVS_EQ_PVS} indicate the
+     * child view's start should be greater than or equal to its parent start.
+     */
+    @IntDef(flag = true, value = {
+            FLAG_CVS_GT_PVS, FLAG_CVS_EQ_PVS, FLAG_CVS_LT_PVS,
+            FLAG_CVS_GT_PVE, FLAG_CVS_EQ_PVE, FLAG_CVS_LT_PVE,
+            FLAG_CVE_GT_PVS, FLAG_CVE_EQ_PVS, FLAG_CVE_LT_PVS,
+            FLAG_CVE_EQ_PVE, FLAG_CVE_EQ_PVE, FLAG_CVE_LT_PVE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ViewBounds {}
+
+    ViewBoundsCheck(Callback callback) {
+        mCallback = callback;
+        mBoundFlags = new BoundFlags();
+    }
+
+    static class BoundFlags {
+        int mBoundFlags = 0;
+        int mRvStart, mRvEnd, mChildStart, mChildEnd;
+
+        void setBounds(int rvStart, int rvEnd, int childStart, int childEnd) {
+            mRvStart = rvStart;
+            mRvEnd = rvEnd;
+            mChildStart = childStart;
+            mChildEnd = childEnd;
+        }
+
+        void setFlags(@ViewBounds int flags, int mask) {
+            mBoundFlags = (mBoundFlags & ~mask) | (flags & mask);
+        }
+
+        void addFlags(@ViewBounds int flags) {
+            mBoundFlags |= flags;
+        }
+
+        void resetFlags() {
+            mBoundFlags = 0;
+        }
+
+        int compare(int x, int y) {
+            if (x > y) {
+                return GT;
+            }
+            if (x == y) {
+                return EQ;
+            }
+            return LT;
+        }
+
+        boolean boundsMatch() {
+            if ((mBoundFlags & (MASK << CVS_PVS_POS)) != 0) {
+                if ((mBoundFlags & (compare(mChildStart, mRvStart) << CVS_PVS_POS)) == 0) {
+                    return false;
+                }
+            }
+
+            if ((mBoundFlags & (MASK << CVS_PVE_POS)) != 0) {
+                if ((mBoundFlags & (compare(mChildStart, mRvEnd) << CVS_PVE_POS)) == 0) {
+                    return false;
+                }
+            }
+
+            if ((mBoundFlags & (MASK << CVE_PVS_POS)) != 0) {
+                if ((mBoundFlags & (compare(mChildEnd, mRvStart) << CVE_PVS_POS)) == 0) {
+                    return false;
+                }
+            }
+
+            if ((mBoundFlags & (MASK << CVE_PVE_POS)) != 0) {
+                if ((mBoundFlags & (compare(mChildEnd, mRvEnd) << CVE_PVE_POS)) == 0) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    };
+
+    /**
+     * Returns the first view starting from fromIndex to toIndex in views whose bounds lie within
+     * its parent bounds based on the provided preferredBoundFlags. If no match is found based on
+     * the preferred flags, and a nonzero acceptableBoundFlags is specified, the last view whose
+     * bounds lie within its parent view based on the acceptableBoundFlags is returned. If no such
+     * view is found based on either of these two flags, null is returned.
+     * @param fromIndex The view position index to start the search from.
+     * @param toIndex The view position index to end the search at.
+     * @param preferredBoundFlags The flags indicating the preferred match. Once a match is found
+     *                            based on this flag, that view is returned instantly.
+     * @param acceptableBoundFlags The flags indicating the acceptable match if no preferred match
+     *                             is found. If so, and if acceptableBoundFlags is non-zero, the
+     *                             last matching acceptable view is returned. Otherwise, null is
+     *                             returned.
+     * @return The first view that satisfies acceptableBoundFlags or the last view satisfying
+     * acceptableBoundFlags boundary conditions.
+     */
+    View findOneViewWithinBoundFlags(int fromIndex, int toIndex,
+            @ViewBounds int preferredBoundFlags,
+            @ViewBounds int acceptableBoundFlags) {
+        final int start = mCallback.getParentStart();
+        final int end = mCallback.getParentEnd();
+        final int next = toIndex > fromIndex ? 1 : -1;
+        View acceptableMatch = null;
+        for (int i = fromIndex; i != toIndex; i += next) {
+            final View child = mCallback.getChildAt(i);
+            final int childStart = mCallback.getChildStart(child);
+            final int childEnd = mCallback.getChildEnd(child);
+            mBoundFlags.setBounds(start, end, childStart, childEnd);
+            if (preferredBoundFlags != 0) {
+                mBoundFlags.resetFlags();
+                mBoundFlags.addFlags(preferredBoundFlags);
+                if (mBoundFlags.boundsMatch()) {
+                    // found a perfect match
+                    return child;
+                }
+            }
+            if (acceptableBoundFlags != 0) {
+                mBoundFlags.resetFlags();
+                mBoundFlags.addFlags(acceptableBoundFlags);
+                if (mBoundFlags.boundsMatch()) {
+                    acceptableMatch = child;
+                }
+            }
+        }
+        return acceptableMatch;
+    }
+
+    /**
+     * Returns whether the specified view lies within the boundary condition of its parent view.
+     * @param child The child view to be checked.
+     * @param boundsFlags The flag against which the child view and parent view are matched.
+     * @return True if the view meets the boundsFlag, false otherwise.
+     */
+    boolean isViewWithinBoundFlags(View child, @ViewBounds int boundsFlags) {
+        mBoundFlags.setBounds(mCallback.getParentStart(), mCallback.getParentEnd(),
+                mCallback.getChildStart(child), mCallback.getChildEnd(child));
+        if (boundsFlags != 0) {
+            mBoundFlags.resetFlags();
+            mBoundFlags.addFlags(boundsFlags);
+            return mBoundFlags.boundsMatch();
+        }
+        return false;
+    }
+
+    /**
+     * Callback provided by the user of this class in order to retrieve information about child and
+     * parent boundaries.
+     */
+    interface Callback {
+        int getChildCount();
+        View getParent();
+        View getChildAt(int index);
+        int getParentStart();
+        int getParentEnd();
+        int getChildStart(View view);
+        int getChildEnd(View view);
+    }
+}
diff --git a/v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java b/v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java
index 90f3a6f..68bbde4 100644
--- a/v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java
+++ b/v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java
@@ -15,24 +15,22 @@
  */
 package android.support.v7.widget;
 
+import static android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo;
+import static android.support.v7.widget.RecyclerView.ViewHolder;
+import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR;
+import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR_AND_DISAPPEAR;
+import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR_PRE_AND_POST;
+import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_DISAPPEARED;
+import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_POST;
+import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_PRE;
+import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_PRE_AND_POST;
+
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
 import android.support.v4.util.ArrayMap;
 import android.support.v4.util.LongSparseArray;
 import android.support.v4.util.Pools;
-import android.view.View;
-
-import static android.support.v7.widget.RecyclerView.ViewHolder;
-import static android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo;
-
-import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR_PRE_AND_POST;
-import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR_AND_DISAPPEAR;
-import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_PRE_AND_POST;
-import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_DISAPPEARED;
-import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR;
-import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_PRE;
-import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_POST;
 /**
  * This class abstracts all tracking for Views to run animations.
  */
@@ -218,7 +216,7 @@
     }
 
     void process(ProcessCallback callback) {
-        for (int index = mLayoutHolderMap.size() - 1; index >= 0; index --) {
+        for (int index = mLayoutHolderMap.size() - 1; index >= 0; index--) {
             final ViewHolder viewHolder = mLayoutHolderMap.keyAt(index);
             final InfoRecord record = mLayoutHolderMap.removeAt(index);
             if ((record.flags & FLAG_APPEAR_AND_DISAPPEAR) == FLAG_APPEAR_AND_DISAPPEAR) {
diff --git a/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java b/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java
index cce7161..068dddf 100644
--- a/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java
+++ b/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java
@@ -16,18 +16,14 @@
 
 package android.support.v7.widget.helper;
 
+import android.animation.Animator;
+import android.animation.ValueAnimator;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.os.Build;
 import android.support.annotation.Nullable;
-import android.support.v4.animation.AnimatorCompatHelper;
-import android.support.v4.animation.AnimatorListenerCompat;
-import android.support.v4.animation.AnimatorUpdateListenerCompat;
-import android.support.v4.animation.ValueAnimatorCompat;
 import android.support.v4.view.GestureDetectorCompat;
-import android.support.v4.view.MotionEventCompat;
-import android.support.v4.view.VelocityTrackerCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.recyclerview.R;
 import android.support.v7.widget.LinearLayoutManager;
@@ -299,15 +295,14 @@
      */
     GestureDetectorCompat mGestureDetector;
 
-    private final OnItemTouchListener mOnItemTouchListener
-            = new OnItemTouchListener() {
+    private final OnItemTouchListener mOnItemTouchListener = new OnItemTouchListener() {
         @Override
         public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent event) {
             mGestureDetector.onTouchEvent(event);
             if (DEBUG) {
                 Log.d(TAG, "intercept: x:" + event.getX() + ",y:" + event.getY() + ", " + event);
             }
-            final int action = MotionEventCompat.getActionMasked(event);
+            final int action = event.getActionMasked();
             if (action == MotionEvent.ACTION_DOWN) {
                 mActivePointerId = event.getPointerId(0);
                 mInitialTouchX = event.getX();
@@ -359,7 +354,7 @@
             if (mActivePointerId == ACTIVE_POINTER_ID_NONE) {
                 return;
             }
-            final int action = MotionEventCompat.getActionMasked(event);
+            final int action = event.getActionMasked();
             final int activePointerIndex = event.findPointerIndex(mActivePointerId);
             if (activePointerIndex >= 0) {
                 checkSelectForSwipe(action, event, activePointerIndex);
@@ -390,7 +385,7 @@
                     mActivePointerId = ACTIVE_POINTER_ID_NONE;
                     break;
                 case MotionEvent.ACTION_POINTER_UP: {
-                    final int pointerIndex = MotionEventCompat.getActionIndex(event);
+                    final int pointerIndex = event.getActionIndex();
                     final int pointerId = event.getPointerId(pointerIndex);
                     if (pointerId == mActivePointerId) {
                         // This was our active pointer going up. Choose a new
@@ -437,10 +432,10 @@
     }
 
     private static boolean hitTest(View child, float x, float y, float left, float top) {
-        return x >= left &&
-                x <= left + child.getWidth() &&
-                y >= top &&
-                y <= top + child.getHeight();
+        return x >= left
+                && x <= left + child.getWidth()
+                && y >= top
+                && y <= top + child.getHeight();
     }
 
     /**
@@ -507,12 +502,12 @@
         if ((mSelectedFlags & (LEFT | RIGHT)) != 0) {
             outPosition[0] = mSelectedStartX + mDx - mSelected.itemView.getLeft();
         } else {
-            outPosition[0] = ViewCompat.getTranslationX(mSelected.itemView);
+            outPosition[0] = mSelected.itemView.getTranslationX();
         }
         if ((mSelectedFlags & (UP | DOWN)) != 0) {
             outPosition[1] = mSelectedStartY + mDy - mSelected.itemView.getTop();
         } else {
-            outPosition[1] = ViewCompat.getTranslationY(mSelected.itemView);
+            outPosition[1] = mSelected.itemView.getTranslationY();
         }
     }
 
@@ -609,7 +604,7 @@
                         prevActionState, currentTranslateX, currentTranslateY,
                         targetTranslateX, targetTranslateY) {
                     @Override
-                    public void onAnimationEnd(ValueAnimatorCompat animation) {
+                    public void onAnimationEnd(Animator animation) {
                         super.onAnimationEnd(animation);
                         if (this.mOverridden) {
                             return;
@@ -674,9 +669,9 @@
         mRecyclerView.post(new Runnable() {
             @Override
             public void run() {
-                if (mRecyclerView != null && mRecyclerView.isAttachedToWindow() &&
-                        !anim.mOverridden &&
-                        anim.mViewHolder.getAdapterPosition() != RecyclerView.NO_POSITION) {
+                if (mRecyclerView != null && mRecyclerView.isAttachedToWindow()
+                        && !anim.mOverridden
+                        && anim.mViewHolder.getAdapterPosition() != RecyclerView.NO_POSITION) {
                     final RecyclerView.ItemAnimator animator = mRecyclerView.getItemAnimator();
                     // if animator is running or we have other active recover animations, we try
                     // not to call onSwiped because DefaultItemAnimator is not good at merging
@@ -740,8 +735,8 @@
             if (mDy < 0 && topDiff < 0) {
                 scrollY = topDiff;
             } else if (mDy > 0) {
-                final int bottomDiff = curY + mSelected.itemView.getHeight() + mTmpRect.bottom -
-                        (mRecyclerView.getHeight() - mRecyclerView.getPaddingBottom());
+                final int bottomDiff = curY + mSelected.itemView.getHeight() + mTmpRect.bottom
+                        - (mRecyclerView.getHeight() - mRecyclerView.getPaddingBottom());
                 if (bottomDiff > 0) {
                     scrollY = bottomDiff;
                 }
@@ -788,7 +783,7 @@
         for (int i = 0; i < childCount; i++) {
             View other = lm.getChildAt(i);
             if (other == viewHolder.itemView) {
-                continue;//myself!
+                continue; //myself!
             }
             if (other.getBottom() < top || other.getTop() > bottom
                     || other.getRight() < left || other.getLeft() > right) {
@@ -1044,7 +1039,7 @@
      * <pre>
      *     viewHolder.dragButton.setOnTouchListener(new View.OnTouchListener() {
      *         public boolean onTouch(View v, MotionEvent event) {
-     *             if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
+     *             if (MotionEvent.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
      *                 mItemTouchHelper.startDrag(viewHolder);
      *             }
      *             return false;
@@ -1059,7 +1054,7 @@
      */
     public void startDrag(ViewHolder viewHolder) {
         if (!mCallback.hasDragFlag(mRecyclerView, viewHolder)) {
-            Log.e(TAG, "Start drag has been called but swiping is not enabled");
+            Log.e(TAG, "Start drag has been called but dragging is not enabled");
             return;
         }
         if (viewHolder.itemView.getParent() != mRecyclerView) {
@@ -1093,7 +1088,7 @@
      * <pre>
      *     viewHolder.dragButton.setOnTouchListener(new View.OnTouchListener() {
      *         public boolean onTouch(View v, MotionEvent event) {
-     *             if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
+     *             if (MotionEvent.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
      *                 mItemTouchHelper.startSwipe(viewHolder);
      *             }
      *             return false;
@@ -1106,7 +1101,7 @@
      */
     public void startSwipe(ViewHolder viewHolder) {
         if (!mCallback.hasSwipeFlag(mRecyclerView, viewHolder)) {
-            Log.e(TAG, "Start swipe has been called but dragging is not enabled");
+            Log.e(TAG, "Start swipe has been called but swiping is not enabled");
             return;
         }
         if (viewHolder.itemView.getParent() != mRecyclerView) {
@@ -1206,15 +1201,13 @@
             if (mVelocityTracker != null && mActivePointerId > -1) {
                 mVelocityTracker.computeCurrentVelocity(PIXELS_PER_SECOND,
                         mCallback.getSwipeVelocityThreshold(mMaxSwipeVelocity));
-                final float xVelocity = VelocityTrackerCompat
-                        .getXVelocity(mVelocityTracker, mActivePointerId);
-                final float yVelocity = VelocityTrackerCompat
-                        .getYVelocity(mVelocityTracker, mActivePointerId);
+                final float xVelocity = mVelocityTracker.getXVelocity(mActivePointerId);
+                final float yVelocity = mVelocityTracker.getYVelocity(mActivePointerId);
                 final int velDirFlag = xVelocity > 0f ? RIGHT : LEFT;
                 final float absXVelocity = Math.abs(xVelocity);
-                if ((velDirFlag & flags) != 0 && dirFlag == velDirFlag &&
-                        absXVelocity >= mCallback.getSwipeEscapeVelocity(mSwipeEscapeVelocity) &&
-                        absXVelocity > Math.abs(yVelocity)) {
+                if ((velDirFlag & flags) != 0 && dirFlag == velDirFlag
+                        && absXVelocity >= mCallback.getSwipeEscapeVelocity(mSwipeEscapeVelocity)
+                        && absXVelocity > Math.abs(yVelocity)) {
                     return velDirFlag;
                 }
             }
@@ -1235,15 +1228,13 @@
             if (mVelocityTracker != null && mActivePointerId > -1) {
                 mVelocityTracker.computeCurrentVelocity(PIXELS_PER_SECOND,
                         mCallback.getSwipeVelocityThreshold(mMaxSwipeVelocity));
-                final float xVelocity = VelocityTrackerCompat
-                        .getXVelocity(mVelocityTracker, mActivePointerId);
-                final float yVelocity = VelocityTrackerCompat
-                        .getYVelocity(mVelocityTracker, mActivePointerId);
+                final float xVelocity = mVelocityTracker.getXVelocity(mActivePointerId);
+                final float yVelocity = mVelocityTracker.getYVelocity(mActivePointerId);
                 final int velDirFlag = yVelocity > 0f ? DOWN : UP;
                 final float absYVelocity = Math.abs(yVelocity);
-                if ((velDirFlag & flags) != 0 && velDirFlag == dirFlag &&
-                        absYVelocity >= mCallback.getSwipeEscapeVelocity(mSwipeEscapeVelocity) &&
-                        absYVelocity > Math.abs(xVelocity)) {
+                if ((velDirFlag & flags) != 0 && velDirFlag == dirFlag
+                        && absYVelocity >= mCallback.getSwipeEscapeVelocity(mSwipeEscapeVelocity)
+                        && absYVelocity > Math.abs(xVelocity)) {
                     return velDirFlag;
                 }
             }
@@ -1259,7 +1250,7 @@
 
     private void addChildDrawingOrderCallback() {
         if (Build.VERSION.SDK_INT >= 21) {
-            return;// we use elevation on Lollipop
+            return; // we use elevation on Lollipop
         }
         if (mChildDrawingOrderCallback == null) {
             mChildDrawingOrderCallback = new RecyclerView.ChildDrawingOrderCallback() {
@@ -1297,7 +1288,7 @@
      * An interface which can be implemented by LayoutManager for better integration with
      * {@link ItemTouchHelper}.
      */
-    public static interface ViewDropHandler {
+    public interface ViewDropHandler {
 
         /**
          * Called by the {@link ItemTouchHelper} after a View is dropped over another View.
@@ -1318,7 +1309,7 @@
          * @param y      The <code>top</code> offset of the View that is being dragged. This value
          *               includes the movement caused by the user.
          */
-        public void prepareForDrop(View view, View target, int x, int y);
+        void prepareForDrop(View view, View target, int x, int y);
     }
 
     /**
@@ -1358,15 +1349,15 @@
 
         public static final int DEFAULT_SWIPE_ANIMATION_DURATION = 250;
 
-        static final int RELATIVE_DIR_FLAGS = START | END |
-                ((START | END) << DIRECTION_FLAG_COUNT) |
-                ((START | END) << (2 * DIRECTION_FLAG_COUNT));
+        static final int RELATIVE_DIR_FLAGS = START | END
+                | ((START | END) << DIRECTION_FLAG_COUNT)
+                | ((START | END) << (2 * DIRECTION_FLAG_COUNT));
 
         private static final ItemTouchUIUtil sUICallback;
 
-        private static final int ABS_HORIZONTAL_DIR_FLAGS = LEFT | RIGHT |
-                ((LEFT | RIGHT) << DIRECTION_FLAG_COUNT) |
-                ((LEFT | RIGHT) << (2 * DIRECTION_FLAG_COUNT));
+        private static final int ABS_HORIZONTAL_DIR_FLAGS = LEFT | RIGHT
+                | ((LEFT | RIGHT) << DIRECTION_FLAG_COUNT)
+                | ((LEFT | RIGHT) << (2 * DIRECTION_FLAG_COUNT));
 
         private static final Interpolator sDragScrollInterpolator = new Interpolator() {
             @Override
@@ -1458,7 +1449,7 @@
         public static int convertToRelativeDirection(int flags, int layoutDirection) {
             int masked = flags & ABS_HORIZONTAL_DIR_FLAGS;
             if (masked == 0) {
-                return flags;// does not have any abs flags, good.
+                return flags; // does not have any abs flags, good.
             }
             flags &= ~masked; //remove left / right.
             if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) {
@@ -1486,9 +1477,9 @@
          * @return Returns an integer composed of the given drag and swipe flags.
          */
         public static int makeMovementFlags(int dragFlags, int swipeFlags) {
-            return makeFlag(ACTION_STATE_IDLE, swipeFlags | dragFlags) |
-                    makeFlag(ACTION_STATE_SWIPE, swipeFlags) | makeFlag(ACTION_STATE_DRAG,
-                    dragFlags);
+            return makeFlag(ACTION_STATE_IDLE, swipeFlags | dragFlags)
+                    | makeFlag(ACTION_STATE_SWIPE, swipeFlags)
+                    | makeFlag(ACTION_STATE_DRAG, dragFlags);
         }
 
         /**
@@ -1547,7 +1538,7 @@
         public int convertToAbsoluteDirection(int flags, int layoutDirection) {
             int masked = flags & RELATIVE_DIR_FLAGS;
             if (masked == 0) {
-                return flags;// does not have any relative flags, good.
+                return flags; // does not have any relative flags, good.
             }
             flags &= ~masked; //remove start / end
             if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) {
@@ -2134,8 +2125,8 @@
             final int direction = (int) Math.signum(viewSizeOutOfBounds);
             // might be negative if other direction
             float outOfBoundsRatio = Math.min(1f, 1f * absOutOfBounds / viewSize);
-            final int cappedScroll = (int) (direction * maxScroll *
-                    sDragViewScrollCapInterpolator.getInterpolation(outOfBoundsRatio));
+            final int cappedScroll = (int) (direction * maxScroll
+                    * sDragViewScrollCapInterpolator.getInterpolation(outOfBoundsRatio));
             final float timeRatio;
             if (msSinceStartScroll > DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS) {
                 timeRatio = 1f;
@@ -2297,7 +2288,7 @@
         }
     }
 
-    private class RecoverAnimation implements AnimatorListenerCompat {
+    private class RecoverAnimation implements Animator.AnimatorListener {
 
         final float mStartDx;
 
@@ -2311,7 +2302,7 @@
 
         final int mActionState;
 
-        private final ValueAnimatorCompat mValueAnimator;
+        private final ValueAnimator mValueAnimator;
 
         final int mAnimationType;
 
@@ -2329,7 +2320,7 @@
 
         private float mFraction;
 
-        public RecoverAnimation(ViewHolder viewHolder, int animationType,
+        RecoverAnimation(ViewHolder viewHolder, int animationType,
                 int actionState, float startDx, float startDy, float targetX, float targetY) {
             mActionState = actionState;
             mAnimationType = animationType;
@@ -2338,11 +2329,11 @@
             mStartDy = startDy;
             mTargetX = targetX;
             mTargetY = targetY;
-            mValueAnimator = AnimatorCompatHelper.emptyValueAnimator();
+            mValueAnimator = ValueAnimator.ofFloat(0f, 1f);
             mValueAnimator.addUpdateListener(
-                    new AnimatorUpdateListenerCompat() {
+                    new ValueAnimator.AnimatorUpdateListener() {
                         @Override
-                        public void onAnimationUpdate(ValueAnimatorCompat animation) {
+                        public void onAnimationUpdate(ValueAnimator animation) {
                             setFraction(animation.getAnimatedFraction());
                         }
                     });
@@ -2374,24 +2365,24 @@
          */
         public void update() {
             if (mStartDx == mTargetX) {
-                mX = ViewCompat.getTranslationX(mViewHolder.itemView);
+                mX = mViewHolder.itemView.getTranslationX();
             } else {
                 mX = mStartDx + mFraction * (mTargetX - mStartDx);
             }
             if (mStartDy == mTargetY) {
-                mY = ViewCompat.getTranslationY(mViewHolder.itemView);
+                mY = mViewHolder.itemView.getTranslationY();
             } else {
                 mY = mStartDy + mFraction * (mTargetY - mStartDy);
             }
         }
 
         @Override
-        public void onAnimationStart(ValueAnimatorCompat animation) {
+        public void onAnimationStart(Animator animation) {
 
         }
 
         @Override
-        public void onAnimationEnd(ValueAnimatorCompat animation) {
+        public void onAnimationEnd(Animator animation) {
             if (!mEnded) {
                 mViewHolder.setIsRecyclable(true);
             }
@@ -2399,13 +2390,13 @@
         }
 
         @Override
-        public void onAnimationCancel(ValueAnimatorCompat animation) {
+        public void onAnimationCancel(Animator animation) {
             setFraction(1f); //make sure we recover the view's state.
         }
 
         @Override
-        public void onAnimationRepeat(ValueAnimatorCompat animation) {
+        public void onAnimationRepeat(Animator animation) {
 
         }
     }
-}
\ No newline at end of file
+}
diff --git a/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchUIUtilImpl.java b/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchUIUtilImpl.java
index ea25477..f8ced35 100644
--- a/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchUIUtilImpl.java
+++ b/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchUIUtilImpl.java
@@ -18,10 +18,9 @@
 
 import android.graphics.Canvas;
 import android.support.v4.view.ViewCompat;
+import android.support.v7.recyclerview.R;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
-import android.support.v7.recyclerview.R;
-
 
 /**
  * Package private class to keep implementations. Putting them inside ItemTouchUIUtil makes them
@@ -75,8 +74,8 @@
 
         @Override
         public void clearView(View view) {
-            ViewCompat.setTranslationX(view, 0f);
-            ViewCompat.setTranslationY(view, 0f);
+            view.setTranslationX(0f);
+            view.setTranslationY(0f);
         }
 
         @Override
@@ -87,8 +86,8 @@
         @Override
         public void onDraw(Canvas c, RecyclerView recyclerView, View view,
                 float dX, float dY, int actionState, boolean isCurrentlyActive) {
-            ViewCompat.setTranslationX(view, dX);
-            ViewCompat.setTranslationY(view, dY);
+            view.setTranslationX(dX);
+            view.setTranslationY(dY);
         }
 
         @Override
diff --git a/v7/recyclerview/tests/AndroidManifest.xml b/v7/recyclerview/tests/AndroidManifest.xml
index 1c8684d..f8cbdd4 100644
--- a/v7/recyclerview/tests/AndroidManifest.xml
+++ b/v7/recyclerview/tests/AndroidManifest.xml
@@ -17,7 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.v7.recyclerview.test">
-    <uses-sdk android:minSdkVersion="9"
+    <uses-sdk android:minSdkVersion="14"
               android:targetSdkVersion="23"
               tools:overrideLibrary="android.support.test,
                       android.app, android.support.test.rule, android.support.test.espresso,
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
index 7185cbc..5f7bf48 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
@@ -150,7 +150,11 @@
         });
     }
 
-    public View focusSearch(final View focused, final int direction)
+    public View focusSearch(final View focused, final int direction) throws Throwable {
+        return focusSearch(focused, direction, false);
+    }
+
+    public View focusSearch(final View focused, final int direction, boolean waitForScroll)
             throws Throwable {
         final View[] result = new View[1];
         mActivityRule.runOnUiThread(new Runnable() {
@@ -163,6 +167,9 @@
                 result[0] = view;
             }
         });
+        if (waitForScroll && (result[0] != null)) {
+            waitForIdleScroll(mRecyclerView);
+        }
         return result[0];
     }
 
@@ -480,7 +487,7 @@
         });
         getInstrumentation().waitForIdleSync();
         assertThat("should be able to scroll in 10 seconds", !assertArrival ||
-                viewAdded.await(10, TimeUnit.SECONDS),
+                        viewAdded.await(10, TimeUnit.SECONDS),
                 CoreMatchers.is(true));
         waitForIdleScroll(mRecyclerView);
         if (mDebug) {
@@ -548,6 +555,7 @@
             }
         }
     }
+
     public class TestLayoutManager extends RecyclerView.LayoutManager {
         int mScrollVerticallyAmount;
         int mScrollHorizontallyAmount;
@@ -1183,4 +1191,60 @@
             validateRemaining(recyclerView);
         }
     }
+
+    /**
+     * Returns whether a child of RecyclerView is partially in bound. A child is
+     * partially in-bounds if it's either fully or partially visible on the screen.
+     * @param parent The RecyclerView holding the child.
+     * @param child The child view to be checked whether is partially (or fully) within RV's bounds.
+     * @return True if the child view is partially (or fully) visible; false otherwise.
+     */
+    public static boolean isViewPartiallyInBound(RecyclerView parent, View child) {
+        if (child == null) {
+            return false;
+        }
+        final int parentLeft = parent.getPaddingLeft();
+        final int parentTop = parent.getPaddingTop();
+        final int parentRight = parent.getWidth() - parent.getPaddingRight();
+        final int parentBottom = parent.getHeight() - parent.getPaddingBottom();
+
+        final int childLeft = child.getLeft() - child.getScrollX();
+        final int childTop = child.getTop() - child.getScrollY();
+        final int childRight = child.getRight() - child.getScrollX();
+        final int childBottom = child.getBottom() - child.getScrollY();
+
+        if (childLeft >= parentRight || childRight <= parentLeft
+                || childTop >= parentBottom || childBottom <= parentTop) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns whether a child of RecyclerView is fully in-bounds, that is it's fully visible
+     * on the screen.
+     * @param parent The RecyclerView holding the child.
+     * @param child The child view to be checked whether is fully within RV's bounds.
+     * @return True if the child view is fully visible; false otherwise.
+     */
+    public boolean isViewFullyInBound(RecyclerView parent, View child) {
+        if (child == null) {
+            return false;
+        }
+        final int parentLeft = parent.getPaddingLeft();
+        final int parentTop = parent.getPaddingTop();
+        final int parentRight = parent.getWidth() - parent.getPaddingRight();
+        final int parentBottom = parent.getHeight() - parent.getPaddingBottom();
+
+        final int childLeft = child.getLeft() - child.getScrollX();
+        final int childTop = child.getTop() - child.getScrollY();
+        final int childRight = child.getRight() - child.getScrollX();
+        final int childBottom = child.getBottom() - child.getScrollY();
+
+        if (childLeft >= parentLeft && childRight <= parentRight
+                && childTop >= parentTop && childBottom <= parentBottom) {
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/BaseStaggeredGridLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/BaseStaggeredGridLayoutManagerTest.java
index fff64b3..776b10d 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseStaggeredGridLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseStaggeredGridLayoutManagerTest.java
@@ -14,9 +14,13 @@
 
 import static java.util.concurrent.TimeUnit.SECONDS;
 
+import android.graphics.Color;
 import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.StateListDrawable;
 import android.support.annotation.Nullable;
 import android.util.Log;
+import android.util.StateSet;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -907,7 +911,13 @@
                 lp.rightMargin = 7;
                 lp.bottomMargin = 9;
             }
-
+            // Good to have colors for debugging
+            StateListDrawable stl = new StateListDrawable();
+            stl.addState(new int[]{android.R.attr.state_focused},
+                    new ColorDrawable(Color.RED));
+            stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+            //noinspection deprecation using this for kitkat tests
+            holder.itemView.setBackgroundDrawable(stl);
             if (mOnBindCallback != null) {
                 mOnBindCallback.onBoundItem(holder, position);
             }
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/DefaultItemAnimatorTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/DefaultItemAnimatorTest.java
index 52777d3..4e3cc6b 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/DefaultItemAnimatorTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/DefaultItemAnimatorTest.java
@@ -21,7 +21,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.Log;
 import android.view.View;
@@ -40,7 +40,7 @@
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class DefaultItemAnimatorTest extends BaseRecyclerViewInstrumentationTest {
 
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/FocusSearchNavigationTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/FocusSearchNavigationTest.java
index 55bed7e..3755018 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/FocusSearchNavigationTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/FocusSearchNavigationTest.java
@@ -30,7 +30,7 @@
 import android.content.Context;
 import android.os.Build;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.recyclerview.test.R;
@@ -57,7 +57,7 @@
 /**
  * This class tests RecyclerView focus search failure handling by using a real LayoutManager.
  */
-@MediumTest
+@LargeTest
 @RunWith(Parameterized.class)
 public class FocusSearchNavigationTest {
     @Rule
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerSnappingTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerSnappingTest.java
index bc107b2..b4e0ae3 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerSnappingTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerSnappingTest.java
@@ -22,8 +22,9 @@
 import static junit.framework.Assert.assertTrue;
 
 import android.support.annotation.Nullable;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.view.View;
+import android.widget.TextView;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -33,6 +34,7 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+@LargeTest
 @RunWith(Parameterized.class)
 public class GridLayoutManagerSnappingTest extends BaseGridLayoutManagerTest {
 
@@ -56,7 +58,6 @@
         return result;
     }
 
-    @MediumTest
     @Test
     public void snapOnScrollSameView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -79,7 +80,6 @@
         assertCenterAligned(viewAfterFling);
     }
 
-    @MediumTest
     @Test
     public void snapOnScrollNextItem() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -103,7 +103,6 @@
         assertCenterAligned(viewAfterScroll);
     }
 
-    @MediumTest
     @Test
     public void snapOnFlingSameView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -130,8 +129,6 @@
         assertCenterAligned(viewAfterFling);
     }
 
-
-    @MediumTest
     @Test
     public void snapOnFlingNextView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -144,7 +141,7 @@
         assertCenterAligned(view);
 
         // Velocity high enough to scroll beyond the current view.
-        int velocity = (int) (0.2 * mRecyclerView.getMaxFlingVelocity());
+        int velocity = (int) (0.25 * mRecyclerView.getMaxFlingVelocity());
         int velocityDir = mReverseScroll ? -velocity : velocity;
 
         mGlm.expectIdleState(1);
@@ -154,7 +151,8 @@
 
         View viewAfterFling = findCenterView(mGlm);
 
-        assertNotSame("The view should have scrolled", view, viewAfterFling);
+        assertNotSame("The view should have scrolled!",
+                ((TextView) view).getText(),((TextView) viewAfterFling).getText());
         assertCenterAligned(viewAfterFling);
     }
 
@@ -204,12 +202,12 @@
             assertEquals("The child should align with the center of the parent",
                     mRecyclerView.getWidth() / 2,
                     mGlm.getDecoratedLeft(view) +
-                            mGlm.getDecoratedMeasuredWidth(view) / 2);
+                            mGlm.getDecoratedMeasuredWidth(view) / 2, 1);
         } else {
             assertEquals("The child should align with the center of the parent",
                     mRecyclerView.getHeight() / 2,
                     mGlm.getDecoratedTop(view) +
-                            mGlm.getDecoratedMeasuredHeight(view) / 2);
+                            mGlm.getDecoratedMeasuredHeight(view) / 2, 1);
         }
     }
 
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerTest.java
index db42498..5ebebfe 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerTest.java
@@ -19,6 +19,7 @@
 import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
 import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
 
+import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -30,7 +31,7 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.StateListDrawable;
 import android.os.Build;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v4.view.AccessibilityDelegateCompat;
@@ -51,7 +52,7 @@
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class GridLayoutManagerTest extends BaseGridLayoutManagerTest {
 
@@ -167,6 +168,367 @@
         }
     }
 
+
+    @Test
+    public void topUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of rows that can be fully in-bounds of RV.
+        final int visibleRowCount = 5;
+        final int spanCount = 3;
+        final int consecutiveFocusableRowsCount = 4;
+        final int consecutiveUnFocusableRowsCount = 8;
+        final int itemCount = (consecutiveFocusableRowsCount + consecutiveUnFocusableRowsCount)
+                * spanCount;
+
+        final RecyclerView recyclerView = setupBasic(new Config(spanCount, itemCount)
+                        .reverseLayout(true),
+                new GridTestAdapter(itemCount, 1) {
+                    RecyclerView mAttachedRv;
+
+                    @Override
+                    public TestViewHolder onCreateViewHolder(ViewGroup parent,
+                            int viewType) {
+                        TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                        // Good to have colors for debugging
+                        StateListDrawable stl = new StateListDrawable();
+                        stl.addState(new int[]{android.R.attr.state_focused},
+                                new ColorDrawable(Color.RED));
+                        stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                        //noinspection deprecation using this for kitkat tests
+                        testViewHolder.itemView.setBackgroundDrawable(stl);
+                        return testViewHolder;
+                    }
+
+                    @Override
+                    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                        mAttachedRv = recyclerView;
+                    }
+
+                    @Override
+                    public void onBindViewHolder(TestViewHolder holder,
+                            int position) {
+                        super.onBindViewHolder(holder, position);
+                        if (position < spanCount * consecutiveFocusableRowsCount) {
+                            holder.itemView.setFocusable(true);
+                            holder.itemView.setFocusableInTouchMode(true);
+                        } else {
+                            holder.itemView.setFocusable(false);
+                            holder.itemView.setFocusableInTouchMode(false);
+                        }
+                        holder.itemView.setMinimumHeight(mAttachedRv.getHeight() / visibleRowCount);
+                    }
+                });
+        waitForFirstLayout(recyclerView);
+
+        // adapter position of the currently focused item.
+        int focusIndex = 1;
+        RecyclerView.ViewHolder toFocus = recyclerView.findViewHolderForAdapterPosition(focusIndex);
+        View viewToFocus = toFocus.itemView;
+        assertTrue(requestFocus(viewToFocus, true));
+        assertSame(viewToFocus, recyclerView.getFocusedChild());
+
+        // adapter position of the item (whether focusable or not) that just becomes fully
+        // visible after focusSearch.
+        int visibleIndex = focusIndex;
+        // The VH of the above adapter position
+        RecyclerView.ViewHolder toVisible = null;
+
+        int maxFocusIndex = (consecutiveFocusableRowsCount - 1) * spanCount + focusIndex;
+        int maxVisibleIndex = (consecutiveFocusableRowsCount + visibleRowCount - 2)
+                * spanCount + visibleIndex;
+
+        // Navigate up through the focusable and unfocusable rows. The focusable rows should
+        // become focused one by one until hitting the last focusable row, at which point,
+        // unfocusable rows should become visible on the screen until the currently focused row
+        // stays on the screen.
+        int pos = focusIndex + spanCount;
+        while (pos < itemCount) {
+            focusSearch(recyclerView.getFocusedChild(), View.FOCUS_UP, true);
+            waitForIdleScroll(recyclerView);
+            focusIndex = Math.min(maxFocusIndex, (focusIndex + spanCount));
+            toFocus = recyclerView.findViewHolderForAdapterPosition(focusIndex);
+            visibleIndex = Math.min(maxVisibleIndex, (visibleIndex + spanCount));
+            toVisible = recyclerView.findViewHolderForAdapterPosition(visibleIndex);
+
+            assertThat("Child at position " + focusIndex + " should be focused",
+                    toFocus.itemView.hasFocus(), is(true));
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(recyclerView, toFocus.itemView));
+            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
+                    isViewFullyInBound(recyclerView, toVisible.itemView));
+            pos += spanCount;
+        }
+    }
+
+    @Test
+    public void bottomUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of rows that can be fully in-bounds of RV.
+        final int visibleRowCount = 5;
+        final int spanCount = 3;
+        final int consecutiveFocusableRowsCount = 4;
+        final int consecutiveUnFocusableRowsCount = 8;
+        final int itemCount = (consecutiveFocusableRowsCount + consecutiveUnFocusableRowsCount)
+                * spanCount;
+
+        final RecyclerView recyclerView = setupBasic(new Config(spanCount, itemCount)
+                        .reverseLayout(false),
+                new GridTestAdapter(itemCount, 1) {
+                    RecyclerView mAttachedRv;
+
+                    @Override
+                    public TestViewHolder onCreateViewHolder(ViewGroup parent,
+                            int viewType) {
+                        TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                        // Good to have colors for debugging
+                        StateListDrawable stl = new StateListDrawable();
+                        stl.addState(new int[]{android.R.attr.state_focused},
+                                new ColorDrawable(Color.RED));
+                        stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                        //noinspection deprecation using this for kitkat tests
+                        testViewHolder.itemView.setBackgroundDrawable(stl);
+                        return testViewHolder;
+                    }
+
+                    @Override
+                    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                        mAttachedRv = recyclerView;
+                    }
+
+                    @Override
+                    public void onBindViewHolder(TestViewHolder holder,
+                            int position) {
+                        super.onBindViewHolder(holder, position);
+                        if (position < spanCount * consecutiveFocusableRowsCount) {
+                            holder.itemView.setFocusable(true);
+                            holder.itemView.setFocusableInTouchMode(true);
+                        } else {
+                            holder.itemView.setFocusable(false);
+                            holder.itemView.setFocusableInTouchMode(false);
+                        }
+                        holder.itemView.setMinimumHeight(mAttachedRv.getHeight() / visibleRowCount);
+                    }
+                });
+        waitForFirstLayout(recyclerView);
+
+        // adapter position of the currently focused item.
+        int focusIndex = 1;
+        RecyclerView.ViewHolder toFocus = recyclerView.findViewHolderForAdapterPosition(focusIndex);
+        View viewToFocus = toFocus.itemView;
+        assertTrue(requestFocus(viewToFocus, true));
+        assertSame(viewToFocus, recyclerView.getFocusedChild());
+
+        // adapter position of the item (whether focusable or not) that just becomes fully
+        // visible after focusSearch.
+        int visibleIndex = focusIndex;
+        // The VH of the above adapter position
+        RecyclerView.ViewHolder toVisible = null;
+
+        int maxFocusIndex = (consecutiveFocusableRowsCount - 1) * spanCount + focusIndex;
+        int maxVisibleIndex = (consecutiveFocusableRowsCount + visibleRowCount - 2)
+                * spanCount + visibleIndex;
+
+        // Navigate down through the focusable and unfocusable rows. The focusable rows should
+        // become focused one by one until hitting the last focusable row, at which point,
+        // unfocusable rows should become visible on the screen until the currently focused row
+        // stays on the screen.
+        int pos = focusIndex + spanCount;
+        while (pos < itemCount) {
+            focusSearch(recyclerView.getFocusedChild(), View.FOCUS_DOWN, true);
+            waitForIdleScroll(recyclerView);
+            focusIndex = Math.min(maxFocusIndex, (focusIndex + spanCount));
+            toFocus = recyclerView.findViewHolderForAdapterPosition(focusIndex);
+            visibleIndex = Math.min(maxVisibleIndex, (visibleIndex + spanCount));
+            toVisible = recyclerView.findViewHolderForAdapterPosition(visibleIndex);
+
+            assertThat("Child at position " + focusIndex + " should be focused",
+                    toFocus.itemView.hasFocus(), is(true));
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(recyclerView, toFocus.itemView));
+            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
+                    isViewFullyInBound(recyclerView, toVisible.itemView));
+            pos += spanCount;
+        }
+    }
+
+    @Test
+    public void leftUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of columns that can be fully in-bounds of RV.
+        final int visibleColCount = 5;
+        final int spanCount = 3;
+        final int consecutiveFocusableColsCount = 4;
+        final int consecutiveUnFocusableColsCount = 8;
+        final int itemCount = (consecutiveFocusableColsCount + consecutiveUnFocusableColsCount)
+                * spanCount;
+
+        final RecyclerView recyclerView = setupBasic(new Config(spanCount, itemCount)
+                        .orientation(HORIZONTAL).reverseLayout(true),
+                new GridTestAdapter(itemCount, 1) {
+                    RecyclerView mAttachedRv;
+
+                    @Override
+                    public TestViewHolder onCreateViewHolder(ViewGroup parent,
+                            int viewType) {
+                        TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                        // Good to have colors for debugging
+                        StateListDrawable stl = new StateListDrawable();
+                        stl.addState(new int[]{android.R.attr.state_focused},
+                                new ColorDrawable(Color.RED));
+                        stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                        //noinspection deprecation using this for kitkat tests
+                        testViewHolder.itemView.setBackgroundDrawable(stl);
+                        return testViewHolder;
+                    }
+
+                    @Override
+                    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                        mAttachedRv = recyclerView;
+                    }
+
+                    @Override
+                    public void onBindViewHolder(TestViewHolder holder,
+                            int position) {
+                        super.onBindViewHolder(holder, position);
+                        if (position < spanCount * consecutiveFocusableColsCount) {
+                            holder.itemView.setFocusable(true);
+                            holder.itemView.setFocusableInTouchMode(true);
+                        } else {
+                            holder.itemView.setFocusable(false);
+                            holder.itemView.setFocusableInTouchMode(false);
+                        }
+                        holder.itemView.setMinimumWidth(mAttachedRv.getWidth() / visibleColCount);
+                    }
+                });
+        waitForFirstLayout(recyclerView);
+
+        // adapter position of the currently focused item.
+        int focusIndex = 1;
+        RecyclerView.ViewHolder toFocus = recyclerView.findViewHolderForAdapterPosition(focusIndex);
+        View viewToFocus = toFocus.itemView;
+        assertTrue(requestFocus(viewToFocus, true));
+        assertSame(viewToFocus, recyclerView.getFocusedChild());
+
+        // adapter position of the item (whether focusable or not) that just becomes fully
+        // visible after focusSearch.
+        int visibleIndex = focusIndex;
+        // The VH of the above adapter position
+        RecyclerView.ViewHolder toVisible = null;
+
+        int maxFocusIndex = (consecutiveFocusableColsCount - 1) * spanCount + focusIndex;
+        int maxVisibleIndex = (consecutiveFocusableColsCount + visibleColCount - 2)
+                * spanCount + visibleIndex;
+
+        // Navigate left through the focusable and unfocusable columns. The focusable columns should
+        // become focused one by one until hitting the last focusable column, at which point,
+        // unfocusable columns should become visible on the screen until the currently focused
+        // column stays on the screen.
+        int pos = focusIndex + spanCount;
+        while (pos < itemCount) {
+            focusSearch(recyclerView.getFocusedChild(), View.FOCUS_LEFT, true);
+            waitForIdleScroll(recyclerView);
+            focusIndex = Math.min(maxFocusIndex, (focusIndex + spanCount));
+            toFocus = recyclerView.findViewHolderForAdapterPosition(focusIndex);
+            visibleIndex = Math.min(maxVisibleIndex, (visibleIndex + spanCount));
+            toVisible = recyclerView.findViewHolderForAdapterPosition(visibleIndex);
+
+            assertThat("Child at position " + focusIndex + " should be focused",
+                    toFocus.itemView.hasFocus(), is(true));
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(recyclerView, toFocus.itemView));
+            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
+                    isViewFullyInBound(recyclerView, toVisible.itemView));
+            pos += spanCount;
+        }
+    }
+
+    @Test
+    public void rightUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of columns that can be fully in-bounds of RV.
+        final int visibleColCount = 5;
+        final int spanCount = 3;
+        final int consecutiveFocusableColsCount = 4;
+        final int consecutiveUnFocusableColsCount = 8;
+        final int itemCount = (consecutiveFocusableColsCount + consecutiveUnFocusableColsCount)
+                * spanCount;
+
+        final RecyclerView recyclerView = setupBasic(new Config(spanCount, itemCount)
+                        .orientation(HORIZONTAL).reverseLayout(false),
+                new GridTestAdapter(itemCount, 1) {
+                    RecyclerView mAttachedRv;
+
+                    @Override
+                    public TestViewHolder onCreateViewHolder(ViewGroup parent,
+                            int viewType) {
+                        TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                        // Good to have colors for debugging
+                        StateListDrawable stl = new StateListDrawable();
+                        stl.addState(new int[]{android.R.attr.state_focused},
+                                new ColorDrawable(Color.RED));
+                        stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                        //noinspection deprecation using this for kitkat tests
+                        testViewHolder.itemView.setBackgroundDrawable(stl);
+                        return testViewHolder;
+                    }
+
+                    @Override
+                    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                        mAttachedRv = recyclerView;
+                    }
+
+                    @Override
+                    public void onBindViewHolder(TestViewHolder holder,
+                            int position) {
+                        super.onBindViewHolder(holder, position);
+                        if (position < spanCount * consecutiveFocusableColsCount) {
+                            holder.itemView.setFocusable(true);
+                            holder.itemView.setFocusableInTouchMode(true);
+                        } else {
+                            holder.itemView.setFocusable(false);
+                            holder.itemView.setFocusableInTouchMode(false);
+                        }
+                        holder.itemView.setMinimumWidth(mAttachedRv.getWidth() / visibleColCount);
+                    }
+                });
+        waitForFirstLayout(recyclerView);
+
+        // adapter position of the currently focused item.
+        int focusIndex = 1;
+        RecyclerView.ViewHolder toFocus = recyclerView.findViewHolderForAdapterPosition(focusIndex);
+        View viewToFocus = toFocus.itemView;
+        assertTrue(requestFocus(viewToFocus, true));
+        assertSame(viewToFocus, recyclerView.getFocusedChild());
+
+        // adapter position of the item (whether focusable or not) that just becomes fully
+        // visible after focusSearch.
+        int visibleIndex = focusIndex;
+        // The VH of the above adapter position
+        RecyclerView.ViewHolder toVisible = null;
+
+        int maxFocusIndex = (consecutiveFocusableColsCount - 1) * spanCount + focusIndex;
+        int maxVisibleIndex = (consecutiveFocusableColsCount + visibleColCount - 2)
+                * spanCount + visibleIndex;
+
+        // Navigate right through the focusable and unfocusable columns. The focusable columns
+        // should become focused one by one until hitting the last focusable column, at which point,
+        // unfocusable columns should become visible on the screen until the currently focused
+        // column stays on the screen.
+        int pos = focusIndex + spanCount;
+        while (pos < itemCount) {
+            focusSearch(recyclerView.getFocusedChild(), View.FOCUS_RIGHT, true);
+            waitForIdleScroll(recyclerView);
+            focusIndex = Math.min(maxFocusIndex, (focusIndex + spanCount));
+            toFocus = recyclerView.findViewHolderForAdapterPosition(focusIndex);
+            visibleIndex = Math.min(maxVisibleIndex, (visibleIndex + spanCount));
+            toVisible = recyclerView.findViewHolderForAdapterPosition(visibleIndex);
+
+            assertThat("Child at position " + focusIndex + " should be focused",
+                    toFocus.itemView.hasFocus(), is(true));
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(recyclerView, toFocus.itemView));
+            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
+                    isViewFullyInBound(recyclerView, toVisible.itemView));
+            pos += spanCount;
+        }
+    }
+
     @UiThreadTest
     @Test
     public void scrollWithoutLayout() throws Throwable {
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerBaseConfigSetTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerBaseConfigSetTest.java
index 0a9095c..731cc67 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerBaseConfigSetTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerBaseConfigSetTest.java
@@ -29,8 +29,7 @@
 import static org.junit.Assert.assertThat;
 
 import android.graphics.Rect;
-import android.support.test.filters.MediumTest;
-import android.support.v4.view.ViewCompat;
+import android.support.test.filters.LargeTest;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewParent;
@@ -47,7 +46,7 @@
  * Tests that rely on the basic configuration and does not do any additions / removals
  */
 @RunWith(Parameterized.class)
-@MediumTest
+@LargeTest
 public class LinearLayoutManagerBaseConfigSetTest extends BaseLinearLayoutManagerTest {
 
     private final Config mConfig;
@@ -246,9 +245,9 @@
             @Override
             public void run() {
                 if (mConfig.mOrientation == HORIZONTAL) {
-                    ViewCompat.setTranslationX(vh.itemView, size * 2);
+                    vh.itemView.setTranslationX(size * 2);
                 } else {
-                    ViewCompat.setTranslationY(vh.itemView, size * 2);
+                    vh.itemView.setTranslationY(size * 2);
                 }
             }
         });
@@ -280,9 +279,9 @@
             @Override
             public void run() {
                 if (mConfig.mOrientation == HORIZONTAL) {
-                    ViewCompat.setTranslationX(vh.itemView, -size * 2);
+                    vh.itemView.setTranslationX(-size * 2);
                 } else {
-                    ViewCompat.setTranslationY(vh.itemView, -size * 2);
+                    vh.itemView.setTranslationY(-size * 2);
                 }
             }
         });
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerSnappingTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerSnappingTest.java
index f211920..ae09600 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerSnappingTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerSnappingTest.java
@@ -22,7 +22,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import android.support.annotation.Nullable;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.view.View;
 
 import org.junit.Test;
@@ -33,6 +33,7 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+@LargeTest
 @RunWith(Parameterized.class)
 public class LinearLayoutManagerSnappingTest extends BaseLinearLayoutManagerTest {
 
@@ -56,7 +57,6 @@
         return result;
     }
 
-    @MediumTest
     @Test
     public void snapOnScrollSameViewEdge() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -82,7 +82,6 @@
         mLayoutManager.assertNoCallbacks("There should be no callbacks after some time", 3);
     }
 
-    @MediumTest
     @Test
     public void snapOnScrollSameView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -105,7 +104,6 @@
         assertCenterAligned(viewAfterFling);
     }
 
-    @MediumTest
     @Test
     public void snapOnScrollNextView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -128,7 +126,6 @@
         assertCenterAligned(viewAfterFling);
     }
 
-    @MediumTest
     @Test
     public void snapOnFlingSameView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -154,7 +151,6 @@
         assertCenterAligned(viewAfterFling);
     }
 
-    @MediumTest
     @Test
     public void snapOnFlingNextView() throws Throwable {
         final Config config = (Config) mConfig.clone();
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java
index 5f61ea7..067689c 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java
@@ -19,16 +19,22 @@
 import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
 import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
 
+import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
-import android.support.test.filters.MediumTest;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.StateListDrawable;
+import android.support.test.filters.LargeTest;
 import android.support.v4.view.AccessibilityDelegateCompat;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
 import android.support.v4.view.accessibility.AccessibilityRecordCompat;
 import android.util.Log;
+import android.util.StateSet;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
@@ -39,6 +45,7 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
+
 /**
  * Includes tests for {@link LinearLayoutManager}.
  * <p>
@@ -46,10 +53,352 @@
  * and stability of LinearLayoutManager in response to different events (state change, scrolling
  * etc) where it is very hard to do manual testing.
  */
-@MediumTest
+@LargeTest
 public class LinearLayoutManagerTest extends BaseLinearLayoutManagerTest {
 
     @Test
+    public void topUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of child views that can be visible at any time.
+        final int visibleChildCount = 5;
+        final int consecutiveFocusablesCount = 2;
+        final int consecutiveUnFocusablesCount = 18;
+        final TestAdapter adapter = new TestAdapter(
+                consecutiveFocusablesCount + consecutiveUnFocusablesCount) {
+            RecyclerView mAttachedRv;
+
+            @Override
+            public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                // Good to have colors for debugging
+                StateListDrawable stl = new StateListDrawable();
+                stl.addState(new int[]{android.R.attr.state_focused},
+                        new ColorDrawable(Color.RED));
+                stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                //noinspection deprecation used to support kitkat tests
+                testViewHolder.itemView.setBackgroundDrawable(stl);
+                return testViewHolder;
+            }
+
+            @Override
+            public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                mAttachedRv = recyclerView;
+            }
+
+            @Override
+            public void onBindViewHolder(TestViewHolder holder,
+                    int position) {
+                super.onBindViewHolder(holder, position);
+                if (position < consecutiveFocusablesCount) {
+                    holder.itemView.setFocusable(true);
+                    holder.itemView.setFocusableInTouchMode(true);
+                } else {
+                    holder.itemView.setFocusable(false);
+                    holder.itemView.setFocusableInTouchMode(false);
+                }
+                // This height ensures that some portion of #visibleChildCount'th child is
+                // off-bounds, creating more interesting test scenario.
+                holder.itemView.setMinimumHeight((mAttachedRv.getHeight()
+                        + mAttachedRv.getHeight() / (2 * visibleChildCount)) / visibleChildCount);
+            }
+        };
+        setupByConfig(new Config(VERTICAL, false, false).adapter(adapter).reverseLayout(true),
+                false);
+        waitForFirstLayout();
+
+        // adapter position of the currently focused item.
+        int focusIndex = 0;
+        View newFocused = mRecyclerView.getChildAt(focusIndex);
+        requestFocus(newFocused, true);
+        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
+                focusIndex);
+        assertThat("Child at position " + focusIndex + " should be focused",
+                toFocus.itemView.hasFocus(), is(true));
+
+        // adapter position of the item (whether focusable or not) that just becomes fully
+        // visible after focusSearch.
+        int visibleIndex = 0;
+        // The VH of the above adapter position
+        RecyclerView.ViewHolder toVisible = null;
+
+        // Navigate up through the focusable and unfocusable chunks. The focusable items should
+        // become focused one by one until hitting the last focusable item, at which point,
+        // unfocusable items should become visible on the screen until the currently focused item
+        // stays on the screen.
+        for (int i = 0; i < adapter.getItemCount(); i++) {
+            focusSearch(mRecyclerView.getFocusedChild(), View.FOCUS_UP, true);
+            // adapter position of the currently focused item.
+            focusIndex = Math.min(consecutiveFocusablesCount - 1, (focusIndex + 1));
+            toFocus = mRecyclerView.findViewHolderForAdapterPosition(focusIndex);
+            visibleIndex = Math.min(consecutiveFocusablesCount + visibleChildCount - 2,
+                    (visibleIndex + 1));
+            toVisible = mRecyclerView.findViewHolderForAdapterPosition(visibleIndex);
+
+            assertThat("Child at position " + focusIndex + " should be focused",
+                    toFocus.itemView.hasFocus(), is(true));
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(mRecyclerView, toFocus.itemView));
+            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
+                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
+        }
+    }
+
+    @Test
+    public void bottomUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of child views that can be visible at any time.
+        final int visibleChildCount = 5;
+        final int consecutiveFocusablesCount = 2;
+        final int consecutiveUnFocusablesCount = 18;
+        final TestAdapter adapter = new TestAdapter(
+                consecutiveFocusablesCount + consecutiveUnFocusablesCount) {
+            RecyclerView mAttachedRv;
+
+            @Override
+            public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                // Good to have colors for debugging
+                StateListDrawable stl = new StateListDrawable();
+                stl.addState(new int[]{android.R.attr.state_focused},
+                        new ColorDrawable(Color.RED));
+                stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                //noinspection deprecation used to support kitkat tests
+                testViewHolder.itemView.setBackgroundDrawable(stl);
+                return testViewHolder;
+            }
+
+            @Override
+            public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                mAttachedRv = recyclerView;
+            }
+
+            @Override
+            public void onBindViewHolder(TestViewHolder holder,
+                    int position) {
+                super.onBindViewHolder(holder, position);
+                if (position < consecutiveFocusablesCount) {
+                    holder.itemView.setFocusable(true);
+                    holder.itemView.setFocusableInTouchMode(true);
+                } else {
+                    holder.itemView.setFocusable(false);
+                    holder.itemView.setFocusableInTouchMode(false);
+                }
+                // This height ensures that some portion of #visibleChildCount'th child is
+                // off-bounds, creating more interesting test scenario.
+                holder.itemView.setMinimumHeight((mAttachedRv.getHeight()
+                        + mAttachedRv.getHeight() / (2 * visibleChildCount)) / visibleChildCount);
+            }
+        };
+        setupByConfig(new Config(VERTICAL, false, false).adapter(adapter), false);
+        waitForFirstLayout();
+
+        // adapter position of the currently focused item.
+        int focusIndex = 0;
+        View newFocused = mRecyclerView.getChildAt(focusIndex);
+        requestFocus(newFocused, true);
+        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
+                focusIndex);
+        assertThat("Child at position " + focusIndex + " should be focused",
+                toFocus.itemView.hasFocus(), is(true));
+
+        // adapter position of the item (whether focusable or not) that just becomes fully
+        // visible after focusSearch.
+        int visibleIndex = 0;
+        // The VH of the above adapter position
+        RecyclerView.ViewHolder toVisible = null;
+
+        // Navigate down through the focusable and unfocusable chunks. The focusable items should
+        // become focused one by one until hitting the last focusable item, at which point,
+        // unfocusable items should become visible on the screen until the currently focused item
+        // stays on the screen.
+        for (int i = 0; i < adapter.getItemCount(); i++) {
+            focusSearch(mRecyclerView.getFocusedChild(), View.FOCUS_DOWN, true);
+            // adapter position of the currently focused item.
+            focusIndex = Math.min(consecutiveFocusablesCount - 1, (focusIndex + 1));
+            toFocus = mRecyclerView.findViewHolderForAdapterPosition(focusIndex);
+            visibleIndex = Math.min(consecutiveFocusablesCount + visibleChildCount - 2,
+                    (visibleIndex + 1));
+            toVisible = mRecyclerView.findViewHolderForAdapterPosition(visibleIndex);
+
+            assertThat("Child at position " + focusIndex + " should be focused",
+                    toFocus.itemView.hasFocus(), is(true));
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(mRecyclerView, toFocus.itemView));
+            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
+                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
+        }
+    }
+
+    @Test
+    public void leftUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of child views that can be visible at any time.
+        final int visibleChildCount = 5;
+        final int consecutiveFocusablesCount = 2;
+        final int consecutiveUnFocusablesCount = 18;
+        final TestAdapter adapter = new TestAdapter(
+                consecutiveFocusablesCount + consecutiveUnFocusablesCount) {
+            RecyclerView mAttachedRv;
+
+            @Override
+            public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                // Good to have colors for debugging
+                StateListDrawable stl = new StateListDrawable();
+                stl.addState(new int[]{android.R.attr.state_focused},
+                        new ColorDrawable(Color.RED));
+                stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                //noinspection deprecation used to support kitkat tests
+                testViewHolder.itemView.setBackgroundDrawable(stl);
+                return testViewHolder;
+            }
+
+            @Override
+            public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                mAttachedRv = recyclerView;
+            }
+
+            @Override
+            public void onBindViewHolder(TestViewHolder holder,
+                    int position) {
+                super.onBindViewHolder(holder, position);
+                if (position < consecutiveFocusablesCount) {
+                    holder.itemView.setFocusable(true);
+                    holder.itemView.setFocusableInTouchMode(true);
+                } else {
+                    holder.itemView.setFocusable(false);
+                    holder.itemView.setFocusableInTouchMode(false);
+                }
+                // This width ensures that some portion of #visibleChildCount'th child is
+                // off-bounds, creating more interesting test scenario.
+                holder.itemView.setMinimumWidth((mAttachedRv.getWidth()
+                        + mAttachedRv.getWidth() / (2 * visibleChildCount)) / visibleChildCount);
+            }
+        };
+        setupByConfig(new Config(HORIZONTAL, false, false).adapter(adapter).reverseLayout(true),
+                false);
+        waitForFirstLayout();
+
+        // adapter position of the currently focused item.
+        int focusIndex = 0;
+        View newFocused = mRecyclerView.getChildAt(focusIndex);
+        requestFocus(newFocused, true);
+        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
+                focusIndex);
+        assertThat("Child at position " + focusIndex + " should be focused",
+                toFocus.itemView.hasFocus(), is(true));
+
+        // adapter position of the item (whether focusable or not) that just becomes fully
+        // visible after focusSearch.
+        int visibleIndex = 0;
+        // The VH of the above adapter position
+        RecyclerView.ViewHolder toVisible = null;
+
+        // Navigate left through the focusable and unfocusable chunks. The focusable items should
+        // become focused one by one until hitting the last focusable item, at which point,
+        // unfocusable items should become visible on the screen until the currently focused item
+        // stays on the screen.
+        for (int i = 0; i < adapter.getItemCount(); i++) {
+            focusSearch(mRecyclerView.getFocusedChild(), View.FOCUS_LEFT, true);
+            // adapter position of the currently focused item.
+            focusIndex = Math.min(consecutiveFocusablesCount - 1, (focusIndex + 1));
+            toFocus = mRecyclerView.findViewHolderForAdapterPosition(focusIndex);
+            visibleIndex = Math.min(consecutiveFocusablesCount + visibleChildCount - 2,
+                    (visibleIndex + 1));
+            toVisible = mRecyclerView.findViewHolderForAdapterPosition(visibleIndex);
+
+            assertThat("Child at position " + focusIndex + " should be focused",
+                    toFocus.itemView.hasFocus(), is(true));
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(mRecyclerView, toFocus.itemView));
+            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
+                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
+        }
+    }
+
+    @Test
+    public void rightUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of child views that can be visible at any time.
+        final int visibleChildCount = 5;
+        final int consecutiveFocusablesCount = 2;
+        final int consecutiveUnFocusablesCount = 18;
+        final TestAdapter adapter = new TestAdapter(
+                consecutiveFocusablesCount + consecutiveUnFocusablesCount) {
+            RecyclerView mAttachedRv;
+
+            @Override
+            public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                // Good to have colors for debugging
+                StateListDrawable stl = new StateListDrawable();
+                stl.addState(new int[]{android.R.attr.state_focused},
+                        new ColorDrawable(Color.RED));
+                stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                //noinspection deprecation used to support kitkat tests
+                testViewHolder.itemView.setBackgroundDrawable(stl);
+                return testViewHolder;
+            }
+
+            @Override
+            public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                mAttachedRv = recyclerView;
+            }
+
+            @Override
+            public void onBindViewHolder(TestViewHolder holder,
+                    int position) {
+                super.onBindViewHolder(holder, position);
+                if (position < consecutiveFocusablesCount) {
+                    holder.itemView.setFocusable(true);
+                    holder.itemView.setFocusableInTouchMode(true);
+                } else {
+                    holder.itemView.setFocusable(false);
+                    holder.itemView.setFocusableInTouchMode(false);
+                }
+                // This width ensures that some portion of #visibleChildCount'th child is
+                // off-bounds, creating more interesting test scenario.
+                holder.itemView.setMinimumWidth((mAttachedRv.getWidth()
+                        + mAttachedRv.getWidth() / (2 * visibleChildCount)) / visibleChildCount);
+            }
+        };
+        setupByConfig(new Config(HORIZONTAL, false, false).adapter(adapter), false);
+        waitForFirstLayout();
+
+        // adapter position of the currently focused item.
+        int focusIndex = 0;
+        View newFocused = mRecyclerView.getChildAt(focusIndex);
+        requestFocus(newFocused, true);
+        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
+                focusIndex);
+        assertThat("Child at position " + focusIndex + " should be focused",
+                toFocus.itemView.hasFocus(), is(true));
+
+        // adapter position of the item (whether focusable or not) that just becomes fully
+        // visible after focusSearch.
+        int visibleIndex = 0;
+        // The VH of the above adapter position
+        RecyclerView.ViewHolder toVisible = null;
+
+        // Navigate right through the focusable and unfocusable chunks. The focusable items should
+        // become focused one by one until hitting the last focusable item, at which point,
+        // unfocusable items should become visible on the screen until the currently focused item
+        // stays on the screen.
+        for (int i = 0; i < adapter.getItemCount(); i++) {
+            focusSearch(mRecyclerView.getFocusedChild(), View.FOCUS_RIGHT, true);
+            // adapter position of the currently focused item.
+            focusIndex = Math.min(consecutiveFocusablesCount - 1, (focusIndex + 1));
+            toFocus = mRecyclerView.findViewHolderForAdapterPosition(focusIndex);
+            visibleIndex = Math.min(consecutiveFocusablesCount + visibleChildCount - 2,
+                    (visibleIndex + 1));
+            toVisible = mRecyclerView.findViewHolderForAdapterPosition(visibleIndex);
+
+            assertThat("Child at position " + focusIndex + " should be focused",
+                    toFocus.itemView.hasFocus(), is(true));
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(mRecyclerView, toFocus.itemView));
+            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
+                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
+        }
+    }
+
+    @Test
     public void removeAnchorItem() throws Throwable {
         removeAnchorItemTest(
                 new Config().orientation(VERTICAL).stackFromBottom(false).reverseLayout(
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerWrapContentTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerWrapContentTest.java
index bda7297..7cc1a65 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerWrapContentTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerWrapContentTest.java
@@ -22,7 +22,7 @@
 
 import android.graphics.Rect;
 import android.os.Build;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.v4.view.ViewCompat;
 import android.view.Gravity;
@@ -36,7 +36,7 @@
 import java.util.List;
 
 @RunWith(Parameterized.class)
-@MediumTest
+@LargeTest
 public class LinearLayoutManagerWrapContentTest extends BaseWrapContentTest {
 
     Config mConfig;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/MultiRecyclerViewPrefetchTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/MultiRecyclerViewPrefetchTest.java
index 2a615f2..1147c52 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/MultiRecyclerViewPrefetchTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/MultiRecyclerViewPrefetchTest.java
@@ -25,7 +25,6 @@
 import android.support.test.filters.SdkSuppress;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.support.v4.view.ViewCompat;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -138,7 +137,7 @@
             rv.layout(0, 0, 200, 200);
             rv.scrollBy(0, 100);
 
-            ViewCompat.setTranslationX(rv, 100 * i);
+            rv.setTranslationX(100 * i);
         }
 
         GapWorker worker = GapWorker.sGapWorker.get();
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/PagerSnapHelperTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/PagerSnapHelperTest.java
index 0799d3d..abdcbe8 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/PagerSnapHelperTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/PagerSnapHelperTest.java
@@ -22,7 +22,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import android.support.annotation.Nullable;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
@@ -35,6 +35,7 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+@LargeTest
 @RunWith(Parameterized.class)
 public class PagerSnapHelperTest extends BaseLinearLayoutManagerTest {
 
@@ -58,7 +59,6 @@
         return result;
     }
 
-    @MediumTest
     @Test
     public void snapOnScrollSameView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -85,7 +85,6 @@
         assertCenterAligned(viewAfterFling);
     }
 
-    @MediumTest
     @Test
     public void snapOnScrollNextView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -116,7 +115,6 @@
         assertCenterAligned(viewAfterFling);
     }
 
-    @MediumTest
     @Test
     public void snapOnFlingSameView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -154,7 +152,6 @@
         assertCenterAligned(viewAfterFling);
     }
 
-    @MediumTest
     @Test
     public void snapOnFlingNextView() throws Throwable {
         final Config config = (Config) mConfig.clone();
@@ -167,7 +164,6 @@
         runSnapOnMaxFlingNextView((int) (0.2 * mRecyclerView.getMaxFlingVelocity()));
     }
 
-    @MediumTest
     @Test
     public void snapOnMaxFlingNextView() throws Throwable {
         final Config config = (Config) mConfig.clone();
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAccessibilityLifecycleTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAccessibilityLifecycleTest.java
index 2d5e677..6a2a175 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAccessibilityLifecycleTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAccessibilityLifecycleTest.java
@@ -19,14 +19,11 @@
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.annotation.TargetApi;
-import android.content.Context;
 import android.os.Build;
 import android.support.test.filters.MediumTest;
 import android.support.test.filters.SdkSuppress;
@@ -37,7 +34,6 @@
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mockito;
 
 import java.util.ArrayList;
 import java.util.Arrays;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAnimationsTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAnimationsTest.java
index 5379354..da5be39 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAnimationsTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAnimationsTest.java
@@ -28,7 +28,7 @@
 import android.graphics.Rect;
 import android.os.Build;
 import android.support.annotation.NonNull;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v4.view.ViewCompat;
@@ -53,7 +53,7 @@
 /**
  * Tests for {@link SimpleItemAnimator} API.
  */
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class RecyclerViewAnimationsTest extends BaseRecyclerViewAnimationsTest {
 
@@ -1404,7 +1404,7 @@
             public void onViewDetachedFromWindow(TestViewHolder holder) {
                 if ((addedView[0] == holder.itemView || addedView[1] == holder.itemView)
                         && ViewCompat.hasTransientState(holder.itemView)) {
-                    ViewCompat.animate(holder.itemView).cancel();
+                    holder.itemView.animate().cancel();
                 }
                 super.onViewDetachedFromWindow(holder);
             }
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
index e15b9bd..786df47 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
@@ -51,7 +51,7 @@
 import android.os.Build;
 import android.os.SystemClock;
 import android.support.annotation.Nullable;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v4.view.ViewCompat;
@@ -82,7 +82,7 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 @RunWith(AndroidJUnit4.class)
-@MediumTest
+@LargeTest
 public class RecyclerViewLayoutTest extends BaseRecyclerViewInstrumentationTest {
     private static final int FLAG_HORIZONTAL = 1;
     private static final int FLAG_VERTICAL = 1 << 1;
@@ -326,7 +326,7 @@
                 holder.itemView.setFocusableInTouchMode(true);
                 holder.itemView.setLayoutParams(
                         new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
-                        ViewGroup.LayoutParams.WRAP_CONTENT));
+                                ViewGroup.LayoutParams.WRAP_CONTENT));
             }
         });
         TestLayoutManager tlm = new TestLayoutManager() {
@@ -355,7 +355,7 @@
 
             @Override
             public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
-                                            RecyclerView.State state) {
+                    RecyclerView.State state) {
                 super.scrollHorizontallyBy(dx, recycler, state);
                 // offset by -dx because the views translate opposite of the scrolling direction
                 mRecyclerView.offsetChildrenHorizontal(-dx);
@@ -364,7 +364,7 @@
 
             @Override
             public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
-                                          RecyclerView.State state) {
+                    RecyclerView.State state) {
                 super.scrollVerticallyBy(dy, recycler, state);
                 // offset by -dy because the views translate opposite of the scrolling direction
                 mRecyclerView.offsetChildrenVertical(-dy);
@@ -416,7 +416,7 @@
             @Override
             public void run(View view) throws RuntimeException {
                 view.layout(10, 10, 30, 50);
-                ViewCompat.setTranslationX(view, 10);
+                view.setTranslationX(10);
                 assertThat(getTransformedBoundingBox(view), is(new Rect(20, 10, 40, 50)));
             }
         });
@@ -428,7 +428,7 @@
             @Override
             public void run(View view) throws RuntimeException {
                 view.layout(10, 10, 30, 50);
-                ViewCompat.setTranslationY(view, 10);
+                view.setTranslationY(10);
                 assertThat(getTransformedBoundingBox(view), is(new Rect(10, 20, 30, 60)));
             }
         });
@@ -440,7 +440,7 @@
             @Override
             public void run(View view) throws RuntimeException {
                 view.layout(10, 10, 30, 50);
-                ViewCompat.setScaleX(view, 2);
+                view.setScaleX(2);
                 assertThat(getTransformedBoundingBox(view), is(new Rect(0, 10, 40, 50)));
             }
         });
@@ -452,7 +452,7 @@
             @Override
             public void run(View view) throws RuntimeException {
                 view.layout(10, 10, 30, 50);
-                ViewCompat.setScaleY(view, 2);
+                view.setScaleY(2);
                 assertThat(getTransformedBoundingBox(view), is(new Rect(10, -10, 30, 70)));
             }
         });
@@ -464,7 +464,7 @@
             @Override
             public void run(View view) throws RuntimeException {
                 view.layout(10, 10, 30, 50);
-                ViewCompat.setRotation(view, 90);
+                view.setRotation(90);
                 assertThat(getTransformedBoundingBox(view), is(new Rect(0, 20, 40, 40)));
             }
         });
@@ -495,7 +495,7 @@
                 // trigger decor offsets calculation
                 calculateItemDecorationsForChild(view, new Rect());
                 view.layout(10, 10, 30, 50);
-                ViewCompat.setRotation(view, 90);
+                view.setRotation(90);
                 assertThat(RecyclerViewLayoutTest.this.getTransformedBoundingBox(view),
                         is(new Rect(-4, 19, 42, 43)));
 
@@ -604,7 +604,7 @@
 
             @Override
             public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
-                                          RecyclerView.State state) {
+                    RecyclerView.State state) {
                 // Access views in the state (that might have been deleted).
                 for (int  i = 10; i < state.getItemCount(); i++) {
                     recycler.getViewForPosition(i);
@@ -728,8 +728,8 @@
             @Nullable
             @Override
             public View onFocusSearchFailed(View focused, int direction,
-                                            RecyclerView.Recycler recycler,
-                                            RecyclerView.State state) {
+                    RecyclerView.Recycler recycler,
+                    RecyclerView.State state) {
                 try {
                     recycler.getViewForPosition(state.getItemCount() - 1);
                 } catch (Throwable t) {
@@ -4246,7 +4246,7 @@
 
                             @Override
                             protected void onTargetFound(View targetView, RecyclerView.State state,
-                                                         Action action) {
+                                    Action action) {
                                 super.onTargetFound(targetView, state, action);
                                 mTargetFound.set(true);
                             }
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerBaseConfigSetTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerBaseConfigSetTest.java
index b9bfe40..984db5b 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerBaseConfigSetTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerBaseConfigSetTest.java
@@ -34,8 +34,7 @@
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.support.test.filters.MediumTest;
-import android.support.v4.view.ViewCompat;
+import android.support.test.filters.LargeTest;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewParent;
@@ -51,7 +50,7 @@
 import java.util.UUID;
 
 @RunWith(Parameterized.class)
-@MediumTest
+@LargeTest
 public class StaggeredGridLayoutManagerBaseConfigSetTest
         extends BaseStaggeredGridLayoutManagerTest {
 
@@ -760,9 +759,9 @@
             @Override
             public void run() {
                 if (mConfig.mOrientation == HORIZONTAL) {
-                    ViewCompat.setTranslationX(vh.itemView, size * 2);
+                    vh.itemView.setTranslationX(size * 2);
                 } else {
-                    ViewCompat.setTranslationY(vh.itemView, size * 2);
+                    vh.itemView.setTranslationY(size * 2);
                 }
             }
         });
@@ -797,9 +796,9 @@
             @Override
             public void run() {
                 if (mConfig.mOrientation == HORIZONTAL) {
-                    ViewCompat.setTranslationX(vh.itemView, -size * 2);
+                    vh.itemView.setTranslationX(-size * 2);
                 } else {
-                    ViewCompat.setTranslationY(vh.itemView, -size * 2);
+                    vh.itemView.setTranslationY(-size * 2);
                 }
             }
         });
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerGapTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerGapTest.java
index 17299a0..08c64f0 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerGapTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerGapTest.java
@@ -21,7 +21,7 @@
 import static org.junit.Assert.assertNull;
 
 import android.graphics.Rect;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -32,7 +32,7 @@
 import java.util.Map;
 
 @RunWith(Parameterized.class)
-@MediumTest
+@LargeTest
 public class StaggeredGridLayoutManagerGapTest extends BaseStaggeredGridLayoutManagerTest {
     private final Config mConfig;
     private final int mDeletePosition;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerSnappingTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerSnappingTest.java
index 828ffab..fd67e03 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerSnappingTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerSnappingTest.java
@@ -22,7 +22,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import android.support.annotation.Nullable;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.view.View;
 
 import org.junit.Test;
@@ -33,7 +33,7 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-@MediumTest
+@LargeTest
 @RunWith(Parameterized.class)
 public class StaggeredGridLayoutManagerSnappingTest extends BaseStaggeredGridLayoutManagerTest {
 
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
index d92b169..89db393 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
@@ -37,7 +37,7 @@
 import android.graphics.drawable.StateListDrawable;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.v4.view.AccessibilityDelegateCompat;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
 import android.support.v4.view.accessibility.AccessibilityRecordCompat;
@@ -58,7 +58,7 @@
 import java.util.Map;
 import java.util.UUID;
 
-@MediumTest
+@LargeTest
 public class StaggeredGridLayoutManagerTest extends BaseStaggeredGridLayoutManagerTest {
     @Test
     public void forceLayoutOnDetach() throws Throwable {
@@ -80,7 +80,7 @@
         smoothScrollToPosition(100);
         mLayoutManager.expectLayouts(1);
         mAdapter.deleteAndNotify(0, 2);
-        mLayoutManager.waitForLayout(2);
+        mLayoutManager.waitForLayout(2000);
         smoothScrollToPosition(0);
         assertFalse("all starts should not be the same", mLayoutManager.areAllStartsEqual());
     }
@@ -277,6 +277,16 @@
                         holder.mBoundItem = item;
                         ((EditText) ((FrameLayout) holder.itemView).getChildAt(0)).setText(
                                 item.mText + " (" + item.mId + ")");
+                        // Good to have colors for debugging
+                        StateListDrawable stl = new StateListDrawable();
+                        stl.addState(new int[]{android.R.attr.state_focused},
+                                new ColorDrawable(Color.RED));
+                        stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                        //noinspection deprecation using this for kitkat tests
+                        holder.itemView.setBackgroundDrawable(stl);
+                        if (mOnBindCallback != null) {
+                            mOnBindCallback.onBoundItem(holder, position);
+                        }
                     }
                 });
         mLayoutManager.expectLayouts(1);
@@ -394,6 +404,449 @@
         waitForIdleScroll(mRecyclerView);
     }
 
+    @Test
+    public void topUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of rows that can be fully in-bounds of RV.
+        final int visibleRowCount = 5;
+        final int spanCount = 3;
+        final int lastFocusableIndex = 6;
+
+        setupByConfig(new Config(VERTICAL, true, spanCount, GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS),
+                new GridTestAdapter(18, 1) {
+                    RecyclerView mAttachedRv;
+
+                    @Override
+                    public TestViewHolder onCreateViewHolder(ViewGroup parent,
+                            int viewType) {
+                        TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                        testViewHolder.itemView.setFocusable(true);
+                        testViewHolder.itemView.setFocusableInTouchMode(true);
+                        // Good to have colors for debugging
+                        StateListDrawable stl = new StateListDrawable();
+                        stl.addState(new int[]{android.R.attr.state_focused},
+                                new ColorDrawable(Color.RED));
+                        stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                        //noinspection deprecation used to support kitkat tests
+                        testViewHolder.itemView.setBackgroundDrawable(stl);
+                        return testViewHolder;
+                    }
+
+                    @Override
+                    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                        mAttachedRv = recyclerView;
+                    }
+
+                    @Override
+                    public void onBindViewHolder(TestViewHolder holder,
+                            int position) {
+                        super.onBindViewHolder(holder, position);
+                        RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.itemView
+                                .getLayoutParams();
+                        if (position <= lastFocusableIndex) {
+                            holder.itemView.setFocusable(true);
+                            holder.itemView.setFocusableInTouchMode(true);
+                        } else {
+                            holder.itemView.setFocusable(false);
+                            holder.itemView.setFocusableInTouchMode(false);
+                        }
+                        holder.itemView.setMinimumHeight(mAttachedRv.getHeight() / visibleRowCount);
+                        lp.topMargin = 0;
+                        lp.leftMargin = 0;
+                        lp.rightMargin = 0;
+                        lp.bottomMargin = 0;
+                        if (position == 11) {
+                            lp.bottomMargin = 9;
+                        }
+                    }
+                });
+
+        /**
+         *
+         * 15 16 17
+         * 12 13 14
+         * 11 11 11
+         * 9 10
+         * 8 8 8
+         * 7
+         * 6 6 6
+         * 3 4 5
+         * 0 1 2
+         */
+        mAdapter.mFullSpanItems.add(6);
+        mAdapter.mFullSpanItems.add(8);
+        mAdapter.mFullSpanItems.add(11);
+        waitFirstLayout();
+
+
+        // adapter position of the currently focused item.
+        int focusIndex = 1;
+        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
+                focusIndex);
+        View viewToFocus = toFocus.itemView;
+        assertTrue(requestFocus(viewToFocus, true));
+        assertSame(viewToFocus, mRecyclerView.getFocusedChild());
+
+        // The VH of the unfocusable item that just became fully visible after focusSearch.
+        RecyclerView.ViewHolder toVisible = null;
+
+        View focusedView = viewToFocus;
+        int actualFocusIndex = -1;
+        // First, scroll until the last focusable row.
+        for (int i : new int[]{4, 6}) {
+            focusSearchAndWaitForScroll(focusedView, View.FOCUS_UP);
+            focusedView = mRecyclerView.getFocusedChild();
+            actualFocusIndex = mRecyclerView.getChildViewHolder(focusedView).getAdapterPosition();
+            assertEquals("Focused view should be at adapter position " + i + " whereas it's at "
+                    + actualFocusIndex, i, actualFocusIndex);
+        }
+
+        // Further scroll up in order to make the unfocusable rows visible. This process should
+        // continue until the currently focused item is still visible. The focused item should not
+        // change in this loop.
+        for (int i : new int[]{9, 11, 11, 11}) {
+            focusSearchAndWaitForScroll(focusedView, View.FOCUS_UP);
+            focusedView = mRecyclerView.getFocusedChild();
+            actualFocusIndex = mRecyclerView.getChildViewHolder(focusedView).getAdapterPosition();
+            toVisible = mRecyclerView.findViewHolderForAdapterPosition(i);
+
+            assertEquals("Focused view should not be changed, whereas it's now at "
+                    + actualFocusIndex, 6, actualFocusIndex);
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(mRecyclerView, focusedView));
+            assertTrue("Child view at adapter pos " + i + " should be fully visible.",
+                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
+        }
+    }
+
+    @Test
+    public void bottomUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of rows that can be fully in-bounds of RV.
+        final int visibleRowCount = 5;
+        final int spanCount = 3;
+        final int lastFocusableIndex = 6;
+
+        setupByConfig(new Config(VERTICAL, false, spanCount, GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS),
+                new GridTestAdapter(18, 1) {
+                    RecyclerView mAttachedRv;
+
+                    @Override
+                    public TestViewHolder onCreateViewHolder(ViewGroup parent,
+                            int viewType) {
+                        TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                        testViewHolder.itemView.setFocusable(true);
+                        testViewHolder.itemView.setFocusableInTouchMode(true);
+                        // Good to have colors for debugging
+                        StateListDrawable stl = new StateListDrawable();
+                        stl.addState(new int[]{android.R.attr.state_focused},
+                                new ColorDrawable(Color.RED));
+                        stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                        //noinspection deprecation used to support kitkat tests
+                        testViewHolder.itemView.setBackgroundDrawable(stl);
+                        return testViewHolder;
+                    }
+
+                    @Override
+                    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                        mAttachedRv = recyclerView;
+                    }
+
+                    @Override
+                    public void onBindViewHolder(TestViewHolder holder,
+                            int position) {
+                        super.onBindViewHolder(holder, position);
+                        RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.itemView
+                                .getLayoutParams();
+                        if (position <= lastFocusableIndex) {
+                            holder.itemView.setFocusable(true);
+                            holder.itemView.setFocusableInTouchMode(true);
+                        } else {
+                            holder.itemView.setFocusable(false);
+                            holder.itemView.setFocusableInTouchMode(false);
+                        }
+                        holder.itemView.setMinimumHeight(mAttachedRv.getHeight() / visibleRowCount);
+                        lp.topMargin = 0;
+                        lp.leftMargin = 0;
+                        lp.rightMargin = 0;
+                        lp.bottomMargin = 0;
+                        if (position == 11) {
+                            lp.topMargin = 9;
+                        }
+                    }
+                });
+
+        /**
+         * 0 1 2
+         * 3 4 5
+         * 6 6 6
+         * 7
+         * 8 8 8
+         * 9 10
+         * 11 11 11
+         * 12 13 14
+         * 15 16 17
+         */
+        mAdapter.mFullSpanItems.add(6);
+        mAdapter.mFullSpanItems.add(8);
+        mAdapter.mFullSpanItems.add(11);
+        waitFirstLayout();
+
+
+        // adapter position of the currently focused item.
+        int focusIndex = 1;
+        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
+                focusIndex);
+        View viewToFocus = toFocus.itemView;
+        assertTrue(requestFocus(viewToFocus, true));
+        assertSame(viewToFocus, mRecyclerView.getFocusedChild());
+
+        // The VH of the unfocusable item that just became fully visible after focusSearch.
+        RecyclerView.ViewHolder toVisible = null;
+
+        View focusedView = viewToFocus;
+        int actualFocusIndex = -1;
+        // First, scroll until the last focusable row.
+        for (int i : new int[]{4, 6}) {
+            focusSearchAndWaitForScroll(focusedView, View.FOCUS_DOWN);
+            focusedView = mRecyclerView.getFocusedChild();
+            actualFocusIndex = mRecyclerView.getChildViewHolder(focusedView).getAdapterPosition();
+            assertEquals("Focused view should be at adapter position " + i + " whereas it's at "
+                    + actualFocusIndex, i, actualFocusIndex);
+        }
+
+        // Further scroll down in order to make the unfocusable rows visible. This process should
+        // continue until the currently focused item is still visible. The focused item should not
+        // change in this loop.
+        for (int i : new int[]{9, 11, 11, 11}) {
+            focusSearchAndWaitForScroll(focusedView, View.FOCUS_DOWN);
+            focusedView = mRecyclerView.getFocusedChild();
+            actualFocusIndex = mRecyclerView.getChildViewHolder(focusedView).getAdapterPosition();
+            toVisible = mRecyclerView.findViewHolderForAdapterPosition(i);
+
+            assertEquals("Focused view should not be changed, whereas it's now at "
+                    + actualFocusIndex, 6, actualFocusIndex);
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(mRecyclerView, focusedView));
+            assertTrue("Child view at adapter pos " + i + " should be fully visible.",
+                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
+        }
+    }
+
+    @Test
+    public void leftUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of columns that can be fully in-bounds of RV.
+        final int visibleColCount = 5;
+        final int spanCount = 3;
+        final int lastFocusableIndex = 6;
+
+        // Reverse layout so that views are placed from right to left.
+        setupByConfig(new Config(HORIZONTAL, true, spanCount,
+                        GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS),
+                new GridTestAdapter(18, 1) {
+                    RecyclerView mAttachedRv;
+
+                    @Override
+                    public TestViewHolder onCreateViewHolder(ViewGroup parent,
+                            int viewType) {
+                        TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                        testViewHolder.itemView.setFocusable(true);
+                        testViewHolder.itemView.setFocusableInTouchMode(true);
+                        // Good to have colors for debugging
+                        StateListDrawable stl = new StateListDrawable();
+                        stl.addState(new int[]{android.R.attr.state_focused},
+                                new ColorDrawable(Color.RED));
+                        stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                        //noinspection deprecation used to support kitkat tests
+                        testViewHolder.itemView.setBackgroundDrawable(stl);
+                        return testViewHolder;
+                    }
+
+                    @Override
+                    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                        mAttachedRv = recyclerView;
+                    }
+
+                    @Override
+                    public void onBindViewHolder(TestViewHolder holder,
+                            int position) {
+                        super.onBindViewHolder(holder, position);
+                        RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.itemView
+                                .getLayoutParams();
+                        if (position <= lastFocusableIndex) {
+                            holder.itemView.setFocusable(true);
+                            holder.itemView.setFocusableInTouchMode(true);
+                        } else {
+                            holder.itemView.setFocusable(false);
+                            holder.itemView.setFocusableInTouchMode(false);
+                        }
+                        holder.itemView.setMinimumWidth(mAttachedRv.getWidth() / visibleColCount);
+                        lp.topMargin = 0;
+                        lp.leftMargin = 0;
+                        lp.rightMargin = 0;
+                        lp.bottomMargin = 0;
+                        if (position == 11) {
+                            lp.rightMargin = 9;
+                        }
+                    }
+                });
+
+        /**
+         * 15 12 11 9  8 7 6 3 0
+         * 16 13 11 10 8   6 4 1
+         * 17 14 11    8   6 5 2
+         */
+        mAdapter.mFullSpanItems.add(6);
+        mAdapter.mFullSpanItems.add(8);
+        mAdapter.mFullSpanItems.add(11);
+        waitFirstLayout();
+
+
+        // adapter position of the currently focused item.
+        int focusIndex = 1;
+        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
+                focusIndex);
+        View viewToFocus = toFocus.itemView;
+        assertTrue(requestFocus(viewToFocus, true));
+        assertSame(viewToFocus, mRecyclerView.getFocusedChild());
+
+        // The VH of the unfocusable item that just became fully visible after focusSearch.
+        RecyclerView.ViewHolder toVisible = null;
+
+        View focusedView = viewToFocus;
+        int actualFocusIndex = -1;
+        // First, scroll until the last focusable column.
+        for (int i : new int[]{4, 6}) {
+            focusSearchAndWaitForScroll(focusedView, View.FOCUS_LEFT);
+            focusedView = mRecyclerView.getFocusedChild();
+            actualFocusIndex = mRecyclerView.getChildViewHolder(focusedView).getAdapterPosition();
+            assertEquals("Focused view should be at adapter position " + i + " whereas it's at "
+                    + actualFocusIndex, i, actualFocusIndex);
+        }
+
+        // Further scroll left in order to make the unfocusable columns visible. This process should
+        // continue until the currently focused item is still visible. The focused item should not
+        // change in this loop.
+        for (int i : new int[]{9, 11, 11, 11}) {
+            focusSearchAndWaitForScroll(focusedView, View.FOCUS_LEFT);
+            focusedView = mRecyclerView.getFocusedChild();
+            actualFocusIndex = mRecyclerView.getChildViewHolder(focusedView).getAdapterPosition();
+            toVisible = mRecyclerView.findViewHolderForAdapterPosition(i);
+
+            assertEquals("Focused view should not be changed, whereas it's now at "
+                    + actualFocusIndex, 6, actualFocusIndex);
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(mRecyclerView, focusedView));
+            assertTrue("Child view at adapter pos " + i + " should be fully visible.",
+                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
+        }
+    }
+
+    @Test
+    public void rightUnfocusableViewsVisibility() throws Throwable {
+        // The maximum number of columns that can be fully in-bounds of RV.
+        final int visibleColCount = 5;
+        final int spanCount = 3;
+        final int lastFocusableIndex = 6;
+
+        setupByConfig(new Config(HORIZONTAL, false, spanCount,
+                        GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS),
+                new GridTestAdapter(18, 1) {
+                    RecyclerView mAttachedRv;
+
+                    @Override
+                    public TestViewHolder onCreateViewHolder(ViewGroup parent,
+                            int viewType) {
+                        TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
+                        testViewHolder.itemView.setFocusable(true);
+                        testViewHolder.itemView.setFocusableInTouchMode(true);
+                        // Good to have colors for debugging
+                        StateListDrawable stl = new StateListDrawable();
+                        stl.addState(new int[]{android.R.attr.state_focused},
+                                new ColorDrawable(Color.RED));
+                        stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
+                        //noinspection deprecation used to support kitkat tests
+                        testViewHolder.itemView.setBackgroundDrawable(stl);
+                        return testViewHolder;
+                    }
+
+                    @Override
+                    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+                        mAttachedRv = recyclerView;
+                    }
+
+                    @Override
+                    public void onBindViewHolder(TestViewHolder holder,
+                            int position) {
+                        super.onBindViewHolder(holder, position);
+                        RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.itemView
+                                .getLayoutParams();
+                        if (position <= lastFocusableIndex) {
+                            holder.itemView.setFocusable(true);
+                            holder.itemView.setFocusableInTouchMode(true);
+                        } else {
+                            holder.itemView.setFocusable(false);
+                            holder.itemView.setFocusableInTouchMode(false);
+                        }
+                        holder.itemView.setMinimumWidth(mAttachedRv.getWidth() / visibleColCount);
+                        lp.topMargin = 0;
+                        lp.leftMargin = 0;
+                        lp.rightMargin = 0;
+                        lp.bottomMargin = 0;
+                        if (position == 11) {
+                            lp.leftMargin = 9;
+                        }
+                    }
+                });
+
+        /**
+         * 0 3 6 7 8 9  11 12 15
+         * 1 4 6   8 10 11 13 16
+         * 2 5 6   8    11 14 17
+         */
+        mAdapter.mFullSpanItems.add(6);
+        mAdapter.mFullSpanItems.add(8);
+        mAdapter.mFullSpanItems.add(11);
+        waitFirstLayout();
+
+
+        // adapter position of the currently focused item.
+        int focusIndex = 1;
+        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
+                focusIndex);
+        View viewToFocus = toFocus.itemView;
+        assertTrue(requestFocus(viewToFocus, true));
+        assertSame(viewToFocus, mRecyclerView.getFocusedChild());
+
+        // The VH of the unfocusable item that just became fully visible after focusSearch.
+        RecyclerView.ViewHolder toVisible = null;
+
+        View focusedView = viewToFocus;
+        int actualFocusIndex = -1;
+        // First, scroll until the last focusable column.
+        for (int i : new int[]{4, 6}) {
+            focusSearchAndWaitForScroll(focusedView, View.FOCUS_RIGHT);
+            focusedView = mRecyclerView.getFocusedChild();
+            actualFocusIndex = mRecyclerView.getChildViewHolder(focusedView).getAdapterPosition();
+            assertEquals("Focused view should be at adapter position " + i + " whereas it's at "
+                    + actualFocusIndex, i, actualFocusIndex);
+        }
+
+        // Further scroll right in order to make the unfocusable rows visible. This process should
+        // continue until the currently focused item is still visible. The focused item should not
+        // change in this loop.
+        for (int i : new int[]{9, 11, 11, 11}) {
+            focusSearchAndWaitForScroll(focusedView, View.FOCUS_RIGHT);
+            focusedView = mRecyclerView.getFocusedChild();
+            actualFocusIndex = mRecyclerView.getChildViewHolder(focusedView).getAdapterPosition();
+            toVisible = mRecyclerView.findViewHolderForAdapterPosition(i);
+
+            assertEquals("Focused view should not be changed, whereas it's now at "
+                    + actualFocusIndex, 6, actualFocusIndex);
+            assertTrue("Focused child should be at least partially visible.",
+                    isViewPartiallyInBound(mRecyclerView, focusedView));
+            assertTrue("Child view at adapter pos " + i + " should be fully visible.",
+                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
+        }
+    }
 
     @Test
     public void scrollToPositionWithPredictive() throws Throwable {
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/ViewBoundsCheckTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/ViewBoundsCheckTest.java
new file mode 100644
index 0000000..c950a78
--- /dev/null
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/ViewBoundsCheckTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.widget;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.view.View;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+@SmallTest
+@RunWith(JUnit4.class)
+public class ViewBoundsCheckTest {
+
+
+    private static final String TAG = "ViewBoundsCheckTest";
+    private Context mContext;
+
+    /** Case #1:
+     * Parent:                    [2.......................8]
+     Views: [-3...-1] [-1...1] [1...3] [3...5] [5...7] [7...9] [9...11] [11...13]
+     */
+    int[] mParentBound1 = {2, 8};
+    int[][] mChildrenBound1 = {{-3, -1}, {-1, 1}, {1, 3}, {3, 5}, {5, 7}, {7, 9}, {9, 11},
+            {11, 13}};
+
+    /** Case #2:
+     * Parent:                  [1...................7]
+     Views: [-3...-1] [-1...1][1...3] [3...5] [5...7] [7...9] [9...11]
+     */
+    int[] mParentBound2 = {1, 7};
+    int[][] mChildrenBound2 = {{-3, -1}, {-1, 1}, {1, 3}, {3, 5}, {5, 7}, {7, 9}, {9, 11}};
+
+    View mParent;
+    View[] mChildren;
+
+    private final ViewBoundsCheck.Callback mBoundCheckCallback =
+            new ViewBoundsCheck.Callback() {
+                @Override
+                public int getChildCount() {
+                    return mChildren.length;
+                }
+
+                @Override
+                public View getParent() {
+                    return mParent;
+                }
+
+                @Override
+                public View getChildAt(int index) {
+                    return mChildren[index];
+                }
+
+                @Override
+                public int getParentStart() {
+                    return mParent.getLeft();
+                }
+
+                @Override
+                public int getParentEnd() {
+                    return mParent.getRight();
+                }
+
+                @Override
+                public int getChildStart(View view) {
+                    return view.getLeft();
+                }
+
+                @Override
+                public int getChildEnd(View view) {
+                    return view.getRight();
+                }
+            };
+
+    ViewBoundsCheck mBoundCheck = new ViewBoundsCheck(mBoundCheckCallback);
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    private void setUpViews(int[] parentBound, int[][] childrenBound) {
+        mParent = new View(mContext);
+        mParent.setLeft(parentBound[0]);
+        mParent.setRight(parentBound[1]);
+        mChildren = new View[childrenBound.length];
+        for (int i = 0; i < childrenBound.length; i++) {
+            mChildren[i] = new View(mContext);
+            mChildren[i].setLeft(childrenBound[i][0]);
+            mChildren[i].setRight(childrenBound[i][1]);
+        }
+    }
+
+    @Test
+    public void preferredFromStart() {
+        setUpViews(mParentBound1, mChildrenBound1);
+        @ViewBoundsCheck.ViewBounds int preferredBoundsFlag = ViewBoundsCheck.FLAG_CVS_GT_PVS
+                | ViewBoundsCheck.FLAG_CVS_EQ_PVS | ViewBoundsCheck.FLAG_CVE_LT_PVE
+                | ViewBoundsCheck.FLAG_CVE_EQ_PVE;
+        @ViewBoundsCheck.ViewBounds int acceptableBoundsFlag = 0;
+        View view = mBoundCheck.findOneViewWithinBoundFlags(0, mChildren.length,
+                preferredBoundsFlag, acceptableBoundsFlag);
+        assertEquals("The first fully visible child from start should be returned", 3,
+                view.getLeft());
+        assertEquals("The first fully visible child from start should be returned", 5,
+                view.getRight());
+    }
+
+    @Test
+    public void preferredFromEnd() {
+        setUpViews(mParentBound1, mChildrenBound1);
+        @ViewBoundsCheck.ViewBounds int preferredBoundsFlag = ViewBoundsCheck.FLAG_CVS_GT_PVS
+                | ViewBoundsCheck.FLAG_CVS_EQ_PVS | ViewBoundsCheck.FLAG_CVE_LT_PVE
+                | ViewBoundsCheck.FLAG_CVE_EQ_PVE;
+        @ViewBoundsCheck.ViewBounds int acceptableBoundsFlag = 0;
+        View view = mBoundCheck.findOneViewWithinBoundFlags(mChildren.length - 1, -1,
+                preferredBoundsFlag, acceptableBoundsFlag);
+        assertEquals("The first fully visible child from end should be returned", 5,
+                view.getLeft());
+        assertEquals("The first fully visible child from end should be returned", 7,
+                view.getRight());
+    }
+
+    @Test
+    public void acceptableFromStart() {
+        setUpViews(mParentBound1, mChildrenBound1);
+        @ViewBoundsCheck.ViewBounds int preferredBoundsFlag = 0;
+        @ViewBoundsCheck.ViewBounds int acceptableBoundsFlag = (ViewBoundsCheck.FLAG_CVS_LT_PVS
+                | ViewBoundsCheck.FLAG_CVE_LT_PVE | ViewBoundsCheck.FLAG_CVE_GT_PVS);
+        View view = mBoundCheck.findOneViewWithinBoundFlags(0, mChildren.length,
+                preferredBoundsFlag, acceptableBoundsFlag);
+        assertEquals("The first partially visible child from start should be returned", 1,
+                view.getLeft());
+        assertEquals("The first partially visible child from start should be returned", 3,
+                view.getRight());
+    }
+
+    @Test
+    public void acceptableFromEnd() {
+        setUpViews(mParentBound1, mChildrenBound1);
+        @ViewBoundsCheck.ViewBounds int preferredBoundsFlag = 0;
+        @ViewBoundsCheck.ViewBounds int acceptableBoundsFlag = (ViewBoundsCheck.FLAG_CVE_GT_PVE
+                | ViewBoundsCheck.FLAG_CVS_GT_PVS | ViewBoundsCheck.FLAG_CVS_LT_PVE);
+        View view = mBoundCheck.findOneViewWithinBoundFlags(mChildren.length - 1, -1,
+                preferredBoundsFlag, acceptableBoundsFlag);
+        assertEquals("The first partially visible child from end should be returned", 7,
+                view.getLeft());
+        assertEquals("The first partially visible child from end should be returned", 9,
+                view.getRight());
+    }
+
+    @Test
+    public void noPreferredFoundAcceptableReturnedFromStart() {
+        setUpViews(mParentBound2, mChildrenBound2);
+        @ViewBoundsCheck.ViewBounds int  preferredBoundsFlag = (ViewBoundsCheck.FLAG_CVS_LT_PVS
+                | ViewBoundsCheck.FLAG_CVE_LT_PVE | ViewBoundsCheck.FLAG_CVE_GT_PVS);
+        @ViewBoundsCheck.ViewBounds int  acceptableBoundsFlag = (ViewBoundsCheck.FLAG_CVS_LT_PVS
+                | ViewBoundsCheck.FLAG_CVE_LT_PVE);
+        View view = mBoundCheck.findOneViewWithinBoundFlags(0, mChildren.length,
+                preferredBoundsFlag, acceptableBoundsFlag);
+        assertEquals("The last fully invisible child from start should be returned", -1,
+                view.getLeft());
+        assertEquals("TThe last fully invisible child from start should be returned", 1,
+                view.getRight());
+    }
+
+    @Test
+    public void noPreferredFoundAcceptableReturnedFromEnd() {
+        setUpViews(mParentBound2, mChildrenBound2);
+        @ViewBoundsCheck.ViewBounds int preferredBoundsFlag = (ViewBoundsCheck.FLAG_CVE_GT_PVE
+                | ViewBoundsCheck.FLAG_CVS_GT_PVS | ViewBoundsCheck.FLAG_CVS_LT_PVE);
+        @ViewBoundsCheck.ViewBounds int acceptableBoundsFlag = (ViewBoundsCheck.FLAG_CVE_GT_PVE
+                | ViewBoundsCheck.FLAG_CVS_GT_PVS);
+        View view = mBoundCheck.findOneViewWithinBoundFlags(mChildren.length - 1, -1,
+                preferredBoundsFlag, acceptableBoundsFlag);
+        assertEquals("The last fully invisible child from end should be returned", 7,
+                view.getLeft());
+        assertEquals("TThe last fully invisible child from end should be returned", 9,
+                view.getRight());
+    }
+
+    @Test
+    public void noViewsFoundWithinGivenBounds() {
+        setUpViews(mParentBound1, mChildrenBound1);
+        // create a view whose bounds cover its parent. Since no such view exist in the example
+        // layout, null should be returned.
+        @ViewBoundsCheck.ViewBounds int preferredBoundsFlag = (ViewBoundsCheck.FLAG_CVS_LT_PVS
+                | ViewBoundsCheck.FLAG_CVE_GT_PVE);
+        @ViewBoundsCheck.ViewBounds int acceptableBoundsFlag = preferredBoundsFlag;
+        View view = mBoundCheck.findOneViewWithinBoundFlags(0, mChildren.length,
+                preferredBoundsFlag, acceptableBoundsFlag);
+        assertNull("Null should be returned since no views are within the given bounds",
+                view);
+    }
+
+}
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/helper/ItemTouchHelperTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/helper/ItemTouchHelperTest.java
index c251c5a..604bf71 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/helper/ItemTouchHelperTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/helper/ItemTouchHelperTest.java
@@ -27,7 +27,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.os.Build;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.test.filters.SdkSuppress;
 import android.support.test.filters.Suppress;
 import android.support.test.runner.AndroidJUnit4;
@@ -44,7 +44,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-@MediumTest
+@LargeTest
 @RunWith(AndroidJUnit4.class)
 public class ItemTouchHelperTest extends BaseRecyclerViewInstrumentationTest {
 
diff --git a/v8/renderscript/Android.mk b/v8/renderscript/Android.mk
deleted file mode 100644
index 8815a0a..0000000
--- a/v8/renderscript/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# Copyright (C) 2012 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.
-#
-
-# Don't build the library in unbundled branches.
-ifeq (,$(TARGET_BUILD_APPS))
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS += -std=c++11
-
-LOCAL_MODULE := android-support-v8-renderscript
-LOCAL_SDK_VERSION := 23
-LOCAL_SRC_FILES := $(call all-java-files-under, java/src)
-LOCAL_SHARED_ANDROID_LIBRARIES := android-support-annotations
-
-LOCAL_JAVA_LANGUAGE_VERSION := 1.7
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# TODO: Build the tests as an APK here
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
-
-endif
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java b/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java
deleted file mode 100644
index 2384518..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java
+++ /dev/null
@@ -1,3032 +0,0 @@
-/*
- * Copyright (C) 2008-2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.util.Log;
-import android.view.Surface;
-
-/**
- * <p> This class provides the primary method through which data is passed to
- * and from RenderScript kernels.  An Allocation provides the backing store for
- * a given {@link android.support.v8.renderscript.Type}.  </p>
- *
- * <p>An Allocation also contains a set of usage flags that denote how the
- * Allocation could be used. For example, an Allocation may have usage flags
- * specifying that it can be used from a script as well as input to a {@link
- * android.support.v8.renderscript.Sampler}. A developer must synchronize
- * across these different usages using
- * {@link android.support.v8.renderscript.Allocation#syncAll} in
- * order to ensure that different users of the Allocation have a consistent view
- * of memory. For example, in the case where an Allocation is used as the output
- * of one kernel and as Sampler input in a later kernel, a developer must call
- * {@link #syncAll syncAll(Allocation.USAGE_SCRIPT)} prior to launching the
- * second kernel to ensure correctness.
- *
- * <p>An Allocation can be populated with the {@link #copyFrom} routines. For
- * more complex Element types, the {@link #copyFromUnchecked} methods can be
- * used to copy from byte arrays or similar constructs.</p>
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses
- * RenderScript, read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
- * developer guide.</p>
- * </div>
- **/
-public class Allocation extends BaseObj {
-    Type mType;
-    Bitmap mBitmap;
-    int mUsage;
-    int mSize;
-    Allocation mAdaptedAllocation;
-    ByteBuffer mByteBuffer = null;
-    long mByteBufferStride = 0;
-
-    boolean mConstrainedLOD;
-    boolean mConstrainedFace;
-    boolean mConstrainedY;
-    boolean mConstrainedZ;
-    boolean mReadAllowed = true;
-    boolean mWriteAllowed = true;
-    boolean mAutoPadding = false;
-    int mSelectedY;
-    int mSelectedZ;
-    int mSelectedLOD;
-    Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
-
-    int mCurrentDimX;
-    int mCurrentDimY;
-    int mCurrentDimZ;
-    int mCurrentCount;
-
-    private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) {
-        final Class c = d.getClass();
-        if (!c.isArray()) {
-            throw new RSIllegalArgumentException("Object passed is not an array of primitives.");
-        }
-        final Class cmp = c.getComponentType();
-        if (!cmp.isPrimitive()) {
-            throw new RSIllegalArgumentException("Object passed is not an Array of primitives.");
-        }
-
-        if (cmp == Long.TYPE) {
-            if (checkType) {
-                validateIsInt64();
-                return mType.mElement.mType;
-            }
-            return Element.DataType.SIGNED_64;
-        }
-
-        if (cmp == Integer.TYPE) {
-            if (checkType) {
-                validateIsInt32();
-                return mType.mElement.mType;
-            }
-            return Element.DataType.SIGNED_32;
-        }
-
-        if (cmp == Short.TYPE) {
-            if (checkType) {
-                validateIsInt16();
-                return mType.mElement.mType;
-            }
-            return Element.DataType.SIGNED_16;
-        }
-
-        if (cmp == Byte.TYPE) {
-            if (checkType) {
-                validateIsInt8();
-                return mType.mElement.mType;
-            }
-            return Element.DataType.SIGNED_8;
-        }
-
-        if (cmp == Float.TYPE) {
-            if (checkType) {
-                validateIsFloat32();
-            }
-            return Element.DataType.FLOAT_32;
-        }
-
-        if (cmp == Double.TYPE) {
-            if (checkType) {
-                validateIsFloat64();
-            }
-            return Element.DataType.FLOAT_64;
-        }
-        return null;
-    }
-
-    /*
-     * Hold reference to the shared allocation in compat context
-     * for Incremental Support Lib.
-     */
-    long mIncCompatAllocation;
-    boolean mIncAllocDestroyed;
-    /**
-     * The usage of the Allocation.  These signal to RenderScript where to place
-     * the Allocation in memory.
-     *
-     */
-
-    /**
-     * The Allocation will be bound to and accessed by scripts.
-     */
-    public static final int USAGE_SCRIPT = 0x0001;
-
-    /**
-     * The Allocation will be used as a texture source by one or more graphics
-     * programs.
-     *
-     */
-    public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
-
-    /**
-     * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
-     * consumer.  This usage will cause the Allocation to be created as
-     * read-only.
-     *
-     */
-    public static final int USAGE_IO_INPUT = 0x0020;
-
-    /**
-     * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
-     * producer.  The dimensions and format of the {@link
-     * android.graphics.SurfaceTexture} will be forced to those of the
-     * Allocation.
-     *
-     */
-    public static final int USAGE_IO_OUTPUT = 0x0040;
-
-    /**
-     * The Allocation's backing store will be inherited from another object
-     * (usually a {@link android.graphics.Bitmap}); copying to or from the
-     * original source Bitmap will cause a synchronization rather than a full
-     * copy.  {@link #syncAll} may also be used to synchronize the Allocation
-     * and the source Bitmap.
-     *
-     * <p>This is set by default for allocations created with {@link
-     * #createFromBitmap} in API version 18 and higher.</p>
-     *
-     */
-    public static final int USAGE_SHARED = 0x0080;
-
-    /**
-     * Controls mipmap behavior when using the bitmap creation and update
-     * functions.
-     */
-    public enum MipmapControl {
-        /**
-         * No mipmaps will be generated and the type generated from the incoming
-         * bitmap will not contain additional LODs.
-         */
-        MIPMAP_NONE(0),
-
-        /**
-         * A full mipmap chain will be created in script memory.  The Type of
-         * the Allocation will contain a full mipmap chain.  On upload, the full
-         * chain will be transferred.
-         */
-        MIPMAP_FULL(1),
-
-        /**
-         * The Type of the Allocation will be the same as MIPMAP_NONE.  It will
-         * not contain mipmaps.  On upload, the allocation data will contain a
-         * full mipmap chain generated from the top level in script memory.
-         */
-        MIPMAP_ON_SYNC_TO_TEXTURE(2);
-
-        int mID;
-        MipmapControl(int id) {
-            mID = id;
-        }
-    }
-
-    /**
-     * Getter & Setter for the dummy allocation for Inc Support Lib.
-     *
-     */
-    public long getIncAllocID() {
-        return mIncCompatAllocation;
-    }
-    public void setIncAllocID(long id) {
-        mIncCompatAllocation = id;
-    }
-
-    private long getIDSafe() {
-        if (mAdaptedAllocation != null) {
-            return mAdaptedAllocation.getID(mRS);
-        }
-        return getID(mRS);
-    }
-
-
-   /**
-     * Get the {@link android.support.v8.renderscript.Element} of the {@link
-     * android.support.v8.renderscript.Type} of the Allocation.
-     *
-     * @return Element
-     *
-     */
-    public Element getElement() {
-        return mType.getElement();
-    }
-
-    /**
-     * Get the usage flags of the Allocation.
-     *
-     * @return usage this Allocation's set of the USAGE_* flags OR'd together
-     *
-     */
-    public int getUsage() {
-        return mUsage;
-    }
-
-    /**
-     * Specifies the mapping between the Allocation's cells and an array's elements
-     * when data is copied from the Allocation to the array, or vice-versa.
-     *
-     * Only applies to an Allocation whose Element is a vector of length 3 (such as
-     * {@link Element#U8_3} or {@link Element#RGB_888}). Enabling this feature may make
-     * copying data from the Allocation to an array or vice-versa less efficient.
-     *
-     * <p> Vec3 Element cells are stored in an Allocation as Vec4 Element cells with
-     * the same {@link android.support.v8.renderscript.Element.DataType}, with the fourth vector
-     * component treated as padding. When this feature is enabled, only the data components,
-     * i.e. the first 3 vector components of each cell, will be mapped between the array
-     * and the Allocation. When disabled, explicit mapping of the padding components
-     * is required, as described in the following example.
-     *
-     * <p> For example, when copying an integer array to an Allocation of two {@link
-     * Element#I32_3} cells using {@link #copyFrom(int[])}:
-     * <p> When disabled:
-     *     The array must have at least 8 integers, with the first 4 integers copied
-     *     to the first cell of the Allocation, and the next 4 integers copied to
-     *     the second cell. The 4th and 8th integers are mapped as the padding components.
-     *
-     * <p> When enabled:
-     *     The array just needs to have at least 6 integers, with the first 3 integers
-     *     copied to the the first cell as data components, and the next 3 copied to
-     *     the second cell. There is no mapping for the padding components.
-     *
-     * <p> Similarly, when copying a byte array to an Allocation of two {@link
-     * Element#I32_3} cells, using {@link #copyFromUnchecked(int[])}:
-     * <p> When disabled:
-     *     The array must have at least 32 bytes, with the first 16 bytes copied
-     *     to the first cell of the Allocation, and the next 16 bytes copied to
-     *     the second cell. The 13th-16th and 29th-32nd bytes are mapped as padding
-     *     components.
-     *
-     * <p> When enabled:
-     *     The array just needs to have at least 24 bytes, with the first 12 bytes copied
-     *     to the first cell of the Allocation, and the next 12 bytes copied to
-     *     the second cell. There is no mapping for the padding components.
-     *
-     * <p> Similar to copying data to an Allocation from an array, when copying data from an
-     * Allocation to an array, the padding components for Vec3 Element cells will not be
-     * copied/mapped to the array if AutoPadding is enabled.
-     *
-     * <p> Default: Disabled.
-     *
-     * @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding
-     *
-     */
-    public void setAutoPadding(boolean useAutoPadding) {
-        mAutoPadding = useAutoPadding;
-    }
-
-    /**
-     * Get the size of the Allocation in bytes.
-     *
-     * @return size of the Allocation in bytes.
-     *
-     */
-    public int getBytesSize() {
-        if (mType.mDimYuv != 0) {
-            return (int)Math.ceil(mType.getCount() * mType.getElement().getBytesSize() * 1.5);
-        }
-        return mType.getCount() * mType.getElement().getBytesSize();
-    }
-
-    private void updateCacheInfo(Type t) {
-        mCurrentDimX = t.getX();
-        mCurrentDimY = t.getY();
-        mCurrentDimZ = t.getZ();
-        mCurrentCount = mCurrentDimX;
-        if (mCurrentDimY > 1) {
-            mCurrentCount *= mCurrentDimY;
-        }
-        if (mCurrentDimZ > 1) {
-            mCurrentCount *= mCurrentDimZ;
-        }
-    }
-
-    private void setBitmap(Bitmap b) {
-        mBitmap = b;
-    }
-
-    Allocation(long id, RenderScript rs, Type t, int usage) {
-        super(id, rs);
-        if ((usage & ~(USAGE_SCRIPT |
-                       USAGE_GRAPHICS_TEXTURE |
-                       USAGE_IO_INPUT |
-                       USAGE_IO_OUTPUT |
-                       USAGE_SHARED)) != 0) {
-            throw new RSIllegalArgumentException("Unknown usage specified.");
-        }
-
-        if ((usage & USAGE_IO_INPUT) != 0) {
-            mWriteAllowed = false;
-
-            if ((usage & ~(USAGE_IO_INPUT |
-                           USAGE_GRAPHICS_TEXTURE |
-                           USAGE_SCRIPT)) != 0) {
-                throw new RSIllegalArgumentException("Invalid usage combination.");
-            }
-        }
-
-        mType = t;
-        mUsage = usage;
-        mIncCompatAllocation = 0;
-        mIncAllocDestroyed = false;
-
-        if (t != null) {
-            // TODO: A3D doesn't have Type info during creation, so we can't
-            // calculate the size ahead of time. We can possibly add a method
-            // to update the size in the future if it seems reasonable.
-            mSize = mType.getCount() * mType.getElement().getBytesSize();
-            updateCacheInfo(t);
-        }
-        if (RenderScript.sUseGCHooks == true) {
-            try {
-                RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize);
-            } catch (Exception e) {
-                Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
-                throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
-            }
-        }
-    }
-
-    protected void finalize() throws Throwable {
-        if (RenderScript.sUseGCHooks == true) {
-            RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
-        }
-        super.finalize();
-    }
-
-    private void validateIsInt64() {
-        if ((mType.mElement.mType == Element.DataType.SIGNED_64) ||
-            (mType.mElement.mType == Element.DataType.UNSIGNED_64)) {
-            return;
-        }
-        throw new RSIllegalArgumentException(
-            "64 bit integer source does not match allocation type " + mType.mElement.mType);
-    }
-
-    private void validateIsInt32() {
-        if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
-            (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
-            return;
-        }
-        throw new RSIllegalArgumentException(
-            "32 bit integer source does not match allocation type " + mType.mElement.mType);
-    }
-
-    private void validateIsInt16() {
-        if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
-            (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
-            return;
-        }
-        throw new RSIllegalArgumentException(
-            "16 bit integer source does not match allocation type " + mType.mElement.mType);
-    }
-
-    private void validateIsInt8() {
-        if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
-            (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
-            return;
-        }
-        throw new RSIllegalArgumentException(
-            "8 bit integer source does not match allocation type " + mType.mElement.mType);
-    }
-
-    private void validateIsFloat32() {
-        if (mType.mElement.mType == Element.DataType.FLOAT_32) {
-            return;
-        }
-        throw new RSIllegalArgumentException(
-            "32 bit float source does not match allocation type " + mType.mElement.mType);
-    }
-
-    private void validateIsFloat64() {
-        if (mType.mElement.mType == Element.DataType.FLOAT_64) {
-            return;
-        }
-        throw new RSIllegalArgumentException(
-            "64 bit float source does not match allocation type " + mType.mElement.mType);
-    }
-
-    private void validateIsObject() {
-        if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
-            (mType.mElement.mType == Element.DataType.RS_TYPE) ||
-            (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
-            (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
-            (mType.mElement.mType == Element.DataType.RS_SCRIPT)) {
-            return;
-        }
-        throw new RSIllegalArgumentException(
-            "Object source does not match allocation type " + mType.mElement.mType);
-    }
-
-    /**
-     * Get the {@link android.support.v8.renderscript.Type} of the Allocation.
-     *
-     * @return Type
-     *
-     */
-    public Type getType() {
-        return mType;
-    }
-
-    /**
-     * Propagate changes from one usage of the Allocation to the
-     * other usages of the Allocation.
-     *
-     */
-    public void syncAll(int srcLocation) {
-        switch (srcLocation) {
-        case USAGE_SCRIPT:
-        case USAGE_GRAPHICS_TEXTURE:
-            break;
-        default:
-            throw new RSIllegalArgumentException("Source must be exactly one usage type.");
-        }
-        mRS.validate();
-        mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
-    }
-
-    /**
-     * Send a buffer to the output stream.  The contents of the Allocation will
-     * be undefined after this operation. This operation is only valid if {@link
-     * #USAGE_IO_OUTPUT} is set on the Allocation.
-     *
-     *
-     */
-    public void ioSend() {
-        if ((mUsage & USAGE_IO_OUTPUT) == 0) {
-            throw new RSIllegalArgumentException(
-                "Can only send buffer if IO_OUTPUT usage specified.");
-        }
-        mRS.validate();
-        mRS.nAllocationIoSend(getID(mRS));
-    }
-
-    /**
-     * Delete once code is updated.
-     */
-    public void ioSendOutput() {
-        ioSend();
-    }
-    /**
-     * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
-     * <p> If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
-     * would contain the up-to-date data as READ ONLY.
-     * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
-     * the Allocation has certain alignment. The size of each row including padding,
-     * called stride, can be queried using the {@link #getStride()} method.
-     *
-     * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
-     *       The ByteBuffer will be Read-Only for devices before Lollopop (API 21).
-     *
-     * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
-     */
-    public ByteBuffer getByteBuffer() {
-        int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
-        // When running on devices before L, we need to construct the ByteBuffer
-        // and explicitly copy the data from the allocation to it.
-        if (mRS.getDispatchAPILevel() < 21) {
-            byte[] data = null;
-            if (mType.getZ() > 0) {
-                // TODO: add support for 3D allocations.
-                return null;
-            } else if (mType.getY() > 0) {
-                // 2D Allocation
-                data = new byte[xBytesSize * mType.getY()];
-                copy2DRangeToUnchecked(0, 0, mType.getX(), mType.getY(), data,
-                                       Element.DataType.SIGNED_8, xBytesSize * mType.getY());
-            } else {
-                // 1D Allocation
-                data = new byte[xBytesSize];
-                copy1DRangeToUnchecked(0, mType.getX(), data);
-            }
-            ByteBuffer bBuffer = ByteBuffer.wrap(data).asReadOnlyBuffer();
-            mByteBufferStride = xBytesSize;
-            return bBuffer;
-        }
-        // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
-        if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
-            mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), xBytesSize, mType.getY(), mType.getZ());
-        }
-        return mByteBuffer;
-    }
-
-    /**
-     * Gets the stride of the Allocation.
-     * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
-     * the Allocation has certain alignment. The size of each row including such
-     * padding is called stride.
-     *
-     * @return the stride. For 1D Allocation, the stride will be the number of
-     *         bytes of this Allocation. For 2D and 3D Allocations, the stride
-     *         will be the stride in X dimension measuring in bytes.
-     */
-    public long getStride() {
-        if (mByteBufferStride ==0) {
-            if (mRS.getDispatchAPILevel() > 21) {
-                mByteBufferStride = mRS.nAllocationGetStride(getID(mRS));
-            } else {
-                mByteBufferStride = mType.getX() * mType.getElement().getBytesSize();
-            }
-        }
-        return mByteBufferStride;
-    }
-
-    /**
-     * Receive the latest input into the Allocation. This operation
-     * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
-     *
-     */
-    public void ioReceive() {
-        if ((mUsage & USAGE_IO_INPUT) == 0) {
-            throw new RSIllegalArgumentException(
-                "Can only receive if IO_INPUT usage specified.");
-        }
-        mRS.validate();
-        mRS.nAllocationIoReceive(getID(mRS));
-    }
-
-    /**
-     * Copy an array of RS objects to the Allocation.
-     *
-     * @param d Source array.
-     */
-    public void copyFrom(BaseObj[] d) {
-        mRS.validate();
-        validateIsObject();
-        if (d.length != mCurrentCount) {
-            throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
-                                                 mCurrentCount + ", array length = " + d.length);
-        }
-
-        if (RenderScript.sPointerSize == 8) {
-            long i[] = new long[d.length * 4];
-            for (int ct=0; ct < d.length; ct++) {
-                i[ct * 4] = d[ct].getID(mRS);
-            }
-            copy1DRangeFromUnchecked(0, mCurrentCount, i);
-        } else {
-            int i[] = new int[d.length];
-            for (int ct=0; ct < d.length; ct++) {
-                i[ct] = (int)d[ct].getID(mRS);
-            }
-            copy1DRangeFromUnchecked(0, mCurrentCount, i);
-        }
-    }
-
-    private void validateBitmapFormat(Bitmap b) {
-        Bitmap.Config bc = b.getConfig();
-        if (bc == null) {
-            throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
-        }
-        switch (bc) {
-        case ALPHA_8:
-            if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
-                throw new RSIllegalArgumentException("Allocation kind is " +
-                                                     mType.getElement().mKind + ", type " +
-                                                     mType.getElement().mType +
-                                                     " of " + mType.getElement().getBytesSize() +
-                                                     " bytes, passed bitmap was " + bc);
-            }
-            break;
-        case ARGB_8888:
-            if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
-                (mType.getElement().getBytesSize() != 4)) {
-                throw new RSIllegalArgumentException("Allocation kind is " +
-                                                     mType.getElement().mKind + ", type " +
-                                                     mType.getElement().mType +
-                                                     " of " + mType.getElement().getBytesSize() +
-                                                     " bytes, passed bitmap was " + bc);
-            }
-            break;
-        case RGB_565:
-            if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
-                (mType.getElement().getBytesSize() != 2)) {
-                throw new RSIllegalArgumentException("Allocation kind is " +
-                                                     mType.getElement().mKind + ", type " +
-                                                     mType.getElement().mType +
-                                                     " of " + mType.getElement().getBytesSize() +
-                                                     " bytes, passed bitmap was " + bc);
-            }
-            break;
-        case ARGB_4444:
-            if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
-                (mType.getElement().getBytesSize() != 2)) {
-                throw new RSIllegalArgumentException("Allocation kind is " +
-                                                     mType.getElement().mKind + ", type " +
-                                                     mType.getElement().mType +
-                                                     " of " + mType.getElement().getBytesSize() +
-                                                     " bytes, passed bitmap was " + bc);
-            }
-            break;
-
-        }
-    }
-
-    private void validateBitmapSize(Bitmap b) {
-        if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
-            throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
-        }
-    }
-
-    private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
-        mRS.validate();
-        if (mCurrentDimZ > 0) {
-            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
-        } else if (mCurrentDimY > 0) {
-            copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
-        } else {
-            copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
-        }
-    }
-
-    /**
-     * Copy into this Allocation from an array. This method does not guarantee
-     * that the Allocation is compatible with the input buffer; it copies memory
-     * without reinterpretation.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param array The source array
-     */
-    public void copyFromUnchecked(Object array) {
-        copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
-                          java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy into this Allocation from an array. This method does not guarantee
-     * that the Allocation is compatible with the input buffer; it copies memory
-     * without reinterpretation.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d the source array
-     */
-    public void copyFromUnchecked(int[] d) {
-        copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
-    }
-
-    /**
-     * Copy into this Allocation from an array. This method does not guarantee
-     * that the Allocation is compatible with the input buffer; it copies memory
-     * without reinterpretation.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d the source array
-     */
-    public void copyFromUnchecked(short[] d) {
-        copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
-    }
-
-    /**
-     * Copy into this Allocation from an array. This method does not guarantee
-     * that the Allocation is compatible with the input buffer; it copies memory
-     * without reinterpretation.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d the source array
-     */
-    public void copyFromUnchecked(byte[] d) {
-        copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
-    }
-
-    /**
-     * Copy into this Allocation from an array. This method does not guarantee
-     * that the Allocation is compatible with the input buffer; it copies memory
-     * without reinterpretation.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d the source array
-     */
-    public void copyFromUnchecked(float[] d) {
-        copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
-    }
-
-
-    /**
-     * Copy into this Allocation from an array.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} does not match the array's
-     * primitive type.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param array The source array
-     */
-    public void copyFrom(Object array) {
-        copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
-                          java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy into this Allocation from an array.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d the source array
-     */
-    public void copyFrom(int[] d) {
-        validateIsInt32();
-        copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
-    }
-
-    /**
-     * Copy into this Allocation from an array.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d the source array
-     */
-    public void copyFrom(short[] d) {
-        validateIsInt16();
-        copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
-    }
-
-    /**
-     * Copy into this Allocation from an array.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d the source array
-     */
-    public void copyFrom(byte[] d) {
-        validateIsInt8();
-        copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
-    }
-
-    /**
-     * Copy into this Allocation from an array.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is neither a 32 bit float nor a vector of
-     * 32 bit floats {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d the source array
-     */
-    public void copyFrom(float[] d) {
-        validateIsFloat32();
-        copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
-    }
-
-    /**
-     * Copy into an Allocation from a {@link android.graphics.Bitmap}.  The
-     * height, width, and format of the bitmap must match the existing
-     * allocation.
-     *
-     * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
-     * android.graphics.Bitmap} used to create the Allocation with {@link
-     * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
-     * this will synchronize the Allocation with the latest data from the {@link
-     * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
-     *
-     * @param b the source bitmap
-     */
-    public void copyFrom(Bitmap b) {
-        mRS.validate();
-        if (b.getConfig() == null) {
-            Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
-            Canvas c = new Canvas(newBitmap);
-            c.drawBitmap(b, 0, 0, null);
-            copyFrom(newBitmap);
-            return;
-        }
-        validateBitmapSize(b);
-        validateBitmapFormat(b);
-        mRS.nAllocationCopyFromBitmap(getID(mRS), b);
-    }
-
-    /**
-     * Copy an Allocation from an Allocation.  The types of both allocations
-     * must be identical.
-     *
-     * @param a the source allocation
-     */
-    public void copyFrom(Allocation a) {
-        mRS.validate();
-        if (!mType.equals(a.getType())) {
-            throw new RSIllegalArgumentException("Types of allocations must match.");
-        }
-        copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
-    }
-
-
-    /**
-     * This is only intended to be used by auto-generated code reflected from
-     * the RenderScript script files and should not be used by developers.
-     *
-     * @param xoff
-     * @param fp
-     */
-    public void setFromFieldPacker(int xoff, FieldPacker fp) {
-        mRS.validate();
-        int eSize = mType.mElement.getBytesSize();
-        final byte[] data = fp.getData();
-        int data_length = fp.getPos();
-
-        int count = data_length / eSize;
-        if ((eSize * count) != data_length) {
-            throw new RSIllegalArgumentException("Field packer length " + data_length +
-                                               " not divisible by element size " + eSize + ".");
-        }
-        copy1DRangeFromUnchecked(xoff, count, data);
-    }
-
-    /**
-     * This is only intended to be used by auto-generated code reflected from
-     * the RenderScript script files.
-     *
-     * @param xoff
-     * @param component_number
-     * @param fp
-     */
-    public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
-        mRS.validate();
-        if (component_number >= mType.mElement.mElements.length) {
-            throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
-        }
-        if(xoff < 0) {
-            throw new RSIllegalArgumentException("Offset must be >= 0.");
-        }
-
-        final byte[] data = fp.getData();
-        int data_length = fp.getPos();
-        int eSize = mType.mElement.mElements[component_number].getBytesSize();
-        eSize *= mType.mElement.mArraySizes[component_number];
-
-        if (data_length != eSize) {
-            throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
-                                               " does not match component size " + eSize + ".");
-        }
-
-        mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
-                                     component_number, data, data_length);
-    }
-
-    /**
-     * @hide
-     * This is only intended to be used by auto-generated code reflected from
-     * the RenderScript script files.
-     *
-     * @param xoff
-     * @param yoff
-     * @param zoff
-     * @param component_number
-     * @param fp
-     */
-    /*
-    public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
-        mRS.validate();
-        if (component_number >= mType.mElement.mElements.length) {
-            throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
-        }
-        if(xoff < 0) {
-            throw new RSIllegalArgumentException("Offset x must be >= 0.");
-        }
-        if(yoff < 0) {
-            throw new RSIllegalArgumentException("Offset y must be >= 0.");
-        }
-        if(zoff < 0) {
-            throw new RSIllegalArgumentException("Offset z must be >= 0.");
-        }
-
-        final byte[] data = fp.getData();
-        int data_length = fp.getPos();
-        int eSize = mType.mElement.mElements[component_number].getBytesSize();
-        eSize *= mType.mElement.mArraySizes[component_number];
-
-        if (data_length != eSize) {
-            throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
-                                               " does not match component size " + eSize + ".");
-        }
-
-        mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
-                                   component_number, data, data_length);
-    }
-    */
-
-    private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) {
-        mRS.validate();
-        if(off < 0) {
-            throw new RSIllegalArgumentException("Offset must be >= 0.");
-        }
-        if(count < 1) {
-            throw new RSIllegalArgumentException("Count must be >= 1.");
-        }
-        if((off + count) > mCurrentCount) {
-            throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
-                                               ", got " + count + " at offset " + off + ".");
-        }
-        if(usePadding) {
-            if(len < dataSize / 4 * 3) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-        } else {
-            if(len < dataSize) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-        }
-    }
-
-    /**
-     * Generate a mipmap chain. This is only valid if the Type of the Allocation
-     * includes mipmaps.
-     *
-     * <p>This function will generate a complete set of mipmaps from the top
-     * level LOD and place them into the script memory space.</p>
-     *
-     * <p>If the Allocation is also using other memory spaces, a call to {@link
-     * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
-     */
-    public void generateMipmaps() {
-        mRS.nAllocationGenerateMipmaps(getID(mRS));
-    }
-
-    private void copy1DRangeFromUnchecked(int off, int count, Object array,
-                                          Element.DataType dt, int arrayLen) {
-        final int dataSize = mType.mElement.getBytesSize() * count;
-        // AutoPadding for Vec3 Element
-        boolean usePadding = false;
-        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
-            usePadding = true;
-        }
-        data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
-        mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
-                              mType.mElement.mType.mSize, usePadding);
-    }
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param array The source array
-     */
-    public void copy1DRangeFromUnchecked(int off, int count, Object array) {
-        copy1DRangeFromUnchecked(off, count, array,
-                                 validateObjectIsPrimitiveArray(array, false),
-                                 java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
-        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
-    }
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
-        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
-    }
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
-        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
-    }
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
-        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
-    }
-
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} does not match the component type
-     * of the array passed in.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param array The source array.
-     */
-    public void copy1DRangeFrom(int off, int count, Object array) {
-        copy1DRangeFromUnchecked(off, count, array,
-                                 validateObjectIsPrimitiveArray(array, true),
-                                 java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not an 32 bit integer nor a vector of 32 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeFrom(int off, int count, int[] d) {
-        validateIsInt32();
-        copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
-    }
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not an 16 bit integer nor a vector of 16 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeFrom(int off, int count, short[] d) {
-        validateIsInt16();
-        copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
-    }
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeFrom(int off, int count, byte[] d) {
-        validateIsInt8();
-        copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
-    }
-
-    /**
-     * Copy an array into a 1D region of this Allocation.  This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is neither a 32 bit float nor a vector of
-     * 32 bit floats {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array.
-     */
-    public void copy1DRangeFrom(int off, int count, float[] d) {
-        validateIsFloat32();
-        copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
-    }
-
-     /**
-     * Copy part of an Allocation into this Allocation.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param data the source data allocation.
-     * @param dataOff off The offset of the first element in data to
-     *          be copied.
-     */
-    public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
-        mRS.nAllocationData2D(getIDSafe(), off, 0,
-                              mSelectedLOD, mSelectedFace.mID,
-                              count, 1, data.getID(mRS), dataOff, 0,
-                              data.mSelectedLOD, data.mSelectedFace.mID);
-    }
-
-    private void validate2DRange(int xoff, int yoff, int w, int h) {
-        if (mAdaptedAllocation != null) {
-
-        } else {
-
-            if (xoff < 0 || yoff < 0) {
-                throw new RSIllegalArgumentException("Offset cannot be negative.");
-            }
-            if (h < 0 || w < 0) {
-                throw new RSIllegalArgumentException("Height or width cannot be negative.");
-            }
-            if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
-                throw new RSIllegalArgumentException("Updated region larger than allocation.");
-            }
-        }
-    }
-
-    void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
-                                  Element.DataType dt, int arrayLen) {
-        mRS.validate();
-        validate2DRange(xoff, yoff, w, h);
-        final int dataSize = mType.mElement.getBytesSize() * w * h;
-        // AutoPadding for Vec3 Element
-        boolean usePadding = false;
-        int sizeBytes = arrayLen * dt.mSize;
-        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
-            if (dataSize / 4 * 3 > sizeBytes) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-            usePadding = true;
-            sizeBytes = dataSize;
-        } else {
-            if (dataSize > sizeBytes) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-        }
-        mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
-                              array, sizeBytes, dt,
-                              mType.mElement.mType.mSize, usePadding);
-    }
-
-    /**
-     * Copy from an array into a rectangular region in this Allocation.  The
-     * array is assumed to be tightly packed. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} does not match the input data type.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to update in this Allocation
-     * @param yoff Y offset of the region to update in this Allocation
-     * @param w Width of the region to update
-     * @param h Height of the region to update
-     * @param array Data to be placed into the Allocation
-     */
-    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
-        copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
-                                 validateObjectIsPrimitiveArray(array, true),
-                                 java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy from an array into a rectangular region in this Allocation.  The
-     * array is assumed to be tightly packed. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to update in this Allocation
-     * @param yoff Y offset of the region to update in this Allocation
-     * @param w Width of the region to update
-     * @param h Height of the region to update
-     * @param data to be placed into the Allocation
-     */
-    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
-        validateIsInt8();
-        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
-                                 Element.DataType.SIGNED_8, data.length);
-    }
-
-    /**
-     * Copy from an array into a rectangular region in this Allocation.  The
-     * array is assumed to be tightly packed. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to update in this Allocation
-     * @param yoff Y offset of the region to update in this Allocation
-     * @param w Width of the region to update
-     * @param h Height of the region to update
-     * @param data to be placed into the Allocation
-     */
-    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
-        validateIsInt16();
-        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
-                                 Element.DataType.SIGNED_16, data.length);
-    }
-
-    /**
-     * Copy from an array into a rectangular region in this Allocation.  The
-     * array is assumed to be tightly packed. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to update in this Allocation
-     * @param yoff Y offset of the region to update in this Allocation
-     * @param w Width of the region to update
-     * @param h Height of the region to update
-     * @param data to be placed into the Allocation
-     */
-    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
-        validateIsInt32();
-        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
-                                 Element.DataType.SIGNED_32, data.length);
-    }
-
-    /**
-     * Copy from an array into a rectangular region in this Allocation.  The
-     * array is assumed to be tightly packed. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is neither a 32 bit float nor a vector of
-     * 32 bit floats {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to update in this Allocation
-     * @param yoff Y offset of the region to update in this Allocation
-     * @param w Width of the region to update
-     * @param h Height of the region to update
-     * @param data to be placed into the Allocation
-     */
-    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
-        validateIsFloat32();
-        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
-                                 Element.DataType.FLOAT_32, data.length);
-    }
-
-    /**
-     * Copy a rectangular region from an Allocation into a rectangular region in
-     * this Allocation.
-     *
-     * @param xoff X offset of the region in this Allocation
-     * @param yoff Y offset of the region in this Allocation
-     * @param w Width of the region to update.
-     * @param h Height of the region to update.
-     * @param data source Allocation.
-     * @param dataXoff X offset in source Allocation
-     * @param dataYoff Y offset in source Allocation
-     */
-    public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
-                                Allocation data, int dataXoff, int dataYoff) {
-        mRS.validate();
-        validate2DRange(xoff, yoff, w, h);
-        mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
-                              mSelectedLOD, mSelectedFace.mID,
-                              w, h, data.getID(mRS), dataXoff, dataYoff,
-                              data.mSelectedLOD, data.mSelectedFace.mID);
-    }
-
-    /**
-     * Copy a {@link android.graphics.Bitmap} into an Allocation.  The height
-     * and width of the update will use the height and width of the {@link
-     * android.graphics.Bitmap}.
-     *
-     * @param xoff X offset of the region to update in this Allocation
-     * @param yoff Y offset of the region to update in this Allocation
-     * @param data the Bitmap to be copied
-     */
-    public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
-        mRS.validate();
-        if (data.getConfig() == null) {
-            Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
-            Canvas c = new Canvas(newBitmap);
-            c.drawBitmap(data, 0, 0, null);
-            copy2DRangeFrom(xoff, yoff, newBitmap);
-            return;
-        }
-        validateBitmapFormat(data);
-        validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
-        mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
-    }
-
-    private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
-        if (mAdaptedAllocation != null) {
-
-        } else {
-
-            if (xoff < 0 || yoff < 0 || zoff < 0) {
-                throw new RSIllegalArgumentException("Offset cannot be negative.");
-            }
-            if (h < 0 || w < 0 || d < 0) {
-                throw new RSIllegalArgumentException("Height or width cannot be negative.");
-            }
-            if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
-                throw new RSIllegalArgumentException("Updated region larger than allocation.");
-            }
-        }
-    }
-
-    /**
-     * Copy a rectangular region from the array into the allocation.
-     * The array is assumed to be tightly packed.
-     *
-     * The data type of the array is not required to be the same as
-     * the element data type.
-     */
-    private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
-                                          Object array, Element.DataType dt, int arrayLen) {
-        mRS.validate();
-        validate3DRange(xoff, yoff, zoff, w, h, d);
-        final int dataSize = mType.mElement.getBytesSize() * w * h * d;
-        // AutoPadding for Vec3 Element
-        boolean usePadding = false;
-        int sizeBytes = arrayLen * dt.mSize;
-        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
-            if (dataSize / 4 * 3 > sizeBytes) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-            usePadding = true;
-            sizeBytes = dataSize;
-        } else {
-            if (dataSize > sizeBytes) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-        }
-        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
-                              array, sizeBytes, dt,
-                              mType.mElement.mType.mSize, usePadding);
-    }
-
-    /**
-     * Copy from an array into a 3D region in this Allocation.  The
-     * array is assumed to be tightly packed. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} does not match the input data type.
-     *
-     * <p> The size of the region is: w * h * d * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to update in this Allocation
-     * @param yoff Y offset of the region to update in this Allocation
-     * @param zoff Z offset of the region to update in this Allocation
-     * @param w Width of the region to update
-     * @param h Height of the region to update
-     * @param d Depth of the region to update
-     * @param array to be placed into the allocation
-     */
-    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
-        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
-                                 validateObjectIsPrimitiveArray(array, true),
-                                 java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy a rectangular region into the allocation from another
-     * allocation.
-     *
-     * @param xoff X offset of the region to update in this Allocation
-     * @param yoff Y offset of the region to update in this Allocation
-     * @param zoff Z offset of the region to update in this Allocation
-     * @param w Width of the region to update.
-     * @param h Height of the region to update.
-     * @param d Depth of the region to update.
-     * @param data source allocation.
-     * @param dataXoff X offset of the region in the source Allocation
-     * @param dataYoff Y offset of the region in the source Allocation
-     * @param dataZoff Z offset of the region in the source Allocation
-     */
-    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
-                                Allocation data, int dataXoff, int dataYoff, int dataZoff) {
-        mRS.validate();
-        validate3DRange(xoff, yoff, zoff, w, h, d);
-        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
-                              w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
-                              data.mSelectedLOD);
-    }
-
-
-    /**
-     * Copy from the Allocation into a {@link android.graphics.Bitmap}.  The
-     * bitmap must match the dimensions of the Allocation.
-     *
-     * @param b The bitmap to be set from the Allocation.
-     */
-    public void copyTo(Bitmap b) {
-        mRS.validate();
-        validateBitmapFormat(b);
-        validateBitmapSize(b);
-        mRS.nAllocationCopyToBitmap(getID(mRS), b);
-    }
-
-    private void copyTo(Object array, Element.DataType dt, int arrayLen) {
-        mRS.validate();
-        boolean usePadding = false;
-        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
-            usePadding = true;
-        }
-        if (usePadding) {
-            if (dt.mSize * arrayLen < mSize / 4 * 3) {
-                throw new RSIllegalArgumentException(
-                    "Size of output array cannot be smaller than size of allocation.");
-            }
-        } else {
-            if (dt.mSize * arrayLen < mSize) {
-                throw new RSIllegalArgumentException(
-                    "Size of output array cannot be smaller than size of allocation.");
-            }
-        }
-        mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding);
-    }
-
-    /**
-     * Copy from the Allocation into an array. The method is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} does not match the input data type.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells will be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param array The array to be set from the Allocation.
-     */
-    public void copyTo(Object array) {
-        copyTo(array, validateObjectIsPrimitiveArray(array, true),
-               java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy from the Allocation into a byte array. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells will be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d The array to be set from the Allocation.
-     */
-    public void copyTo(byte[] d) {
-        validateIsInt8();
-        copyTo(d, Element.DataType.SIGNED_8, d.length);
-    }
-
-    /**
-     * Copy from the Allocation into a short array. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells will be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d The array to be set from the Allocation.
-     */
-    public void copyTo(short[] d) {
-        validateIsInt16();
-        copyTo(d, Element.DataType.SIGNED_16, d.length);
-    }
-
-    /**
-     * Copy from the Allocation into a int array. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells will be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d The array to be set from the Allocation.
-     */
-    public void copyTo(int[] d) {
-        validateIsInt32();
-        copyTo(d, Element.DataType.SIGNED_32, d.length);
-    }
-
-    /**
-     * Copy from the Allocation into a float array. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is neither a 32 bit float nor a vector of
-     * 32 bit floats {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the Allocation {@link
-     * #getBytesSize getBytesSize()}.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells will be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
-     * the cells must not be part of the array.
-     *
-     * @param d The array to be set from the Allocation.
-     */
-    public void copyTo(float[] d) {
-        validateIsFloat32();
-        copyTo(d, Element.DataType.FLOAT_32, d.length);
-    }
-
-    /**
-     * @hide
-     * This is only intended to be used by auto-generated code reflected from
-     * the RenderScript script files and should not be used by developers.
-     *
-     * @param xoff
-     * @param yoff
-     * @param zoff
-     * @param component_number
-     * @param fp
-     */
-    /*
-    public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
-        mRS.validate();
-        if (component_number >= mType.mElement.mElements.length) {
-            throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
-        }
-        if(xoff < 0) {
-            throw new RSIllegalArgumentException("Offset x must be >= 0.");
-        }
-        if(yoff < 0) {
-            throw new RSIllegalArgumentException("Offset y must be >= 0.");
-        }
-        if(zoff < 0) {
-            throw new RSIllegalArgumentException("Offset z must be >= 0.");
-        }
-
-        final byte[] data = fp.getData();
-        int data_length = data.length;
-        int eSize = mType.mElement.mElements[component_number].getBytesSize();
-        eSize *= mType.mElement.mArraySizes[component_number];
-
-        if (data_length != eSize) {
-            throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
-                                               " does not match component size " + eSize + ".");
-        }
-
-        mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
-                                   component_number, data, data_length);
-    }
-    */
-
-    private void copy1DRangeToUnchecked(int off, int count, Object array,
-                                        Element.DataType dt, int arrayLen) {
-        final int dataSize = mType.mElement.getBytesSize() * count;
-        // AutoPadding for Vec3 Element
-        boolean usePadding = false;
-        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
-            usePadding = true;
-        }
-        data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
-        mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
-                              mType.mElement.mType.mSize, usePadding);
-    }
-
-    /**
-     * Copy a 1D region of this Allocation into an array.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param array The dest array
-     */
-    public void copy1DRangeToUnchecked(int off, int count, Object array) {
-        copy1DRangeToUnchecked(off, count, array,
-                               validateObjectIsPrimitiveArray(array, false),
-                               java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy a 1D region of this Allocation into an array.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeToUnchecked(int off, int count, int[] d) {
-        copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
-    }
-
-    /**
-     * Copy a 1D region of this Allocation into an array.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeToUnchecked(int off, int count, short[] d) {
-        copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
-    }
-
-    /**
-     * Copy a 1D region of this Allocation into an array.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeToUnchecked(int off, int count, byte[] d) {
-        copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
-    }
-
-    /**
-     * Copy a 1D region of this Allocation into an array.  This method does not
-     * guarantee that the Allocation is compatible with the input buffer.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeToUnchecked(int off, int count, float[] d) {
-        copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
-    }
-
-
-    /**
-     * Copy a 1D region of this Allocation into an array.  This method is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} does not match the component type
-     * of the array passed in.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param array The source array.
-     */
-    public void copy1DRangeTo(int off, int count, Object array) {
-        copy1DRangeToUnchecked(off, count, array,
-                               validateObjectIsPrimitiveArray(array, true),
-                               java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy a 1D region of this Allocation into an array. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is neither a 32 bit integer nor a vector of 32 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeTo(int off, int count, int[] d) {
-        validateIsInt32();
-        copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
-    }
-
-    /**
-     * Copy a 1D region of this Allocation into an array. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is neither a 16 bit integer nor a vector of 16 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeTo(int off, int count, short[] d) {
-        validateIsInt16();
-        copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
-    }
-
-    /**
-     * Copy a 1D region of this Allocation into an array. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit
-     * integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array
-     */
-    public void copy1DRangeTo(int off, int count, byte[] d) {
-        validateIsInt8();
-        copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
-    }
-
-    /**
-     * Copy a 1D region of this Allocation into an array. This variant is type checked
-     * and will generate exceptions if the Allocation's {@link
-     * android.support.v8.renderscript.Element} is neither a 32 bit float nor a vector of
-     * 32 bit floats {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: count * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param off The offset of the first element to be copied.
-     * @param count The number of elements to be copied.
-     * @param d the source array.
-     */
-    public void copy1DRangeTo(int off, int count, float[] d) {
-        validateIsFloat32();
-        copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
-    }
-
-
-    void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array,
-                                Element.DataType dt, int arrayLen) {
-        mRS.validate();
-        validate2DRange(xoff, yoff, w, h);
-        final int dataSize = mType.mElement.getBytesSize() * w * h;
-        // AutoPadding for Vec3 Element
-        boolean usePadding = false;
-        int sizeBytes = arrayLen * dt.mSize;
-        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
-            if (dataSize / 4 * 3 > sizeBytes) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-            usePadding = true;
-            sizeBytes = dataSize;
-        } else {
-            if (dataSize > sizeBytes) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-        }
-        mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
-                              array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
-    }
-
-    /**
-     * Copy from a rectangular region in this Allocation into an array. This
-     * method is type checked and will generate exceptions if the Allocation's
-     * {@link android.support.v8.renderscript.Element} does not match the component type
-     * of the array passed in.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to copy in this Allocation
-     * @param yoff Y offset of the region to copy in this Allocation
-     * @param w Width of the region to copy
-     * @param h Height of the region to copy
-     * @param array Dest Array to be copied into
-     */
-    public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) {
-        copy2DRangeToUnchecked(xoff, yoff, w, h, array,
-                               validateObjectIsPrimitiveArray(array, true),
-                               java.lang.reflect.Array.getLength(array));
-    }
-
-    /**
-     * Copy from a rectangular region in this Allocation into an array. This
-     * variant is type checked and will generate exceptions if the Allocation's
-     * {@link android.support.v8.renderscript.Element} is neither an 8 bit integer nor a vector
-     * of 8 bit integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to copy in this Allocation
-     * @param yoff Y offset of the region to copy in this Allocation
-     * @param w Width of the region to copy
-     * @param h Height of the region to copy
-     * @param data Dest Array to be copied into
-     */
-    public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) {
-        validateIsInt8();
-        copy2DRangeToUnchecked(xoff, yoff, w, h, data,
-                               Element.DataType.SIGNED_8, data.length);
-    }
-
-    /**
-     * Copy from a rectangular region in this Allocation into an array. This
-     * variant is type checked and will generate exceptions if the Allocation's
-     * {@link android.support.v8.renderscript.Element} is neither a 16 bit integer nor a vector
-     * of 16 bit integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to copy in this Allocation
-     * @param yoff Y offset of the region to copy in this Allocation
-     * @param w Width of the region to copy
-     * @param h Height of the region to copy
-     * @param data Dest Array to be copied into
-     */
-    public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) {
-        validateIsInt16();
-        copy2DRangeToUnchecked(xoff, yoff, w, h, data,
-                               Element.DataType.SIGNED_16, data.length);
-    }
-
-    /**
-     * Copy from a rectangular region in this Allocation into an array. This
-     * variant is type checked and will generate exceptions if the Allocation's
-     * {@link android.support.v8.renderscript.Element} is neither a 32 bit integer nor a vector
-     * of 32 bit integers {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to copy in this Allocation
-     * @param yoff Y offset of the region to copy in this Allocation
-     * @param w Width of the region to copy
-     * @param h Height of the region to copy
-     * @param data Dest Array to be copied into
-     */
-    public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) {
-        validateIsInt32();
-        copy2DRangeToUnchecked(xoff, yoff, w, h, data,
-                               Element.DataType.SIGNED_32, data.length);
-    }
-
-    /**
-     * Copy from a rectangular region in this Allocation into an array. This
-     * variant is type checked and will generate exceptions if the Allocation's
-     * {@link android.support.v8.renderscript.Element} is neither a 32 bit float nor a vector
-     * of 32 bit floats {@link android.support.v8.renderscript.Element.DataType}.
-     *
-     * <p> The size of the region is: w * h * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to copy in this Allocation
-     * @param yoff Y offset of the region to copy in this Allocation
-     * @param w Width of the region to copy
-     * @param h Height of the region to copy
-     * @param data Dest Array to be copied into
-     */
-    public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) {
-        validateIsFloat32();
-        copy2DRangeToUnchecked(xoff, yoff, w, h, data,
-                               Element.DataType.FLOAT_32, data.length);
-    }
-
-
-    /**
-     * Copy from a 3D region in this Allocation into an array. This method does
-     * not guarantee that the Allocation is compatible with the input buffer.
-     * The array is assumed to be tightly packed.
-     *
-     * The data type of the array is not required to be the same as
-     * the element data type.
-     */
-    /*
-    private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
-                                        Object array, Element.DataType dt, int arrayLen) {
-        mRS.validate();
-        validate3DRange(xoff, yoff, zoff, w, h, d);
-        final int dataSize = mType.mElement.getBytesSize() * w * h * d;
-        // AutoPadding for Vec3 Element
-        boolean usePadding = false;
-        int sizeBytes = arrayLen * dt.mSize;
-        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
-            if (dataSize / 4 * 3 > sizeBytes) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-            usePadding = true;
-            sizeBytes = dataSize;
-        } else {
-            if (dataSize > sizeBytes) {
-                throw new RSIllegalArgumentException("Array too small for allocation type.");
-            }
-        }
-        mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
-                              array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
-    }
-    */
-
-    /**
-     * @hide
-     * Copy from a 3D region in this Allocation into an array. This
-     * method is type checked and will generate exceptions if the Allocation's
-     * {@link android.support.v8.renderscript.Element} does not match the component type
-     * of the array passed in.
-     *
-     * <p> The size of the region is: w * h * d * {@link #getElement}.{@link
-     * Element#getBytesSize}.
-     *
-     * <p> If the Allocation does not have Vec3 Elements, then the size of the
-     * array in bytes must be at least the size of the region.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is disabled, then the size of the array in bytes must be at least the size
-     * of the region. The padding bytes for the cells must be part of the array.
-     *
-     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
-     * is enabled, then the size of the array in bytes must be at least 3/4 the size
-     * of the region. The padding bytes for the cells must not be part of the array.
-     *
-     * @param xoff X offset of the region to copy in this Allocation
-     * @param yoff Y offset of the region to copy in this Allocation
-     * @param zoff Z offset of the region to copy in this Allocation
-     * @param w Width of the region to copy
-     * @param h Height of the region to copy
-     * @param d Depth of the region to copy
-     * @param array Dest Array to be copied into
-     */
-    /*
-    public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
-        copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array,
-                                 validateObjectIsPrimitiveArray(array, true),
-                                 java.lang.reflect.Array.getLength(array));
-    }
-    */
-
-    // creation
-
-    static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
-    static {
-        mBitmapOptions.inScaled = false;
-    }
-
-    /**
-     * Creates a new Allocation with the given {@link
-     * android.support.v8.renderscript.Type}, mipmap flag, and usage flags.
-     *
-     * @param type RenderScript type describing data layout
-     * @param mips specifies desired mipmap behaviour for the
-     *             allocation
-     * @param usage bit field specifying how the Allocation is
-     *              utilized
-     */
-    static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
-        rs.validate();
-        if (type.getID(rs) == 0) {
-            throw new RSInvalidStateException("Bad Type");
-        }
-
-        if(!rs.usingIO() && (usage & (USAGE_IO_INPUT | USAGE_IO_INPUT)) != 0) {
-            throw new RSRuntimeException("USAGE_IO not supported, Allocation creation failed.");
-        }
-
-        long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
-        if (id == 0) {
-            throw new RSRuntimeException("Allocation creation failed.");
-        }
-        return new Allocation(id, rs, type, usage);
-    }
-
-    /**
-     * Creates an Allocation with the size specified by the type and no mipmaps
-     * generated by default
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param type renderscript type describing data layout
-     * @param usage bit field specifying how the allocation is
-     *              utilized
-     *
-     * @return allocation
-     */
-    static public Allocation createTyped(RenderScript rs, Type type, int usage) {
-        return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
-    }
-
-    /**
-     * Creates an Allocation for use by scripts with a given {@link
-     * android.support.v8.renderscript.Type} and no mipmaps
-     *
-     * @param rs Context to which the Allocation will belong.
-     * @param type RenderScript Type describing data layout
-     *
-     * @return allocation
-     */
-    static public Allocation createTyped(RenderScript rs, Type type) {
-        return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
-    }
-
-    /**
-     * Creates an Allocation with a specified number of given elements
-     *
-     * @param rs Context to which the Allocation will belong.
-     * @param e Element to use in the Allocation
-     * @param count the number of Elements in the Allocation
-     * @param usage bit field specifying how the Allocation is
-     *              utilized
-     *
-     * @return allocation
-     */
-    static public Allocation createSized(RenderScript rs, Element e,
-                                         int count, int usage) {
-        rs.validate();
-        Type.Builder b = new Type.Builder(rs, e);
-        b.setX(count);
-        Type t = b.create();
-
-        long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
-        if (id == 0) {
-            throw new RSRuntimeException("Allocation creation failed.");
-        }
-        return new Allocation(id, rs, t, usage);
-    }
-
-    /**
-     * Creates an Allocation with a specified number of given elements
-     *
-     * @param rs Context to which the Allocation will belong.
-     * @param e Element to use in the Allocation
-     * @param count the number of Elements in the Allocation
-     *
-     * @return allocation
-     */
-    static public Allocation createSized(RenderScript rs, Element e, int count) {
-        return createSized(rs, e, count, USAGE_SCRIPT);
-    }
-
-    static Element elementFromBitmap(RenderScript rs, Bitmap b) {
-        final Bitmap.Config bc = b.getConfig();
-        if (bc == Bitmap.Config.ALPHA_8) {
-            return Element.A_8(rs);
-        }
-        if (bc == Bitmap.Config.ARGB_4444) {
-            return Element.RGBA_4444(rs);
-        }
-        if (bc == Bitmap.Config.ARGB_8888) {
-            return Element.RGBA_8888(rs);
-        }
-        if (bc == Bitmap.Config.RGB_565) {
-            return Element.RGB_565(rs);
-        }
-        throw new RSInvalidStateException("Bad bitmap type: " + bc);
-    }
-
-    static Type typeFromBitmap(RenderScript rs, Bitmap b,
-                                       MipmapControl mip) {
-        Element e = elementFromBitmap(rs, b);
-        Type.Builder tb = new Type.Builder(rs, e);
-        tb.setX(b.getWidth());
-        tb.setY(b.getHeight());
-        tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
-        return tb.create();
-    }
-
-    /**
-     * Creates an Allocation from a {@link android.graphics.Bitmap}.
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param b Bitmap source for the allocation data
-     * @param mips specifies desired mipmap behaviour for the
-     *             allocation
-     * @param usage bit field specifying how the allocation is
-     *              utilized
-     *
-     * @return Allocation containing bitmap data
-     *
-     */
-    static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
-                                              MipmapControl mips,
-                                              int usage) {
-        rs.validate();
-
-        // WAR undocumented color formats
-        if (b.getConfig() == null) {
-            if ((usage & USAGE_SHARED) != 0) {
-                throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
-            }
-            Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
-            Canvas c = new Canvas(newBitmap);
-            c.drawBitmap(b, 0, 0, null);
-            return createFromBitmap(rs, newBitmap, mips, usage);
-        }
-
-        Type t = typeFromBitmap(rs, b, mips);
-
-        // enable optimized bitmap path only with no mipmap and script-only usage
-        if (mips == MipmapControl.MIPMAP_NONE &&
-            t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
-            usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
-            long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
-            if (id == 0) {
-                throw new RSRuntimeException("Load failed.");
-            }
-
-            // keep a reference to the Bitmap around to prevent GC
-            Allocation alloc = new Allocation(id, rs, t, usage);
-            alloc.setBitmap(b);
-            return alloc;
-        }
-
-
-        long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
-        if (id == 0) {
-            throw new RSRuntimeException("Load failed.");
-        }
-        return new Allocation(id, rs, t, usage);
-    }
-
-    /**
-     * Associate a {@link android.view.Surface} with this Allocation. This
-     * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
-     *
-     * @param sur Surface to associate with allocation
-     */
-    public void setSurface(Surface sur) {
-        mRS.validate();
-        if ((mUsage & USAGE_IO_OUTPUT) == 0) {
-            throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
-        }
-
-        mRS.nAllocationSetSurface(getID(mRS), sur);
-    }
-
-    /**
-     * Creates an Allocation from a {@link android.graphics.Bitmap}.
-     *
-     * <p>This Allocation will be created with {@link #USAGE_SHARED}, and
-     * {@link #USAGE_SCRIPT}.</p>
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param b bitmap source for the allocation data
-     *
-     * @return Allocation containing bitmap data
-     *
-     */
-    static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
-        return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
-                                USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
-    }
-
-    /**
-     * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
-     * containing the horizontal list of cube faces. Each face must be a square,
-     * have the same size as all other faces, and have a width that is a power
-     * of 2.
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param b Bitmap with cubemap faces layed out in the following
-     *          format: right, left, top, bottom, front, back
-     * @param mips specifies desired mipmap behaviour for the cubemap
-     * @param usage bit field specifying how the cubemap is utilized
-     *
-     * @return allocation containing cubemap data
-     *
-     */
-    static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
-                                                     MipmapControl mips,
-                                                     int usage) {
-        rs.validate();
-
-        int height = b.getHeight();
-        int width = b.getWidth();
-
-        if (width % 6 != 0) {
-            throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
-        }
-        if (width / 6 != height) {
-            throw new RSIllegalArgumentException("Only square cube map faces supported");
-        }
-        boolean isPow2 = (height & (height - 1)) == 0;
-        if (!isPow2) {
-            throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
-        }
-
-        Element e = elementFromBitmap(rs, b);
-        Type.Builder tb = new Type.Builder(rs, e);
-        tb.setX(height);
-        tb.setY(height);
-        tb.setFaces(true);
-        tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
-        Type t = tb.create();
-
-        long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
-        if(id == 0) {
-            throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
-        }
-        return new Allocation(id, rs, t, usage);
-    }
-
-    /**
-     * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
-     * from a {@link android.graphics.Bitmap} containing the horizontal list of
-     * cube faces. Each face must be a square, have the same size as all other
-     * faces, and have a width that is a power of 2.
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param b bitmap with cubemap faces layed out in the following
-     *          format: right, left, top, bottom, front, back
-     *
-     * @return allocation containing cubemap data
-     *
-     */
-    static public Allocation createCubemapFromBitmap(RenderScript rs,
-                                                     Bitmap b) {
-        return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
-                                       USAGE_GRAPHICS_TEXTURE);
-    }
-
-    /**
-     * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
-     * objects containing the cube faces. Each face must be a square, have the
-     * same size as all other faces, and have a width that is a power of 2.
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param xpos cubemap face in the positive x direction
-     * @param xneg cubemap face in the negative x direction
-     * @param ypos cubemap face in the positive y direction
-     * @param yneg cubemap face in the negative y direction
-     * @param zpos cubemap face in the positive z direction
-     * @param zneg cubemap face in the negative z direction
-     * @param mips specifies desired mipmap behaviour for the cubemap
-     * @param usage bit field specifying how the cubemap is utilized
-     *
-     * @return allocation containing cubemap data
-     *
-     */
-    static public Allocation createCubemapFromCubeFaces(RenderScript rs,
-                                                        Bitmap xpos,
-                                                        Bitmap xneg,
-                                                        Bitmap ypos,
-                                                        Bitmap yneg,
-                                                        Bitmap zpos,
-                                                        Bitmap zneg,
-                                                        MipmapControl mips,
-                                                        int usage) {
-        /*
-        int height = xpos.getHeight();
-        if (xpos.getWidth() != height ||
-            xneg.getWidth() != height || xneg.getHeight() != height ||
-            ypos.getWidth() != height || ypos.getHeight() != height ||
-            yneg.getWidth() != height || yneg.getHeight() != height ||
-            zpos.getWidth() != height || zpos.getHeight() != height ||
-            zneg.getWidth() != height || zneg.getHeight() != height) {
-            throw new RSIllegalArgumentException("Only square cube map faces supported");
-        }
-        boolean isPow2 = (height & (height - 1)) == 0;
-        if (!isPow2) {
-            throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
-        }
-
-        Element e = elementFromBitmap(rs, xpos);
-        Type.Builder tb = new Type.Builder(rs, e);
-        tb.setX(height);
-        tb.setY(height);
-        tb.setFaces(true);
-        tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
-        Type t = tb.create();
-        Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
-
-        AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
-        adapter.setFace(Type.CubemapFace.POSITIVE_X);
-        adapter.copyFrom(xpos);
-        adapter.setFace(Type.CubemapFace.NEGATIVE_X);
-        adapter.copyFrom(xneg);
-        adapter.setFace(Type.CubemapFace.POSITIVE_Y);
-        adapter.copyFrom(ypos);
-        adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
-        adapter.copyFrom(yneg);
-        adapter.setFace(Type.CubemapFace.POSITIVE_Z);
-        adapter.copyFrom(zpos);
-        adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
-        adapter.copyFrom(zneg);
-
-        return cubemap;
-        */
-        return null;
-    }
-
-    /**
-     * Creates a non-mipmapped cubemap Allocation for use as a sampler input
-     * from 6 {@link android.graphics.Bitmap} objects containing the cube
-     * faces. Each face must be a square, have the same size as all other faces,
-     * and have a width that is a power of 2.
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param xpos cubemap face in the positive x direction
-     * @param xneg cubemap face in the negative x direction
-     * @param ypos cubemap face in the positive y direction
-     * @param yneg cubemap face in the negative y direction
-     * @param zpos cubemap face in the positive z direction
-     * @param zneg cubemap face in the negative z direction
-     *
-     * @return allocation containing cubemap data
-     *
-     */
-    static public Allocation createCubemapFromCubeFaces(RenderScript rs,
-                                                        Bitmap xpos,
-                                                        Bitmap xneg,
-                                                        Bitmap ypos,
-                                                        Bitmap yneg,
-                                                        Bitmap zpos,
-                                                        Bitmap zneg) {
-        return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
-                                          zpos, zneg, MipmapControl.MIPMAP_NONE,
-                                          USAGE_GRAPHICS_TEXTURE);
-    }
-
-    /**
-     * Creates an Allocation from the Bitmap referenced
-     * by resource ID.
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param res application resources
-     * @param id resource id to load the data from
-     * @param mips specifies desired mipmap behaviour for the
-     *             allocation
-     * @param usage bit field specifying how the allocation is
-     *              utilized
-     *
-     * @return Allocation containing resource data
-     *
-     */
-    static public Allocation createFromBitmapResource(RenderScript rs,
-                                                      Resources res,
-                                                      int id,
-                                                      MipmapControl mips,
-                                                      int usage) {
-
-        rs.validate();
-        if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
-            throw new RSIllegalArgumentException("Unsupported usage specified.");
-        }
-        Bitmap b = BitmapFactory.decodeResource(res, id);
-        Allocation alloc = createFromBitmap(rs, b, mips, usage);
-        b.recycle();
-        return alloc;
-    }
-
-    /**
-     * Creates a non-mipmapped Allocation to use as a graphics texture from the
-     * {@link android.graphics.Bitmap} referenced by resource ID.
-     *
-     * <p>This allocation will be created with {@link #USAGE_SCRIPT} and
-     * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param res application resources
-     * @param id resource id to load the data from
-     *
-     * @return Allocation containing resource data
-     *
-     */
-    static public Allocation createFromBitmapResource(RenderScript rs,
-                                                      Resources res,
-                                                      int id) {
-        return createFromBitmapResource(rs, res, id,
-                                        MipmapControl.MIPMAP_NONE,
-                                        USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
-    }
-
-    /**
-     * Creates an Allocation containing string data encoded in UTF-8 format.
-     *
-     * @param rs Context to which the allocation will belong.
-     * @param str string to create the allocation from
-     * @param usage bit field specifying how the allocaiton is
-     *              utilized
-     *
-     */
-    static public Allocation createFromString(RenderScript rs,
-                                              String str,
-                                              int usage) {
-        rs.validate();
-        byte[] allocArray = null;
-        try {
-            allocArray = str.getBytes("UTF-8");
-            Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
-            alloc.copyFrom(allocArray);
-            return alloc;
-        }
-        catch (Exception e) {
-            throw new RSRuntimeException("Could not convert string to utf-8.");
-        }
-    }
-
-    /**
-     * Frees any native resources associated with this object.  The
-     * primary use is to force immediate cleanup of resources when it is
-     * believed the GC will not respond quickly enough.
-     * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
-     */
-    @Override
-    public void destroy() {
-        if (mIncCompatAllocation != 0) {
-            boolean shouldDestroy = false;
-            synchronized(this) {
-                if (!mIncAllocDestroyed) {
-                    shouldDestroy = true;
-                    mIncAllocDestroyed = true;
-                }
-            }
-
-            if (shouldDestroy) {
-                // must include nObjDestroy in the critical section
-                ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
-                rlock.lock();
-                if(mRS.isAlive()) {
-                    mRS.nIncObjDestroy(mIncCompatAllocation);
-                }
-                rlock.unlock();
-                mIncCompatAllocation = 0;
-            }
-        }
-        if ((mUsage & (USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
-            setSurface(null);
-        }
-        super.destroy();
-    }
-
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/BaseObj.java b/v8/renderscript/java/src/android/support/v8/renderscript/BaseObj.java
deleted file mode 100644
index bb49600..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/BaseObj.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.Log;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * BaseObj is the base class for all RenderScript objects owned by a RS context.
- * It is responsible for lifetime management and resource tracking. This class
- * should not be used by a user application.
- *
- **/
-public class BaseObj {
-    BaseObj(long id, RenderScript rs) {
-        rs.validate();
-        mRS = rs;
-        mID = id;
-        mDestroyed = false;
-    }
-
-    void setID(long id) {
-        if (mID != 0) {
-            throw new RSRuntimeException("Internal Error, reset of object ID.");
-        }
-        mID = id;
-    }
-
-    /**
-     * Lookup the native object ID for this object.  Primarily used by the
-     * generated reflected code.
-     *
-     * @param rs Context to verify against internal context for
-     *           match.
-     *
-     * @return long
-     */
-    long getID(RenderScript rs) {
-        mRS.validate();
-        if (mDestroyed) {
-            throw new RSInvalidStateException("using a destroyed object.");
-        }
-        if (mID == 0) {
-            throw new RSRuntimeException("Internal error: Object id 0.");
-        }
-        if ((rs != null) && (rs != mRS)) {
-            throw new RSInvalidStateException("using object with mismatched context.");
-        }
-        return mID;
-    }
-
-    android.renderscript.BaseObj getNObj() {
-        return null;
-    }
-
-    void checkValid() {
-        if ((mID == 0) && (getNObj() == null)) {
-            throw new RSIllegalArgumentException("Invalid object.");
-        }
-    }
-
-    private long mID;
-    private boolean mDestroyed;
-    RenderScript mRS;
-
-    private void helpDestroy() {
-        boolean shouldDestroy = false;
-        synchronized(this) {
-            if (!mDestroyed) {
-                shouldDestroy = true;
-                mDestroyed = true;
-            }
-        }
-
-        if (shouldDestroy) {
-            // must include nObjDestroy in the critical section
-            ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
-            rlock.lock();
-            if(mRS.isAlive()) {
-                mRS.nObjDestroy(mID);
-            }
-            rlock.unlock();
-            mRS = null;
-            mID = 0;
-        }
-    }
-
-
-    protected void finalize() throws Throwable {
-        helpDestroy();
-        super.finalize();
-    }
-
-    /**
-     * Frees any native resources associated with this object.  The
-     * primary use is to force immediate cleanup of resources when it is
-     * believed the GC will not respond quickly enough.
-     */
-    public void destroy() {
-        if(mDestroyed) {
-            throw new RSInvalidStateException("Object already destroyed.");
-        }
-        helpDestroy();
-    }
-
-    /**
-     * Calculates the hash code value for a BaseObj.
-     *
-     * @return int
-     */
-    @Override
-    public int hashCode() {
-        return (int)((mID & 0xfffffff) ^ (mID >> 32));
-    }
-
-    /**
-     * Compare the current BaseObj with another BaseObj for equality.
-     *
-     * @param obj The object to check equality with.
-     *
-     * @return boolean
-     */
-    @Override
-    public boolean equals(Object obj) {
-        // Early-out check to see if both BaseObjs are actually the same
-        if (this == obj)
-            return true;
-
-        if (obj == null) {
-            return false;
-        }
-
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-
-        BaseObj b = (BaseObj) obj;
-        return mID == b.mID;
-    }
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Byte2.java b/v8/renderscript/java/src/android/support/v8/renderscript/Byte2.java
deleted file mode 100644
index 2371077..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Byte2.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript byte2 type back to the Android system.
- *
- **/
-public class Byte2 {
-    public Byte2() {
-    }
-
-    public Byte2(byte initX, byte initY) {
-        x = initX;
-        y = initY;
-    }
-
-    public byte x;
-    public byte y;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Byte3.java b/v8/renderscript/java/src/android/support/v8/renderscript/Byte3.java
deleted file mode 100644
index 4ed6af6..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Byte3.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript byte3 type back to the Android system.
- *
- **/
-public class Byte3 {
-    public Byte3() {
-    }
-
-    public Byte3(byte initX, byte initY, byte initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
-    public byte x;
-    public byte y;
-    public byte z;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Byte4.java b/v8/renderscript/java/src/android/support/v8/renderscript/Byte4.java
deleted file mode 100644
index 715a718..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Byte4.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript byte4 type back to the Android system.
- *
- **/
-public class Byte4 {
-    public Byte4() {
-    }
-
-    public Byte4(byte initX, byte initY, byte initZ, byte initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
-    public byte x;
-    public byte y;
-    public byte z;
-    public byte w;
-}
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Double2.java b/v8/renderscript/java/src/android/support/v8/renderscript/Double2.java
deleted file mode 100644
index cd73363..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Double2.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript double2 type back
- * to the Android system.
- *
- **/
-public class Double2 {
-    public Double2() {
-    }
-
-    public Double2(double initX, double initY) {
-        x = initX;
-        y = initY;
-    }
-
-    public double x;
-    public double y;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Double3.java b/v8/renderscript/java/src/android/support/v8/renderscript/Double3.java
deleted file mode 100644
index 38a46a6..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Double3.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript double3 type back
- * to the Android system.
- *
- **/
-public class Double3 {
-    public Double3() {
-    }
-
-    public Double3(double initX, double initY, double initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
-    public double x;
-    public double y;
-    public double z;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Double4.java b/v8/renderscript/java/src/android/support/v8/renderscript/Double4.java
deleted file mode 100644
index 6de0fa8..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Double4.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript double4 type back
- * to the Android system.
- *
- **/
-public class Double4 {
-    public Double4() {
-    }
-
-    public Double4(double initX, double initY, double initZ, double initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
-    public double x;
-    public double y;
-    public double z;
-    public double w;
-}
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Element.java b/v8/renderscript/java/src/android/support/v8/renderscript/Element.java
deleted file mode 100644
index 135d854..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Element.java
+++ /dev/null
@@ -1,1020 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.reflect.Field;
-
-import android.util.Log;
-
-/**
- * <p>An Element represents one item within an {@link
- * android.support.v8.renderscript.Allocation}.  An Element is roughly
- * equivalent to a C type in a RenderScript kernel. Elements may be basic or
- * complex. Some basic elements are</p> <ul> <li>A single float value
- * (equivalent to a float in a kernel)</li> <li>A four-element float vector
- * (equivalent to a float4 in a kernel)</li> <li>An unsigned 32-bit integer
- * (equivalent to an unsigned int in a kernel)</li> <li>A single signed 8-bit
- * integer (equivalent to a char in a kernel)</li> </ul> <p>A complex element is
- * roughly equivalent to a C struct and contains a number of basic or complex
- * Elements. From Java code, a complex element contains a list of sub-elements
- * and names that represents a particular data structure. Structs used in RS
- * scripts are available to Java code by using the
- * {@code ScriptField_structname} class that is reflected from a particular
- * script.</p>
- *
- * <p>Basic Elements are comprised of a {@link
- * android.support.v8.renderscript.Element.DataType} and a {@link
- * android.support.v8.renderscript.Element.DataKind}. The DataType encodes C
- * type information of an Element, while the DataKind encodes how that Element
- * should be interpreted by a {@link android.support.v8.renderscript.Sampler}.
- * Note that {@link android.support.v8.renderscript.Allocation} objects with
- * DataKind {@link android.support.v8.renderscript.Element.DataKind#USER} cannot
- * be used as input for a {@link android.support.v8.renderscript.Sampler}. In
- * general, {@link android.support.v8.renderscript.Allocation} objects that are
- * intended for use with a {@link android.support.v8.renderscript.Sampler}
- * should use bitmap-derived Elements such as
- * {@link android.support.v8.renderscript.Element#RGBA_8888} or {@link
- * android.support.v8.renderscript#Element.A_8}.</p>
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses RenderScript,
- * read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
- * developer guide.</p>
- * </div>
- **/
-public class Element extends BaseObj {
-    int mSize;
-    Element[] mElements;
-    String[] mElementNames;
-    int[] mArraySizes;
-    int[] mOffsetInBytes;
-    int[] mVisibleElementMap;
-
-    DataType mType;
-    DataKind mKind;
-    boolean mNormalized;
-    int mVectorSize;
-
-    private void updateVisibleSubElements() {
-        if (mElements == null) {
-            return;
-        }
-
-        int noPaddingFieldCount = 0;
-        int fieldCount = mElementNames.length;
-        // Find out how many elements are not padding
-        for (int ct = 0; ct < fieldCount; ct ++) {
-            if (mElementNames[ct].charAt(0) != '#') {
-                noPaddingFieldCount ++;
-            }
-        }
-        mVisibleElementMap = new int[noPaddingFieldCount];
-
-        // Make a map that points us at non-padding elements
-        for (int ct = 0, ctNoPadding = 0; ct < fieldCount; ct ++) {
-            if (mElementNames[ct].charAt(0) != '#') {
-                mVisibleElementMap[ctNoPadding ++] = ct;
-            }
-        }
-    }
-
-    /**
-    * @return element size in bytes
-    */
-    public int getBytesSize() {
-        return mSize;
-    }
-
-    /**
-    * Returns the number of vector components. 2 for float2, 4 for
-    * float4, etc.
-    * @return element vector size
-    */
-    public int getVectorSize() {
-        return mVectorSize;
-    }
-
-
-    /**
-     * DataType represents the basic type information for a basic element.  The
-     * naming convention follows.  For numeric types it is FLOAT,
-     * SIGNED, or UNSIGNED followed by the _BITS where BITS is the
-     * size of the data.  BOOLEAN is a true / false (1,0)
-     * represented in an 8 bit container.  The UNSIGNED variants
-     * with multiple bit definitions are for packed graphical data
-     * formats and represent vectors with per vector member sizes
-     * which are treated as a single unit for packing and alignment
-     * purposes.
-     *
-     * MATRIX the three matrix types contain FLOAT_32 elements and are treated
-     * as 32 bits for alignment purposes.
-     *
-     * RS_* objects.  32 bit opaque handles.
-     */
-    public enum DataType {
-        NONE (0, 0),
-        //FLOAT_16 (1, 2),
-        FLOAT_32 (2, 4),
-        FLOAT_64 (3, 8),
-        SIGNED_8 (4, 1),
-        SIGNED_16 (5, 2),
-        SIGNED_32 (6, 4),
-        SIGNED_64 (7, 8),
-        UNSIGNED_8 (8, 1),
-        UNSIGNED_16 (9, 2),
-        UNSIGNED_32 (10, 4),
-        UNSIGNED_64 (11, 8),
-
-        BOOLEAN(12, 1),
-
-        UNSIGNED_5_6_5 (13, 2),
-        UNSIGNED_5_5_5_1 (14, 2),
-        UNSIGNED_4_4_4_4 (15, 2),
-
-        MATRIX_4X4 (16, 64),
-        MATRIX_3X3 (17, 36),
-        MATRIX_2X2 (18, 16),
-
-        RS_ELEMENT (1000),
-        RS_TYPE (1001),
-        RS_ALLOCATION (1002),
-        RS_SAMPLER (1003),
-        RS_SCRIPT (1004);
-
-        int mID;
-        int mSize;
-        DataType(int id, int size) {
-            mID = id;
-            mSize = size;
-        }
-
-        DataType(int id) {
-            mID = id;
-            mSize = 4;
-            if (RenderScript.sPointerSize == 8) {
-                mSize = 32;
-            }
-        }
-    }
-
-    /**
-     * The special interpretation of the data if required.  This is primarly
-     * useful for graphical data.  USER indicates no special interpretation is
-     * expected.  PIXEL is used in conjunction with the standard data types for
-     * representing texture formats.
-     */
-    public enum DataKind {
-        USER (0),
-
-        PIXEL_L (7),
-        PIXEL_A (8),
-        PIXEL_LA (9),
-        PIXEL_RGB (10),
-        PIXEL_RGBA (11),
-        PIXEL_DEPTH (12),
-        PIXEL_YUV(13);
-
-        int mID;
-        DataKind(int id) {
-            mID = id;
-        }
-    }
-
-    /**
-     * Return if a element is too complex for use as a data source for a Mesh or
-     * a Program.
-     *
-     * @return boolean
-     */
-    public boolean isComplex() {
-        if (mElements == null) {
-            return false;
-        }
-        for (int ct=0; ct < mElements.length; ct++) {
-            if (mElements[ct].mElements != null) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-    * Elements could be simple, such as an int or a float, or a
-    * structure with multiple sub elements, such as a collection of
-    * floats, float2, float4. This function returns zero for simple
-    * elements or the number of sub-elements otherwise.
-    * @return number of sub-elements in this element
-    */
-    public int getSubElementCount() {
-        if (mVisibleElementMap == null) {
-            return 0;
-        }
-        return mVisibleElementMap.length;
-    }
-
-    /**
-    * For complex elements, this function will return the
-    * sub-element at index
-    * @param index index of the sub-element to return
-    * @return sub-element in this element at given index
-    */
-    public Element getSubElement(int index) {
-        if (mVisibleElementMap == null) {
-            throw new RSIllegalArgumentException("Element contains no sub-elements");
-        }
-        if (index < 0 || index >= mVisibleElementMap.length) {
-            throw new RSIllegalArgumentException("Illegal sub-element index");
-        }
-        return mElements[mVisibleElementMap[index]];
-    }
-
-    /**
-    * For complex elements, this function will return the
-    * sub-element name at index
-    * @param index index of the sub-element
-    * @return sub-element in this element at given index
-    */
-    public String getSubElementName(int index) {
-        if (mVisibleElementMap == null) {
-            throw new RSIllegalArgumentException("Element contains no sub-elements");
-        }
-        if (index < 0 || index >= mVisibleElementMap.length) {
-            throw new RSIllegalArgumentException("Illegal sub-element index");
-        }
-        return mElementNames[mVisibleElementMap[index]];
-    }
-
-    /**
-    * For complex elements, some sub-elements could be statically
-    * sized arrays. This function will return the array size for
-    * sub-element at index
-    * @param index index of the sub-element
-    * @return array size of sub-element in this element at given index
-    */
-    public int getSubElementArraySize(int index) {
-        if (mVisibleElementMap == null) {
-            throw new RSIllegalArgumentException("Element contains no sub-elements");
-        }
-        if (index < 0 || index >= mVisibleElementMap.length) {
-            throw new RSIllegalArgumentException("Illegal sub-element index");
-        }
-        return mArraySizes[mVisibleElementMap[index]];
-    }
-
-    /**
-    * This function specifies the location of a sub-element within
-    * the element
-    * @param index index of the sub-element
-    * @return offset in bytes of sub-element in this element at given index
-    */
-    public int getSubElementOffsetBytes(int index) {
-        if (mVisibleElementMap == null) {
-            throw new RSIllegalArgumentException("Element contains no sub-elements");
-        }
-        if (index < 0 || index >= mVisibleElementMap.length) {
-            throw new RSIllegalArgumentException("Illegal sub-element index");
-        }
-        return mOffsetInBytes[mVisibleElementMap[index]];
-    }
-
-    /**
-    * @return element data type
-    */
-    public DataType getDataType() {
-        return mType;
-    }
-
-    /**
-    * @return element data kind
-    */
-    public DataKind getDataKind() {
-        return mKind;
-    }
-
-    /**
-     * Utility function for returning an Element containing a single Boolean.
-     *
-     * @param rs Context to which the element will belong.
-     *
-     * @return Element
-     */
-    public static Element BOOLEAN(RenderScript rs) {
-        if(rs.mElement_BOOLEAN == null) {
-            rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN);
-        }
-        return rs.mElement_BOOLEAN;
-    }
-
-    /**
-     * Utility function for returning an Element containing a single UNSIGNED_8.
-     *
-     * @param rs Context to which the element will belong.
-     *
-     * @return Element
-     */
-    public static Element U8(RenderScript rs) {
-        if(rs.mElement_U8 == null) {
-            rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
-        }
-        return rs.mElement_U8;
-    }
-
-    /**
-     * Utility function for returning an Element containing a single SIGNED_8.
-     *
-     * @param rs Context to which the element will belong.
-     *
-     * @return Element
-     */
-    public static Element I8(RenderScript rs) {
-        if(rs.mElement_I8 == null) {
-            rs.mElement_I8 = createUser(rs, DataType.SIGNED_8);
-        }
-        return rs.mElement_I8;
-    }
-
-    public static Element U16(RenderScript rs) {
-        if(rs.mElement_U16 == null) {
-            rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16);
-        }
-        return rs.mElement_U16;
-    }
-
-    public static Element I16(RenderScript rs) {
-        if(rs.mElement_I16 == null) {
-            rs.mElement_I16 = createUser(rs, DataType.SIGNED_16);
-        }
-        return rs.mElement_I16;
-    }
-
-    public static Element U32(RenderScript rs) {
-        if(rs.mElement_U32 == null) {
-            rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32);
-        }
-        return rs.mElement_U32;
-    }
-
-    public static Element I32(RenderScript rs) {
-        if(rs.mElement_I32 == null) {
-            rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
-        }
-        return rs.mElement_I32;
-    }
-
-    public static Element U64(RenderScript rs) {
-        if(rs.mElement_U64 == null) {
-            rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
-        }
-        return rs.mElement_U64;
-    }
-
-    public static Element I64(RenderScript rs) {
-        if(rs.mElement_I64 == null) {
-            rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
-        }
-        return rs.mElement_I64;
-    }
-
-    public static Element F32(RenderScript rs) {
-        if(rs.mElement_F32 == null) {
-            rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
-        }
-        return rs.mElement_F32;
-    }
-
-    public static Element F64(RenderScript rs) {
-        if(rs.mElement_F64 == null) {
-            rs.mElement_F64 = createUser(rs, DataType.FLOAT_64);
-        }
-        return rs.mElement_F64;
-    }
-
-    public static Element ELEMENT(RenderScript rs) {
-        if(rs.mElement_ELEMENT == null) {
-            rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
-        }
-        return rs.mElement_ELEMENT;
-    }
-
-    public static Element TYPE(RenderScript rs) {
-        if(rs.mElement_TYPE == null) {
-            rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE);
-        }
-        return rs.mElement_TYPE;
-    }
-
-    public static Element ALLOCATION(RenderScript rs) {
-        if(rs.mElement_ALLOCATION == null) {
-            rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
-        }
-        return rs.mElement_ALLOCATION;
-    }
-
-    public static Element SAMPLER(RenderScript rs) {
-        if(rs.mElement_SAMPLER == null) {
-            rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
-        }
-        return rs.mElement_SAMPLER;
-    }
-
-    public static Element SCRIPT(RenderScript rs) {
-        if(rs.mElement_SCRIPT == null) {
-            rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
-        }
-        return rs.mElement_SCRIPT;
-    }
-
-
-    public static Element A_8(RenderScript rs) {
-        if(rs.mElement_A_8 == null) {
-            rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A);
-        }
-        return rs.mElement_A_8;
-    }
-
-    public static Element RGB_565(RenderScript rs) {
-        if(rs.mElement_RGB_565 == null) {
-            rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB);
-        }
-        return rs.mElement_RGB_565;
-    }
-
-    public static Element RGB_888(RenderScript rs) {
-        if(rs.mElement_RGB_888 == null) {
-            rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB);
-        }
-        return rs.mElement_RGB_888;
-    }
-
-    public static Element RGBA_5551(RenderScript rs) {
-        if(rs.mElement_RGBA_5551 == null) {
-            rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA);
-        }
-        return rs.mElement_RGBA_5551;
-    }
-
-    public static Element RGBA_4444(RenderScript rs) {
-        if(rs.mElement_RGBA_4444 == null) {
-            rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA);
-        }
-        return rs.mElement_RGBA_4444;
-    }
-
-    public static Element RGBA_8888(RenderScript rs) {
-        if(rs.mElement_RGBA_8888 == null) {
-            rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA);
-        }
-        return rs.mElement_RGBA_8888;
-    }
-
-    public static Element F32_2(RenderScript rs) {
-        if(rs.mElement_FLOAT_2 == null) {
-            rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2);
-        }
-        return rs.mElement_FLOAT_2;
-    }
-
-    public static Element F32_3(RenderScript rs) {
-        if(rs.mElement_FLOAT_3 == null) {
-            rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
-        }
-        return rs.mElement_FLOAT_3;
-    }
-
-    public static Element F32_4(RenderScript rs) {
-        if(rs.mElement_FLOAT_4 == null) {
-            rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
-        }
-        return rs.mElement_FLOAT_4;
-    }
-
-    public static Element F64_2(RenderScript rs) {
-        if(rs.mElement_DOUBLE_2 == null) {
-            rs.mElement_DOUBLE_2 = createVector(rs, DataType.FLOAT_64, 2);
-        }
-        return rs.mElement_DOUBLE_2;
-    }
-
-    public static Element F64_3(RenderScript rs) {
-        if(rs.mElement_DOUBLE_3 == null) {
-            rs.mElement_DOUBLE_3 = createVector(rs, DataType.FLOAT_64, 3);
-        }
-        return rs.mElement_DOUBLE_3;
-    }
-
-    public static Element F64_4(RenderScript rs) {
-        if(rs.mElement_DOUBLE_4 == null) {
-            rs.mElement_DOUBLE_4 = createVector(rs, DataType.FLOAT_64, 4);
-        }
-        return rs.mElement_DOUBLE_4;
-    }
-
-    public static Element U8_2(RenderScript rs) {
-        if(rs.mElement_UCHAR_2 == null) {
-            rs.mElement_UCHAR_2 = createVector(rs, DataType.UNSIGNED_8, 2);
-        }
-        return rs.mElement_UCHAR_2;
-    }
-
-    public static Element U8_3(RenderScript rs) {
-        if(rs.mElement_UCHAR_3 == null) {
-            rs.mElement_UCHAR_3 = createVector(rs, DataType.UNSIGNED_8, 3);
-        }
-        return rs.mElement_UCHAR_3;
-    }
-
-    public static Element U8_4(RenderScript rs) {
-        if(rs.mElement_UCHAR_4 == null) {
-            rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
-        }
-        return rs.mElement_UCHAR_4;
-    }
-
-    public static Element I8_2(RenderScript rs) {
-        if(rs.mElement_CHAR_2 == null) {
-            rs.mElement_CHAR_2 = createVector(rs, DataType.SIGNED_8, 2);
-        }
-        return rs.mElement_CHAR_2;
-    }
-
-    public static Element I8_3(RenderScript rs) {
-        if(rs.mElement_CHAR_3 == null) {
-            rs.mElement_CHAR_3 = createVector(rs, DataType.SIGNED_8, 3);
-        }
-        return rs.mElement_CHAR_3;
-    }
-
-    public static Element I8_4(RenderScript rs) {
-        if(rs.mElement_CHAR_4 == null) {
-            rs.mElement_CHAR_4 = createVector(rs, DataType.SIGNED_8, 4);
-        }
-        return rs.mElement_CHAR_4;
-    }
-
-    public static Element U16_2(RenderScript rs) {
-        if(rs.mElement_USHORT_2 == null) {
-            rs.mElement_USHORT_2 = createVector(rs, DataType.UNSIGNED_16, 2);
-        }
-        return rs.mElement_USHORT_2;
-    }
-
-    public static Element U16_3(RenderScript rs) {
-        if(rs.mElement_USHORT_3 == null) {
-            rs.mElement_USHORT_3 = createVector(rs, DataType.UNSIGNED_16, 3);
-        }
-        return rs.mElement_USHORT_3;
-    }
-
-    public static Element U16_4(RenderScript rs) {
-        if(rs.mElement_USHORT_4 == null) {
-            rs.mElement_USHORT_4 = createVector(rs, DataType.UNSIGNED_16, 4);
-        }
-        return rs.mElement_USHORT_4;
-    }
-
-    public static Element I16_2(RenderScript rs) {
-        if(rs.mElement_SHORT_2 == null) {
-            rs.mElement_SHORT_2 = createVector(rs, DataType.SIGNED_16, 2);
-        }
-        return rs.mElement_SHORT_2;
-    }
-
-    public static Element I16_3(RenderScript rs) {
-        if(rs.mElement_SHORT_3 == null) {
-            rs.mElement_SHORT_3 = createVector(rs, DataType.SIGNED_16, 3);
-        }
-        return rs.mElement_SHORT_3;
-    }
-
-    public static Element I16_4(RenderScript rs) {
-        if(rs.mElement_SHORT_4 == null) {
-            rs.mElement_SHORT_4 = createVector(rs, DataType.SIGNED_16, 4);
-        }
-        return rs.mElement_SHORT_4;
-    }
-
-    public static Element U32_2(RenderScript rs) {
-        if(rs.mElement_UINT_2 == null) {
-            rs.mElement_UINT_2 = createVector(rs, DataType.UNSIGNED_32, 2);
-        }
-        return rs.mElement_UINT_2;
-    }
-
-    public static Element U32_3(RenderScript rs) {
-        if(rs.mElement_UINT_3 == null) {
-            rs.mElement_UINT_3 = createVector(rs, DataType.UNSIGNED_32, 3);
-        }
-        return rs.mElement_UINT_3;
-    }
-
-    public static Element U32_4(RenderScript rs) {
-        if(rs.mElement_UINT_4 == null) {
-            rs.mElement_UINT_4 = createVector(rs, DataType.UNSIGNED_32, 4);
-        }
-        return rs.mElement_UINT_4;
-    }
-
-    public static Element I32_2(RenderScript rs) {
-        if(rs.mElement_INT_2 == null) {
-            rs.mElement_INT_2 = createVector(rs, DataType.SIGNED_32, 2);
-        }
-        return rs.mElement_INT_2;
-    }
-
-    public static Element I32_3(RenderScript rs) {
-        if(rs.mElement_INT_3 == null) {
-            rs.mElement_INT_3 = createVector(rs, DataType.SIGNED_32, 3);
-        }
-        return rs.mElement_INT_3;
-    }
-
-    public static Element I32_4(RenderScript rs) {
-        if(rs.mElement_INT_4 == null) {
-            rs.mElement_INT_4 = createVector(rs, DataType.SIGNED_32, 4);
-        }
-        return rs.mElement_INT_4;
-    }
-
-    public static Element U64_2(RenderScript rs) {
-        if(rs.mElement_ULONG_2 == null) {
-            rs.mElement_ULONG_2 = createVector(rs, DataType.UNSIGNED_64, 2);
-        }
-        return rs.mElement_ULONG_2;
-    }
-
-    public static Element U64_3(RenderScript rs) {
-        if(rs.mElement_ULONG_3 == null) {
-            rs.mElement_ULONG_3 = createVector(rs, DataType.UNSIGNED_64, 3);
-        }
-        return rs.mElement_ULONG_3;
-    }
-
-    public static Element U64_4(RenderScript rs) {
-        if(rs.mElement_ULONG_4 == null) {
-            rs.mElement_ULONG_4 = createVector(rs, DataType.UNSIGNED_64, 4);
-        }
-        return rs.mElement_ULONG_4;
-    }
-
-    public static Element I64_2(RenderScript rs) {
-        if(rs.mElement_LONG_2 == null) {
-            rs.mElement_LONG_2 = createVector(rs, DataType.SIGNED_64, 2);
-        }
-        return rs.mElement_LONG_2;
-    }
-
-    public static Element I64_3(RenderScript rs) {
-        if(rs.mElement_LONG_3 == null) {
-            rs.mElement_LONG_3 = createVector(rs, DataType.SIGNED_64, 3);
-        }
-        return rs.mElement_LONG_3;
-    }
-
-    public static Element I64_4(RenderScript rs) {
-        if(rs.mElement_LONG_4 == null) {
-            rs.mElement_LONG_4 = createVector(rs, DataType.SIGNED_64, 4);
-        }
-        return rs.mElement_LONG_4;
-    }
-
-    public static Element MATRIX_4X4(RenderScript rs) {
-        if(rs.mElement_MATRIX_4X4 == null) {
-            rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
-        }
-        return rs.mElement_MATRIX_4X4;
-    }
-
-    public static Element MATRIX_3X3(RenderScript rs) {
-        if(rs.mElement_MATRIX_3X3 == null) {
-            rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3);
-        }
-        return rs.mElement_MATRIX_3X3;
-    }
-
-    public static Element MATRIX_2X2(RenderScript rs) {
-        if(rs.mElement_MATRIX_2X2 == null) {
-            rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2);
-        }
-        return rs.mElement_MATRIX_2X2;
-    }
-
-    Element(long id, RenderScript rs, Element[] e, String[] n, int[] as) {
-        super(id, rs);
-        mSize = 0;
-        mVectorSize = 1;
-        mElements = e;
-        mElementNames = n;
-        mArraySizes = as;
-        mType = DataType.NONE;
-        mKind = DataKind.USER;
-        mOffsetInBytes = new int[mElements.length];
-        for (int ct = 0; ct < mElements.length; ct++ ) {
-            mOffsetInBytes[ct] = mSize;
-            mSize += mElements[ct].mSize * mArraySizes[ct];
-        }
-        updateVisibleSubElements();
-    }
-
-    Element(long id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
-        super(id, rs);
-        if ((dt != DataType.UNSIGNED_5_6_5) &&
-            (dt != DataType.UNSIGNED_4_4_4_4) &&
-            (dt != DataType.UNSIGNED_5_5_5_1)) {
-            if (size == 3) {
-                mSize = dt.mSize * 4;
-            } else {
-                mSize = dt.mSize * size;
-            }
-        } else {
-            mSize = dt.mSize;
-        }
-        mType = dt;
-        mKind = dk;
-        mNormalized = norm;
-        mVectorSize = size;
-    }
-
-    Element(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /*
-     * Get an identical dummy Element for Compat Context
-     *
-     */
-    public long getDummyElement(RenderScript mRS) {
-        return mRS.nIncElementCreate(mType.mID, mKind.mID, mNormalized, mVectorSize);
-    }
-    /**
-     * Create a custom Element of the specified DataType.  The DataKind will be
-     * set to USER and the vector size to 1 indicating non-vector.
-     *
-     * @param rs The context associated with the new Element.
-     * @param dt The DataType for the new element.
-     * @return Element
-     */
-    static Element createUser(RenderScript rs, DataType dt) {
-        DataKind dk = DataKind.USER;
-        boolean norm = false;
-        int vecSize = 1;
-        long id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize);
-        return new Element(id, rs, dt, dk, norm, vecSize);
-    }
-
-    /**
-     * Create a custom vector element of the specified DataType and vector size.
-     * DataKind will be set to USER. Only primitive types (FLOAT_32, FLOAT_64,
-     * SIGNED_8, SIGNED_16, SIGNED_32, SIGNED_64, UNSIGNED_8, UNSIGNED_16,
-     * UNSIGNED_32, UNSIGNED_64, BOOLEAN) are supported.
-     *
-     * @param rs The context associated with the new Element.
-     * @param dt The DataType for the new Element.
-     * @param size Vector size for the new Element.  Range 2-4 inclusive
-     *             supported.
-     *
-     * @return Element
-     */
-    public static Element createVector(RenderScript rs, DataType dt, int size) {
-        if (size < 2 || size > 4) {
-            throw new RSIllegalArgumentException("Vector size out of range 2-4.");
-        }
-
-        switch (dt) {
-        // Support only primitive integer/float/boolean types as vectors.
-        case FLOAT_32:
-        case FLOAT_64:
-        case SIGNED_8:
-        case SIGNED_16:
-        case SIGNED_32:
-        case SIGNED_64:
-        case UNSIGNED_8:
-        case UNSIGNED_16:
-        case UNSIGNED_32:
-        case UNSIGNED_64:
-        case BOOLEAN: {
-            DataKind dk = DataKind.USER;
-            boolean norm = false;
-            long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
-            return new Element(id, rs, dt, dk, norm, size);
-        }
-
-        default: {
-            throw new RSIllegalArgumentException("Cannot create vector of " +
-                "non-primitive type.");
-        }
-        }
-    }
-
-    /**
-     * Create a new pixel Element type.  A matching DataType and DataKind must
-     * be provided.  The DataType and DataKind must contain the same number of
-     * components.  Vector size will be set to 1.
-     *
-     * @param rs The context associated with the new Element.
-     * @param dt The DataType for the new element.
-     * @param dk The DataKind to specify the mapping of each component in the
-     *           DataType.
-     *
-     * @return Element
-     */
-    public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
-        if (!(dk == DataKind.PIXEL_L ||
-              dk == DataKind.PIXEL_A ||
-              dk == DataKind.PIXEL_LA ||
-              dk == DataKind.PIXEL_RGB ||
-              dk == DataKind.PIXEL_RGBA ||
-              dk == DataKind.PIXEL_DEPTH ||
-              dk == DataKind.PIXEL_YUV)) {
-            throw new RSIllegalArgumentException("Unsupported DataKind");
-        }
-        if (!(dt == DataType.UNSIGNED_8 ||
-              dt == DataType.UNSIGNED_16 ||
-              dt == DataType.UNSIGNED_5_6_5 ||
-              dt == DataType.UNSIGNED_4_4_4_4 ||
-              dt == DataType.UNSIGNED_5_5_5_1)) {
-            throw new RSIllegalArgumentException("Unsupported DataType");
-        }
-        if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) {
-            throw new RSIllegalArgumentException("Bad kind and type combo");
-        }
-        if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) {
-            throw new RSIllegalArgumentException("Bad kind and type combo");
-        }
-        if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
-            throw new RSIllegalArgumentException("Bad kind and type combo");
-        }
-        if (dt == DataType.UNSIGNED_16 &&
-            dk != DataKind.PIXEL_DEPTH) {
-            throw new RSIllegalArgumentException("Bad kind and type combo");
-        }
-
-        int size = 1;
-        switch (dk) {
-        case PIXEL_LA:
-            size = 2;
-            break;
-        case PIXEL_RGB:
-            size = 3;
-            break;
-        case PIXEL_RGBA:
-            size = 4;
-            break;
-        }
-
-        boolean norm = true;
-        long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
-        return new Element(id, rs, dt, dk, norm, size);
-    }
-
-    /**
-     * Check if the current Element is compatible with another Element.
-     * Primitive Elements are compatible if they share the same underlying
-     * size and type (i.e. U8 is compatible with A_8). User-defined Elements
-     * must be equal in order to be compatible. This requires strict name
-     * equivalence for all sub-Elements (in addition to structural equivalence).
-     *
-     * @param e The Element to check compatibility with.
-     *
-     * @return boolean true if the Elements are compatible, otherwise false.
-     */
-    public boolean isCompatible(Element e) {
-        // Try strict BaseObj equality to start with.
-        if (this.equals(e)) {
-            return true;
-        }
-
-        // Ignore mKind because it is allowed to be different (user vs. pixel).
-        // We also ignore mNormalized because it can be different. The mType
-        // field must not be NONE since we require name equivalence for
-        // all user-created Elements.
-        return ((mSize == e.mSize) &&
-                (mType != DataType.NONE) &&
-                (mType == e.mType) &&
-                (mVectorSize == e.mVectorSize));
-    }
-
-    /**
-     * Builder class for producing complex elements with matching field and name
-     * pairs.  The builder starts empty.  The order in which elements are added
-     * is retained for the layout in memory.
-     *
-     */
-    public static class Builder {
-
-        RenderScript mRS;
-        Element[] mElements;
-        String[] mElementNames;
-        int[] mArraySizes;
-        int mCount;
-        int mSkipPadding;
-
-        /**
-         * Create a builder object.
-         *
-         * @param rs
-         */
-        public Builder(RenderScript rs) {
-            mRS = rs;
-            mCount = 0;
-            mElements = new Element[8];
-            mElementNames = new String[8];
-            mArraySizes = new int[8];
-        }
-
-        /**
-         * Add an array of elements to this element.
-         *
-         * @param element
-         * @param name
-         * @param arraySize
-         */
-        public Builder add(Element element, String name, int arraySize) {
-            if (arraySize < 1) {
-                throw new RSIllegalArgumentException("Array size cannot be less than 1.");
-            }
-
-            // Skip padding fields after a vector 3 type.
-            if (mSkipPadding != 0) {
-                if (name.startsWith("#padding_")) {
-                    mSkipPadding = 0;
-                    return this;
-                }
-            }
-
-            if (element.mVectorSize == 3) {
-                mSkipPadding = 1;
-            } else {
-                mSkipPadding = 0;
-            }
-
-            if(mCount == mElements.length) {
-                Element[] e = new Element[mCount + 8];
-                String[] s = new String[mCount + 8];
-                int[] as = new int[mCount + 8];
-                System.arraycopy(mElements, 0, e, 0, mCount);
-                System.arraycopy(mElementNames, 0, s, 0, mCount);
-                System.arraycopy(mArraySizes, 0, as, 0, mCount);
-                mElements = e;
-                mElementNames = s;
-                mArraySizes = as;
-            }
-            mElements[mCount] = element;
-            mElementNames[mCount] = name;
-            mArraySizes[mCount] = arraySize;
-            mCount++;
-
-            return this;
-        }
-
-        /**
-         * Add a single element to this Element.
-         *
-         * @param element
-         * @param name
-         */
-        public Builder add(Element element, String name) {
-            return add(element, name, 1);
-        }
-
-        /**
-         * Create the element from this builder.
-         *
-         *
-         * @return Element
-         */
-        public Element create() {
-            mRS.validate();
-            Element[] ein = new Element[mCount];
-            String[] sin = new String[mCount];
-            int[] asin = new int[mCount];
-            java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
-            java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
-            java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
-
-            long[] ids = new long[ein.length];
-            for (int ct = 0; ct < ein.length; ct++ ) {
-                ids[ct] = ein[ct].getID(mRS);
-            }
-
-            long id = mRS.nElementCreate2(ids, sin, asin);
-            return new Element(id, mRS, ein, sin, asin);
-        }
-    }
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/FieldPacker.java b/v8/renderscript/java/src/android/support/v8/renderscript/FieldPacker.java
deleted file mode 100644
index 5f61920..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/FieldPacker.java
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.support.v8.renderscript.RenderScript;
-import java.util.BitSet;
-
-/**
- * Utility class for packing arguments and structures from Android system objects to
- * RenderScript objects.
- *
- * This class is only intended to be used to support the
- * reflected code generated by the RS tool chain.  It should not
- * be called directly.
- *
- **/
-public class FieldPacker {
-    public FieldPacker(int len) {
-        mPos = 0;
-        mLen = len;
-        mData = new byte[len];
-        mAlignment = new BitSet();
-    }
-
-    public FieldPacker(byte[] data) {
-        // Advance mPos to the end of the buffer, since we are copying in the
-        // full data input.
-        mPos = data.length;
-        mLen = data.length;
-        mData = data;
-        mAlignment = new BitSet();
-        // TODO: We should either have an actual FieldPacker copy constructor
-        // or drop support for computing alignment like this. As it stands,
-        // subAlign() can never work correctly for copied FieldPacker objects.
-    }
-
-    static FieldPacker createFromArray(Object[] args) {
-        FieldPacker fp = new FieldPacker(RenderScript.sPointerSize * 8);
-        for (Object arg : args) {
-            fp.addSafely(arg);
-        }
-        fp.resize(fp.mPos);
-        return fp;
-    }
-
-    public void align(int v) {
-        if ((v <= 0) || ((v & (v - 1)) != 0)) {
-            throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
-        }
-
-        while ((mPos & (v - 1)) != 0) {
-            mAlignment.flip(mPos);
-            mData[mPos++] = 0;
-        }
-    }
-
-    public void subalign(int v) {
-        if ((v & (v - 1)) != 0) {
-            throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
-        }
-
-        while ((mPos & (v - 1)) != 0) {
-            mPos--;
-        }
-
-        if (mPos > 0) {
-            while (mAlignment.get(mPos - 1) == true) {
-                mPos--;
-                mAlignment.flip(mPos);
-            }
-        }
-
-    }
-
-    public void reset() {
-        mPos = 0;
-    }
-    public void reset(int i) {
-        if ((i < 0) || (i > mLen)) {
-            throw new RSIllegalArgumentException("out of range argument: " + i);
-        }
-        mPos = i;
-    }
-
-    public void skip(int i) {
-        int res = mPos + i;
-        if ((res < 0) || (res > mLen)) {
-            throw new RSIllegalArgumentException("out of range argument: " + i);
-        }
-        mPos = res;
-    }
-
-    public void addI8(byte v) {
-        mData[mPos++] = v;
-    }
-
-    public byte subI8() {
-        subalign(1);
-        return mData[--mPos];
-    }
-
-    public void addI16(short v) {
-        align(2);
-        mData[mPos++] = (byte)(v & 0xff);
-        mData[mPos++] = (byte)(v >> 8);
-    }
-
-    public short subI16() {
-        subalign(2);
-        short v = 0;
-        v = (short)((mData[--mPos] & 0xff) << 8);
-        v = (short)(v | (short)(mData[--mPos] & 0xff));
-        return v;
-    }
-
-
-    public void addI32(int v) {
-        align(4);
-        mData[mPos++] = (byte)(v & 0xff);
-        mData[mPos++] = (byte)((v >> 8) & 0xff);
-        mData[mPos++] = (byte)((v >> 16) & 0xff);
-        mData[mPos++] = (byte)((v >> 24) & 0xff);
-    }
-
-    public int subI32() {
-        subalign(4);
-        int v = 0;
-        v = ((mData[--mPos] & 0xff) << 24);
-        v = v | ((mData[--mPos] & 0xff) << 16);
-        v = v | ((mData[--mPos] & 0xff) << 8);
-        v = v | ((mData[--mPos] & 0xff));
-        return v;
-    }
-
-
-    public void addI64(long v) {
-        align(8);
-        mData[mPos++] = (byte)(v & 0xff);
-        mData[mPos++] = (byte)((v >> 8) & 0xff);
-        mData[mPos++] = (byte)((v >> 16) & 0xff);
-        mData[mPos++] = (byte)((v >> 24) & 0xff);
-        mData[mPos++] = (byte)((v >> 32) & 0xff);
-        mData[mPos++] = (byte)((v >> 40) & 0xff);
-        mData[mPos++] = (byte)((v >> 48) & 0xff);
-        mData[mPos++] = (byte)((v >> 56) & 0xff);
-    }
-
-    public long subI64() {
-        subalign(8);
-        long v = 0;
-        byte x = 0;
-        x = ((mData[--mPos]));
-        v = (long)(v | (((long)x) & 0xff) << 56l);
-        x = ((mData[--mPos]));
-        v = (long)(v | (((long)x) & 0xff) << 48l);
-        x = ((mData[--mPos]));
-        v = (long)(v | (((long)x) & 0xff) << 40l);
-        x = ((mData[--mPos]));
-        v = (long)(v | (((long)x) & 0xff) << 32l);
-        x = ((mData[--mPos]));
-        v = (long)(v | (((long)x) & 0xff) << 24l);
-        x = ((mData[--mPos]));
-        v = (long)(v | (((long)x) & 0xff) << 16l);
-        x = ((mData[--mPos]));
-        v = (long)(v | (((long)x) & 0xff) << 8l);
-        x = ((mData[--mPos]));
-        v = (long)(v | (((long)x) & 0xff));
-        return v;
-    }
-
-    public void addU8(short v) {
-        if ((v < 0) || (v > 0xff)) {
-            android.util.Log.e("rs", "FieldPacker.addU8( " + v + " )");
-            throw new IllegalArgumentException("Saving value out of range for type");
-        }
-        mData[mPos++] = (byte)v;
-    }
-
-    public void addU16(int v) {
-        if ((v < 0) || (v > 0xffff)) {
-            android.util.Log.e("rs", "FieldPacker.addU16( " + v + " )");
-            throw new IllegalArgumentException("Saving value out of range for type");
-        }
-        align(2);
-        mData[mPos++] = (byte)(v & 0xff);
-        mData[mPos++] = (byte)(v >> 8);
-    }
-
-    public void addU32(long v) {
-        if ((v < 0) || (v > 0xffffffffL)) {
-            android.util.Log.e("rs", "FieldPacker.addU32( " + v + " )");
-            throw new IllegalArgumentException("Saving value out of range for type");
-        }
-        align(4);
-        mData[mPos++] = (byte)(v & 0xff);
-        mData[mPos++] = (byte)((v >> 8) & 0xff);
-        mData[mPos++] = (byte)((v >> 16) & 0xff);
-        mData[mPos++] = (byte)((v >> 24) & 0xff);
-    }
-
-    public void addU64(long v) {
-        if (v < 0) {
-            android.util.Log.e("rs", "FieldPacker.addU64( " + v + " )");
-            throw new IllegalArgumentException("Saving value out of range for type");
-        }
-        align(8);
-        mData[mPos++] = (byte)(v & 0xff);
-        mData[mPos++] = (byte)((v >> 8) & 0xff);
-        mData[mPos++] = (byte)((v >> 16) & 0xff);
-        mData[mPos++] = (byte)((v >> 24) & 0xff);
-        mData[mPos++] = (byte)((v >> 32) & 0xff);
-        mData[mPos++] = (byte)((v >> 40) & 0xff);
-        mData[mPos++] = (byte)((v >> 48) & 0xff);
-        mData[mPos++] = (byte)((v >> 56) & 0xff);
-    }
-
-    public void addF32(float v) {
-        addI32(Float.floatToRawIntBits(v));
-    }
-
-    public float subF32() {
-        return Float.intBitsToFloat(subI32());
-    }
-
-    public void addF64(double v) {
-        addI64(Double.doubleToRawLongBits(v));
-    }
-
-    public double subF64() {
-        return Double.longBitsToDouble(subI64());
-    }
-
-    public void addObj(BaseObj obj) {
-        if (obj != null) {
-            if (RenderScript.sPointerSize == 8) {
-                addI64(obj.getID(null));
-                addI64(0);
-                addI64(0);
-                addI64(0);
-            } else {
-                addI32((int)obj.getID(null));
-            }
-        } else {
-            if (RenderScript.sPointerSize == 8) {
-                addI64(0);
-                addI64(0);
-                addI64(0);
-                addI64(0);
-            } else {
-                addI32(0);
-            }
-        }
-    }
-
-    public void addF32(Float2 v) {
-        addF32(v.x);
-        addF32(v.y);
-    }
-    public void addF32(Float3 v) {
-        addF32(v.x);
-        addF32(v.y);
-        addF32(v.z);
-    }
-    public void addF32(Float4 v) {
-        addF32(v.x);
-        addF32(v.y);
-        addF32(v.z);
-        addF32(v.w);
-    }
-
-    public void addF64(Double2 v) {
-        addF64(v.x);
-        addF64(v.y);
-    }
-    public void addF64(Double3 v) {
-        addF64(v.x);
-        addF64(v.y);
-        addF64(v.z);
-    }
-    public void addF64(Double4 v) {
-        addF64(v.x);
-        addF64(v.y);
-        addF64(v.z);
-        addF64(v.w);
-    }
-
-    public void addI8(Byte2 v) {
-        addI8(v.x);
-        addI8(v.y);
-    }
-    public void addI8(Byte3 v) {
-        addI8(v.x);
-        addI8(v.y);
-        addI8(v.z);
-    }
-    public void addI8(Byte4 v) {
-        addI8(v.x);
-        addI8(v.y);
-        addI8(v.z);
-        addI8(v.w);
-    }
-
-    public void addU8(Short2 v) {
-        addU8(v.x);
-        addU8(v.y);
-    }
-    public void addU8(Short3 v) {
-        addU8(v.x);
-        addU8(v.y);
-        addU8(v.z);
-    }
-    public void addU8(Short4 v) {
-        addU8(v.x);
-        addU8(v.y);
-        addU8(v.z);
-        addU8(v.w);
-    }
-
-    public void addI16(Short2 v) {
-        addI16(v.x);
-        addI16(v.y);
-    }
-    public void addI16(Short3 v) {
-        addI16(v.x);
-        addI16(v.y);
-        addI16(v.z);
-    }
-    public void addI16(Short4 v) {
-        addI16(v.x);
-        addI16(v.y);
-        addI16(v.z);
-        addI16(v.w);
-    }
-
-    public void addU16(Int2 v) {
-        addU16(v.x);
-        addU16(v.y);
-    }
-    public void addU16(Int3 v) {
-        addU16(v.x);
-        addU16(v.y);
-        addU16(v.z);
-    }
-    public void addU16(Int4 v) {
-        addU16(v.x);
-        addU16(v.y);
-        addU16(v.z);
-        addU16(v.w);
-    }
-
-    public void addI32(Int2 v) {
-        addI32(v.x);
-        addI32(v.y);
-    }
-    public void addI32(Int3 v) {
-        addI32(v.x);
-        addI32(v.y);
-        addI32(v.z);
-    }
-    public void addI32(Int4 v) {
-        addI32(v.x);
-        addI32(v.y);
-        addI32(v.z);
-        addI32(v.w);
-    }
-
-    public void addU32(Long2 v) {
-        addU32(v.x);
-        addU32(v.y);
-    }
-    public void addU32(Long3 v) {
-        addU32(v.x);
-        addU32(v.y);
-        addU32(v.z);
-    }
-    public void addU32(Long4 v) {
-        addU32(v.x);
-        addU32(v.y);
-        addU32(v.z);
-        addU32(v.w);
-    }
-
-    public void addI64(Long2 v) {
-        addI64(v.x);
-        addI64(v.y);
-    }
-    public void addI64(Long3 v) {
-        addI64(v.x);
-        addI64(v.y);
-        addI64(v.z);
-    }
-    public void addI64(Long4 v) {
-        addI64(v.x);
-        addI64(v.y);
-        addI64(v.z);
-        addI64(v.w);
-    }
-
-    public void addU64(Long2 v) {
-        addU64(v.x);
-        addU64(v.y);
-    }
-    public void addU64(Long3 v) {
-        addU64(v.x);
-        addU64(v.y);
-        addU64(v.z);
-    }
-    public void addU64(Long4 v) {
-        addU64(v.x);
-        addU64(v.y);
-        addU64(v.z);
-        addU64(v.w);
-    }
-
-
-    public Float2 subFloat2() {
-        Float2 v = new Float2();
-        v.y = subF32();
-        v.x = subF32();
-        return v;
-    }
-    public Float3 subFloat3() {
-        Float3 v = new Float3();
-        v.z = subF32();
-        v.y = subF32();
-        v.x = subF32();
-        return v;
-    }
-    public Float4 subFloat4() {
-        Float4 v = new Float4();
-        v.w = subF32();
-        v.z = subF32();
-        v.y = subF32();
-        v.x = subF32();
-        return v;
-    }
-
-    public Double2 subDouble2() {
-        Double2 v = new Double2();
-        v.y = subF64();
-        v.x = subF64();
-        return v;
-    }
-    public Double3 subDouble3() {
-        Double3 v = new Double3();
-        v.z = subF64();
-        v.y = subF64();
-        v.x = subF64();
-        return v;
-    }
-    public Double4 subDouble4() {
-        Double4 v = new Double4();
-        v.w = subF64();
-        v.z = subF64();
-        v.y = subF64();
-        v.x = subF64();
-        return v;
-    }
-
-    public Byte2 subByte2() {
-        Byte2 v = new Byte2();
-        v.y = subI8();
-        v.x = subI8();
-        return v;
-    }
-    public Byte3 subByte3() {
-        Byte3 v = new Byte3();
-        v.z = subI8();
-        v.y = subI8();
-        v.x = subI8();
-        return v;
-    }
-    public Byte4 subByte4() {
-        Byte4 v = new Byte4();
-        v.w = subI8();
-        v.z = subI8();
-        v.y = subI8();
-        v.x = subI8();
-        return v;
-    }
-
-    public Short2 subShort2() {
-        Short2 v = new Short2();
-        v.y = subI16();
-        v.x = subI16();
-        return v;
-    }
-    public Short3 subShort3() {
-        Short3 v = new Short3();
-        v.z = subI16();
-        v.y = subI16();
-        v.x = subI16();
-        return v;
-    }
-    public Short4 subShort4() {
-        Short4 v = new Short4();
-        v.w = subI16();
-        v.z = subI16();
-        v.y = subI16();
-        v.x = subI16();
-        return v;
-    }
-
-    public Int2 subInt2() {
-        Int2 v = new Int2();
-        v.y = subI32();
-        v.x = subI32();
-        return v;
-    }
-    public Int3 subInt3() {
-        Int3 v = new Int3();
-        v.z = subI32();
-        v.y = subI32();
-        v.x = subI32();
-        return v;
-    }
-    public Int4 subInt4() {
-        Int4 v = new Int4();
-        v.w = subI32();
-        v.z = subI32();
-        v.y = subI32();
-        v.x = subI32();
-        return v;
-    }
-
-    public Long2 subLong2() {
-        Long2 v = new Long2();
-        v.y = subI64();
-        v.x = subI64();
-        return v;
-    }
-    public Long3 subLong3() {
-        Long3 v = new Long3();
-        v.z = subI64();
-        v.y = subI64();
-        v.x = subI64();
-        return v;
-    }
-    public Long4 subLong4() {
-        Long4 v = new Long4();
-        v.w = subI64();
-        v.z = subI64();
-        v.y = subI64();
-        v.x = subI64();
-        return v;
-    }
-
-
-
-    public void addMatrix(Matrix4f v) {
-        for (int i=0; i < v.mMat.length; i++) {
-            addF32(v.mMat[i]);
-        }
-    }
-
-    public Matrix4f subMatrix4f() {
-        Matrix4f v = new Matrix4f();
-        for (int i = v.mMat.length - 1; i >= 0; i--) {
-            v.mMat[i] = subF32();
-        }
-        return v;
-    }
-
-    public void addMatrix(Matrix3f v) {
-        for (int i=0; i < v.mMat.length; i++) {
-            addF32(v.mMat[i]);
-        }
-    }
-
-    public Matrix3f subMatrix3f() {
-        Matrix3f v = new Matrix3f();
-        for (int i = v.mMat.length - 1; i >= 0; i--) {
-            v.mMat[i] = subF32();
-        }
-        return v;
-    }
-
-    public void addMatrix(Matrix2f v) {
-        for (int i=0; i < v.mMat.length; i++) {
-            addF32(v.mMat[i]);
-        }
-    }
-
-    public Matrix2f subMatrix2f() {
-        Matrix2f v = new Matrix2f();
-        for (int i = v.mMat.length - 1; i >= 0; i--) {
-            v.mMat[i] = subF32();
-        }
-        return v;
-    }
-
-    public void addBoolean(boolean v) {
-        addI8((byte)(v ? 1 : 0));
-    }
-
-    public boolean subBoolean() {
-        byte v = subI8();
-        if (v == 1) {
-            return true;
-        }
-        return false;
-    }
-
-    public final byte[] getData() {
-        return mData;
-    }
-
-    /**
-     * Get the actual length used for the FieldPacker.
-     *
-     * @hide
-     */
-    public int getPos() {
-        return mPos;
-    }
-
-    private static void addToPack(FieldPacker fp, Object obj) {
-        if (obj instanceof Boolean) {
-            fp.addBoolean(((Boolean)obj).booleanValue());
-            return;
-        }
-
-        if (obj instanceof Byte) {
-            fp.addI8(((Byte)obj).byteValue());
-            return;
-        }
-
-        if (obj instanceof Short) {
-            fp.addI16(((Short)obj).shortValue());
-            return;
-        }
-
-        if (obj instanceof Integer) {
-            fp.addI32(((Integer)obj).intValue());
-            return;
-        }
-
-        if (obj instanceof Long) {
-            fp.addI64(((Long)obj).longValue());
-            return;
-        }
-
-        if (obj instanceof Float) {
-            fp.addF32(((Float)obj).floatValue());
-            return;
-        }
-
-        if (obj instanceof Double) {
-            fp.addF64(((Double)obj).doubleValue());
-            return;
-        }
-
-        if (obj instanceof Byte2) {
-            fp.addI8((Byte2)obj);
-            return;
-        }
-
-        if (obj instanceof Byte3) {
-            fp.addI8((Byte3)obj);
-            return;
-        }
-
-        if (obj instanceof Byte4) {
-            fp.addI8((Byte4)obj);
-            return;
-        }
-
-        if (obj instanceof Short2) {
-            fp.addI16((Short2)obj);
-            return;
-        }
-
-        if (obj instanceof Short3) {
-            fp.addI16((Short3)obj);
-            return;
-        }
-
-        if (obj instanceof Short4) {
-            fp.addI16((Short4)obj);
-            return;
-        }
-
-        if (obj instanceof Int2) {
-            fp.addI32((Int2)obj);
-            return;
-        }
-
-        if (obj instanceof Int3) {
-            fp.addI32((Int3)obj);
-            return;
-        }
-
-        if (obj instanceof Int4) {
-            fp.addI32((Int4)obj);
-            return;
-        }
-
-        if (obj instanceof Long2) {
-            fp.addI64((Long2)obj);
-            return;
-        }
-
-        if (obj instanceof Long3) {
-            fp.addI64((Long3)obj);
-            return;
-        }
-
-        if (obj instanceof Long4) {
-            fp.addI64((Long4)obj);
-            return;
-        }
-
-        if (obj instanceof Float2) {
-            fp.addF32((Float2)obj);
-            return;
-        }
-
-        if (obj instanceof Float3) {
-            fp.addF32((Float3)obj);
-            return;
-        }
-
-        if (obj instanceof Float4) {
-            fp.addF32((Float4)obj);
-            return;
-        }
-
-        if (obj instanceof Double2) {
-            fp.addF64((Double2)obj);
-            return;
-        }
-
-        if (obj instanceof Double3) {
-            fp.addF64((Double3)obj);
-            return;
-        }
-
-        if (obj instanceof Double4) {
-            fp.addF64((Double4)obj);
-            return;
-        }
-
-        if (obj instanceof Matrix2f) {
-            fp.addMatrix((Matrix2f)obj);
-            return;
-        }
-
-        if (obj instanceof Matrix3f) {
-            fp.addMatrix((Matrix3f)obj);
-            return;
-        }
-
-        if (obj instanceof Matrix4f) {
-            fp.addMatrix((Matrix4f)obj);
-            return;
-        }
-
-        if (obj instanceof BaseObj) {
-            fp.addObj((BaseObj)obj);
-            return;
-        }
-    }
-
-    private static int getPackedSize(Object obj) {
-        if (obj instanceof Boolean) {
-            return 1;
-        }
-
-        if (obj instanceof Byte) {
-            return 1;
-        }
-
-        if (obj instanceof Short) {
-            return 2;
-        }
-
-        if (obj instanceof Integer) {
-            return 4;
-        }
-
-        if (obj instanceof Long) {
-            return 8;
-        }
-
-        if (obj instanceof Float) {
-            return 4;
-        }
-
-        if (obj instanceof Double) {
-            return 8;
-        }
-
-        if (obj instanceof Byte2) {
-            return 2;
-        }
-
-        if (obj instanceof Byte3) {
-            return 3;
-        }
-
-        if (obj instanceof Byte4) {
-            return 4;
-        }
-
-        if (obj instanceof Short2) {
-            return 4;
-        }
-
-        if (obj instanceof Short3) {
-            return 6;
-        }
-
-        if (obj instanceof Short4) {
-            return 8;
-        }
-
-        if (obj instanceof Int2) {
-            return 8;
-        }
-
-        if (obj instanceof Int3) {
-            return 12;
-        }
-
-        if (obj instanceof Int4) {
-            return 16;
-        }
-
-        if (obj instanceof Long2) {
-            return 16;
-        }
-
-        if (obj instanceof Long3) {
-            return 24;
-        }
-
-        if (obj instanceof Long4) {
-            return 32;
-        }
-
-        if (obj instanceof Float2) {
-            return 8;
-        }
-
-        if (obj instanceof Float3) {
-            return 12;
-        }
-
-        if (obj instanceof Float4) {
-            return 16;
-        }
-
-        if (obj instanceof Double2) {
-            return 16;
-        }
-
-        if (obj instanceof Double3) {
-            return 24;
-        }
-
-        if (obj instanceof Double4) {
-            return 32;
-        }
-
-        if (obj instanceof Matrix2f) {
-            return 16;
-        }
-
-        if (obj instanceof Matrix3f) {
-            return 36;
-        }
-
-        if (obj instanceof Matrix4f) {
-            return 64;
-        }
-
-        if (obj instanceof BaseObj) {
-            if (RenderScript.sPointerSize == 8) {
-                return 32;
-            } else {
-                return 4;
-            }
-        }
-
-        return 0;
-    }
-
-    static FieldPacker createFieldPack(Object[] args) {
-        int len = 0;
-        for (Object arg : args) {
-            len += getPackedSize(arg);
-        }
-        FieldPacker fp = new FieldPacker(len);
-        for (Object arg : args) {
-            addToPack(fp, arg);
-        }
-        return fp;
-    }
-
-
-    private boolean resize(int newSize) {
-        if (newSize == mLen) {
-            return false;
-        }
-
-        byte[] newData = new byte[newSize];
-        System.arraycopy(mData, 0, newData, 0, mPos);
-        mData = newData;
-        mLen = newSize;
-        return true;
-    }
-
-    private void addSafely(Object obj) {
-        boolean retry;
-        final int oldPos = mPos;
-        do {
-            retry = false;
-            try {
-                addToPack(this, obj);
-            } catch (ArrayIndexOutOfBoundsException e) {
-                mPos = oldPos;
-                resize(mLen * 2);
-                retry = true;
-            }
-        } while (retry);
-    }
-
-    private byte mData[];
-    private int mPos;
-    private int mLen;
-    private BitSet mAlignment;
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Float2.java b/v8/renderscript/java/src/android/support/v8/renderscript/Float2.java
deleted file mode 100644
index edbc5aa..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Float2.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript float2 type back to the Android system.
- *
- **/
-public class Float2 {
-    public Float2() {
-    }
-
-    public Float2(float initX, float initY) {
-        x = initX;
-        y = initY;
-    }
-
-    public float x;
-    public float y;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Float3.java b/v8/renderscript/java/src/android/support/v8/renderscript/Float3.java
deleted file mode 100644
index 90162a1..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Float3.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript float2 type back to the Android system.
- *
- **/
-public class Float3 {
-    public Float3() {
-    }
-    public Float3(float initX, float initY, float initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
-    public float x;
-    public float y;
-    public float z;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Float4.java b/v8/renderscript/java/src/android/support/v8/renderscript/Float4.java
deleted file mode 100644
index d0dc568..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Float4.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript float2 type back to the Android system.
- *
- **/
-public class Float4 {
-    public Float4() {
-    }
-
-    public Float4(float initX, float initY, float initZ, float initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
-    public float x;
-    public float y;
-    public float z;
-    public float w;
-}
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Int2.java b/v8/renderscript/java/src/android/support/v8/renderscript/Int2.java
deleted file mode 100644
index e5d04b8..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Int2.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript int2 type back to the Android system.
- *
- **/
-public class Int2 {
-    public Int2() {
-    }
-
-    public Int2(int initX, int initY) {
-        x = initX;
-        y = initY;
-    }
-
-    public int x;
-    public int y;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Int3.java b/v8/renderscript/java/src/android/support/v8/renderscript/Int3.java
deleted file mode 100644
index 12f59e8..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Int3.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript int3 type back to the Android system.
- *
- **/
-public class Int3 {
-    public Int3() {
-    }
-
-    public Int3(int initX, int initY, int initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
-    public int x;
-    public int y;
-    public int z;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Int4.java b/v8/renderscript/java/src/android/support/v8/renderscript/Int4.java
deleted file mode 100644
index bb49fb1..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Int4.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript int4 type back to the Android system.
- *
- **/
-public class Int4 {
-    public Int4() {
-    }
-
-    public Int4(int initX, int initY, int initZ, int initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
-    public int x;
-    public int y;
-    public int z;
-    public int w;
-}
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Long2.java b/v8/renderscript/java/src/android/support/v8/renderscript/Long2.java
deleted file mode 100644
index b3c95f2..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Long2.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript long2 type back to the Android system.
- **/
-public class Long2 {
-    public Long2() {
-    }
-
-    public Long2(long initX, long initY) {
-        x = initX;
-        y = initY;
-    }
-
-    public long x;
-    public long y;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Long3.java b/v8/renderscript/java/src/android/support/v8/renderscript/Long3.java
deleted file mode 100644
index 6ce0f83..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Long3.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript long3 type back to the Android system.
- **/
-public class Long3 {
-    public Long3() {
-    }
-
-    public Long3(long initX, long initY, long initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
-    public long x;
-    public long y;
-    public long z;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Long4.java b/v8/renderscript/java/src/android/support/v8/renderscript/Long4.java
deleted file mode 100644
index d44a321..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Long4.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript long4 type back to the Android system.
- **/
-public class Long4 {
-    public Long4() {
-    }
-
-    public Long4(long initX, long initY, long initZ, long initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
-    public long x;
-    public long y;
-    public long z;
-    public long w;
-}
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Matrix2f.java b/v8/renderscript/java/src/android/support/v8/renderscript/Matrix2f.java
deleted file mode 100644
index 9a8b5bf..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Matrix2f.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2009-2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript rs_matrix2x2 type back to the Android system.
- *
- **/
-public class Matrix2f {
-
-    /**
-    * Creates a new identity 2x2 matrix
-    */
-    public Matrix2f() {
-        mMat = new float[4];
-        loadIdentity();
-    }
-
-    /**
-    * Creates a new matrix and sets its values from the given
-    * parameter
-    *
-    * @param dataArray values to set the matrix to, must be 4
-    *                  floats long
-    */
-    public Matrix2f(float[] dataArray) {
-        mMat = new float[4];
-        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
-    }
-
-    /**
-    * Return a reference to the internal array representing matrix
-    * values. Modifying this array will also change the matrix
-    *
-    * @return internal array representing the matrix
-    */
-    public float[] getArray() {
-        return mMat;
-    }
-
-    /**
-    * Returns the value for a given row and column
-    *
-    * @param x column of the value to return
-    * @param y row of the value to return
-    *
-    * @return value in the yth row and xth column
-    */
-    public float get(int x, int y) {
-        return mMat[x*2 + y];
-    }
-
-    /**
-    * Sets the value for a given row and column
-    *
-    * @param x column of the value to set
-    * @param y row of the value to set
-    */
-    public void set(int x, int y, float v) {
-        mMat[x*2 + y] = v;
-    }
-
-    /**
-    * Sets the matrix values to identity
-    */
-    public void loadIdentity() {
-        mMat[0] = 1;
-        mMat[1] = 0;
-
-        mMat[2] = 0;
-        mMat[3] = 1;
-    }
-
-    /**
-    * Sets the values of the matrix to those of the parameter
-    *
-    * @param src matrix to load the values from
-    */
-    public void load(Matrix2f src) {
-        System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
-    }
-
-    /**
-    * Sets current values to be a rotation matrix of given angle
-    *
-    * @param rot rotation angle
-    */
-    public void loadRotate(float rot) {
-        float c, s;
-        rot *= (float)(java.lang.Math.PI / 180.0f);
-        c = (float)java.lang.Math.cos(rot);
-        s = (float)java.lang.Math.sin(rot);
-        mMat[0] = c;
-        mMat[1] = -s;
-        mMat[2] = s;
-        mMat[3] = c;
-    }
-
-    /**
-    * Sets current values to be a scale matrix of given dimensions
-    *
-    * @param x scale component x
-    * @param y scale component y
-    */
-    public void loadScale(float x, float y) {
-        loadIdentity();
-        mMat[0] = x;
-        mMat[3] = y;
-    }
-
-    /**
-    * Sets current values to be the result of multiplying two given
-    * matrices
-    *
-    * @param lhs left hand side matrix
-    * @param rhs right hand side matrix
-    */
-    public void loadMultiply(Matrix2f lhs, Matrix2f rhs) {
-        for (int i=0 ; i<2 ; i++) {
-            float ri0 = 0;
-            float ri1 = 0;
-            for (int j=0 ; j<2 ; j++) {
-                float rhs_ij = rhs.get(i,j);
-                ri0 += lhs.get(j,0) * rhs_ij;
-                ri1 += lhs.get(j,1) * rhs_ij;
-            }
-            set(i,0, ri0);
-            set(i,1, ri1);
-        }
-    }
-
-    /**
-    * Post-multiplies the current matrix by a given parameter
-    *
-    * @param rhs right hand side to multiply by
-    */
-    public void multiply(Matrix2f rhs) {
-        Matrix2f tmp = new Matrix2f();
-        tmp.loadMultiply(this, rhs);
-        load(tmp);
-    }
-    /**
-    * Modifies the current matrix by post-multiplying it with a
-    * rotation matrix of given angle
-    *
-    * @param rot angle of rotation
-    */
-    public void rotate(float rot) {
-        Matrix2f tmp = new Matrix2f();
-        tmp.loadRotate(rot);
-        multiply(tmp);
-    }
-    /**
-    * Modifies the current matrix by post-multiplying it with a
-    * scale matrix of given dimensions
-    *
-    * @param x scale component x
-    * @param y scale component y
-    */
-    public void scale(float x, float y) {
-        Matrix2f tmp = new Matrix2f();
-        tmp.loadScale(x, y);
-        multiply(tmp);
-    }
-    /**
-    * Sets the current matrix to its transpose
-    */
-    public void transpose() {
-        float temp = mMat[1];
-        mMat[1] = mMat[2];
-        mMat[2] = temp;
-    }
-
-    final float[] mMat;
-}
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Matrix3f.java b/v8/renderscript/java/src/android/support/v8/renderscript/Matrix3f.java
deleted file mode 100644
index 4528543..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Matrix3f.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2009-2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system.
- *
- **/
-public class Matrix3f {
-
-    /**
-    * Creates a new identity 3x3 matrix
-    */
-    public Matrix3f() {
-        mMat = new float[9];
-        loadIdentity();
-    }
-
-    /**
-    * Creates a new matrix and sets its values from the given
-    * parameter
-    *
-    * @param dataArray values to set the matrix to, must be 9
-    *                  floats long
-    */
-    public Matrix3f(float[] dataArray) {
-        mMat = new float[9];
-        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
-    }
-
-    /**
-    * Return a reference to the internal array representing matrix
-    * values. Modifying this array will also change the matrix
-    *
-    * @return internal array representing the matrix
-    */
-    public float[] getArray() {
-        return mMat;
-    }
-
-    /**
-    * Returns the value for a given row and column
-    *
-    * @param x column of the value to return
-    * @param y row of the value to return
-    *
-    * @return value in the yth row and xth column
-    */
-    public float get(int x, int y) {
-        return mMat[x*3 + y];
-    }
-
-    /**
-    * Sets the value for a given row and column
-    *
-    * @param x column of the value to set
-    * @param y row of the value to set
-    */
-    public void set(int x, int y, float v) {
-        mMat[x*3 + y] = v;
-    }
-
-    /**
-    * Sets the matrix values to identity
-    */
-    public void loadIdentity() {
-        mMat[0] = 1;
-        mMat[1] = 0;
-        mMat[2] = 0;
-
-        mMat[3] = 0;
-        mMat[4] = 1;
-        mMat[5] = 0;
-
-        mMat[6] = 0;
-        mMat[7] = 0;
-        mMat[8] = 1;
-    }
-
-    /**
-    * Sets the values of the matrix to those of the parameter
-    *
-    * @param src matrix to load the values from
-    */
-    public void load(Matrix3f src) {
-        System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
-    }
-
-    /**
-    * Sets current values to be a rotation matrix of certain angle
-    * about a given axis
-    *
-    * @param rot angle of rotation
-    * @param x rotation axis x
-    * @param y rotation axis y
-    * @param z rotation axis z
-    */
-    public void loadRotate(float rot, float x, float y, float z) {
-        float c, s;
-        rot *= (float)(java.lang.Math.PI / 180.0f);
-        c = (float)java.lang.Math.cos(rot);
-        s = (float)java.lang.Math.sin(rot);
-
-        float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
-        if (!(len != 1)) {
-            float recipLen = 1.f / len;
-            x *= recipLen;
-            y *= recipLen;
-            z *= recipLen;
-        }
-        float nc = 1.0f - c;
-        float xy = x * y;
-        float yz = y * z;
-        float zx = z * x;
-        float xs = x * s;
-        float ys = y * s;
-        float zs = z * s;
-        mMat[0] = x*x*nc +  c;
-        mMat[3] =  xy*nc - zs;
-        mMat[6] =  zx*nc + ys;
-        mMat[1] =  xy*nc + zs;
-        mMat[4] = y*y*nc +  c;
-        mMat[7] =  yz*nc - xs;
-        mMat[2] =  zx*nc - ys;
-        mMat[5] =  yz*nc + xs;
-        mMat[8] = z*z*nc +  c;
-    }
-
-    /**
-    * Makes the upper 2x2 a rotation matrix of the given angle
-    *
-    * @param rot rotation angle
-    */
-    public void loadRotate(float rot) {
-        loadIdentity();
-        float c, s;
-        rot *= (float)(java.lang.Math.PI / 180.0f);
-        c = (float)java.lang.Math.cos(rot);
-        s = (float)java.lang.Math.sin(rot);
-        mMat[0] = c;
-        mMat[1] = -s;
-        mMat[3] = s;
-        mMat[4] = c;
-    }
-
-    /**
-    * Makes the upper 2x2 a scale matrix of given dimensions
-    *
-    * @param x scale component x
-    * @param y scale component y
-    */
-    public void loadScale(float x, float y) {
-        loadIdentity();
-        mMat[0] = x;
-        mMat[4] = y;
-    }
-
-    /**
-    * Sets current values to be a scale matrix of given dimensions
-    *
-    * @param x scale component x
-    * @param y scale component y
-    * @param z scale component z
-    */
-    public void loadScale(float x, float y, float z) {
-        loadIdentity();
-        mMat[0] = x;
-        mMat[4] = y;
-        mMat[8] = z;
-    }
-
-    /**
-    * Sets current values to be a translation matrix of given
-    * dimensions
-    *
-    * @param x translation component x
-    * @param y translation component y
-    */
-    public void loadTranslate(float x, float y) {
-        loadIdentity();
-        mMat[6] = x;
-        mMat[7] = y;
-    }
-
-    /**
-    * Sets current values to be the result of multiplying two given
-    * matrices
-    *
-    * @param lhs left hand side matrix
-    * @param rhs right hand side matrix
-    */
-    public void loadMultiply(Matrix3f lhs, Matrix3f rhs) {
-        for (int i=0 ; i<3 ; i++) {
-            float ri0 = 0;
-            float ri1 = 0;
-            float ri2 = 0;
-            for (int j=0 ; j<3 ; j++) {
-                float rhs_ij = rhs.get(i,j);
-                ri0 += lhs.get(j,0) * rhs_ij;
-                ri1 += lhs.get(j,1) * rhs_ij;
-                ri2 += lhs.get(j,2) * rhs_ij;
-            }
-            set(i,0, ri0);
-            set(i,1, ri1);
-            set(i,2, ri2);
-        }
-    }
-
-    /**
-    * Post-multiplies the current matrix by a given parameter
-    *
-    * @param rhs right hand side to multiply by
-    */
-    public void multiply(Matrix3f rhs) {
-        Matrix3f tmp = new Matrix3f();
-        tmp.loadMultiply(this, rhs);
-        load(tmp);
-    }
-
-    /**
-    * Modifies the current matrix by post-multiplying it with a
-    * rotation matrix of certain angle about a given axis
-    *
-    * @param rot angle of rotation
-    * @param x rotation axis x
-    * @param y rotation axis y
-    * @param z rotation axis z
-    */
-    public void rotate(float rot, float x, float y, float z) {
-        Matrix3f tmp = new Matrix3f();
-        tmp.loadRotate(rot, x, y, z);
-        multiply(tmp);
-    }
-
-    /**
-    * Modifies the upper 2x2 of the current matrix by
-    * post-multiplying it with a rotation matrix of given angle
-    *
-    * @param rot angle of rotation
-    */
-    public void rotate(float rot) {
-        Matrix3f tmp = new Matrix3f();
-        tmp.loadRotate(rot);
-        multiply(tmp);
-    }
-
-    /**
-    * Modifies the upper 2x2 of the current matrix by
-    * post-multiplying it with a scale matrix of given dimensions
-    *
-    * @param x scale component x
-    * @param y scale component y
-    */
-    public void scale(float x, float y) {
-        Matrix3f tmp = new Matrix3f();
-        tmp.loadScale(x, y);
-        multiply(tmp);
-    }
-
-    /**
-    * Modifies the current matrix by post-multiplying it with a
-    * scale matrix of given dimensions
-    *
-    * @param x scale component x
-    * @param y scale component y
-    * @param z scale component z
-    */
-    public void scale(float x, float y, float z) {
-        Matrix3f tmp = new Matrix3f();
-        tmp.loadScale(x, y, z);
-        multiply(tmp);
-    }
-
-    /**
-    * Modifies the current matrix by post-multiplying it with a
-    * translation matrix of given dimensions
-    *
-    * @param x translation component x
-    * @param y translation component y
-    */
-    public void translate(float x, float y) {
-        Matrix3f tmp = new Matrix3f();
-        tmp.loadTranslate(x, y);
-        multiply(tmp);
-    }
-
-    /**
-    * Sets the current matrix to its transpose
-    */
-    public void transpose() {
-        for(int i = 0; i < 2; ++i) {
-            for(int j = i + 1; j < 3; ++j) {
-                float temp = mMat[i*3 + j];
-                mMat[i*3 + j] = mMat[j*3 + i];
-                mMat[j*3 + i] = temp;
-            }
-        }
-    }
-
-    final float[] mMat;
-}
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Matrix4f.java b/v8/renderscript/java/src/android/support/v8/renderscript/Matrix4f.java
deleted file mode 100644
index b9e5636..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Matrix4f.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2009-2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
- *
- **/
-public class Matrix4f {
-
-    /**
-    * Creates a new identity 4x4 matrix
-    */
-    public Matrix4f() {
-        mMat = new float[16];
-        loadIdentity();
-    }
-
-    /**
-    * Creates a new matrix and sets its values from the given
-    * parameter
-    *
-    * @param dataArray values to set the matrix to, must be 16
-    *                  floats long
-    */
-    public Matrix4f(float[] dataArray) {
-        mMat = new float[16];
-        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
-    }
-
-    /**
-    * Return a reference to the internal array representing matrix
-    * values. Modifying this array will also change the matrix
-    *
-    * @return internal array representing the matrix
-    */
-    public float[] getArray() {
-        return mMat;
-    }
-
-    /**
-    * Returns the value for a given row and column
-    *
-    * @param x column of the value to return
-    * @param y row of the value to return
-    *
-    * @return value in the yth row and xth column
-    */
-    public float get(int x, int y) {
-        return mMat[x*4 + y];
-    }
-
-    /**
-    * Sets the value for a given row and column
-    *
-    * @param x column of the value to set
-    * @param y row of the value to set
-    */
-    public void set(int x, int y, float v) {
-        mMat[x*4 + y] = v;
-    }
-
-    /**
-    * Sets the matrix values to identity
-    */
-    public void loadIdentity() {
-        mMat[0] = 1;
-        mMat[1] = 0;
-        mMat[2] = 0;
-        mMat[3] = 0;
-
-        mMat[4] = 0;
-        mMat[5] = 1;
-        mMat[6] = 0;
-        mMat[7] = 0;
-
-        mMat[8] = 0;
-        mMat[9] = 0;
-        mMat[10] = 1;
-        mMat[11] = 0;
-
-        mMat[12] = 0;
-        mMat[13] = 0;
-        mMat[14] = 0;
-        mMat[15] = 1;
-    }
-
-    /**
-    * Sets the values of the matrix to those of the parameter
-    *
-    * @param src matrix to load the values from
-    */
-    public void load(Matrix4f src) {
-        System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
-    }
-
-    /**
-    * Sets the values of the matrix to those of the parameter
-    *
-    * @param src matrix to load the values from
-    * @hide
-    */
-    public void load(Matrix3f src) {
-        mMat[0] = src.mMat[0];
-        mMat[1] = src.mMat[1];
-        mMat[2] = src.mMat[2];
-        mMat[3] = 0;
-
-        mMat[4] = src.mMat[3];
-        mMat[5] = src.mMat[4];
-        mMat[6] = src.mMat[5];
-        mMat[7] = 0;
-
-        mMat[8] = src.mMat[6];
-        mMat[9] = src.mMat[7];
-        mMat[10] = src.mMat[8];
-        mMat[11] = 0;
-
-        mMat[12] = 0;
-        mMat[13] = 0;
-        mMat[14] = 0;
-        mMat[15] = 1;
-    }
-
-    /**
-    * Sets current values to be a rotation matrix of certain angle
-    * about a given axis
-    *
-    * @param rot angle of rotation
-    * @param x rotation axis x
-    * @param y rotation axis y
-    * @param z rotation axis z
-    */
-    public void loadRotate(float rot, float x, float y, float z) {
-        float c, s;
-        mMat[3] = 0;
-        mMat[7] = 0;
-        mMat[11]= 0;
-        mMat[12]= 0;
-        mMat[13]= 0;
-        mMat[14]= 0;
-        mMat[15]= 1;
-        rot *= (float)(java.lang.Math.PI / 180.0f);
-        c = (float)java.lang.Math.cos(rot);
-        s = (float)java.lang.Math.sin(rot);
-
-        float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
-        if (!(len != 1)) {
-            float recipLen = 1.f / len;
-            x *= recipLen;
-            y *= recipLen;
-            z *= recipLen;
-        }
-        float nc = 1.0f - c;
-        float xy = x * y;
-        float yz = y * z;
-        float zx = z * x;
-        float xs = x * s;
-        float ys = y * s;
-        float zs = z * s;
-        mMat[ 0] = x*x*nc +  c;
-        mMat[ 4] =  xy*nc - zs;
-        mMat[ 8] =  zx*nc + ys;
-        mMat[ 1] =  xy*nc + zs;
-        mMat[ 5] = y*y*nc +  c;
-        mMat[ 9] =  yz*nc - xs;
-        mMat[ 2] =  zx*nc - ys;
-        mMat[ 6] =  yz*nc + xs;
-        mMat[10] = z*z*nc +  c;
-    }
-
-    /**
-    * Sets current values to be a scale matrix of given dimensions
-    *
-    * @param x scale component x
-    * @param y scale component y
-    * @param z scale component z
-    */
-    public void loadScale(float x, float y, float z) {
-        loadIdentity();
-        mMat[0] = x;
-        mMat[5] = y;
-        mMat[10] = z;
-    }
-
-    /**
-    * Sets current values to be a translation matrix of given
-    * dimensions
-    *
-    * @param x translation component x
-    * @param y translation component y
-    * @param z translation component z
-    */
-    public void loadTranslate(float x, float y, float z) {
-        loadIdentity();
-        mMat[12] = x;
-        mMat[13] = y;
-        mMat[14] = z;
-    }
-
-    /**
-    * Sets current values to be the result of multiplying two given
-    * matrices
-    *
-    * @param lhs left hand side matrix
-    * @param rhs right hand side matrix
-    */
-    public void loadMultiply(Matrix4f lhs, Matrix4f rhs) {
-        for (int i=0 ; i<4 ; i++) {
-            float ri0 = 0;
-            float ri1 = 0;
-            float ri2 = 0;
-            float ri3 = 0;
-            for (int j=0 ; j<4 ; j++) {
-                float rhs_ij = rhs.get(i,j);
-                ri0 += lhs.get(j,0) * rhs_ij;
-                ri1 += lhs.get(j,1) * rhs_ij;
-                ri2 += lhs.get(j,2) * rhs_ij;
-                ri3 += lhs.get(j,3) * rhs_ij;
-            }
-            set(i,0, ri0);
-            set(i,1, ri1);
-            set(i,2, ri2);
-            set(i,3, ri3);
-        }
-    }
-
-    /**
-    * Set current values to be an orthographic projection matrix
-    *
-    * @param l location of the left vertical clipping plane
-    * @param r location of the right vertical clipping plane
-    * @param b location of the bottom horizontal clipping plane
-    * @param t location of the top horizontal clipping plane
-    * @param n location of the near clipping plane
-    * @param f location of the far clipping plane
-    */
-    public void loadOrtho(float l, float r, float b, float t, float n, float f) {
-        loadIdentity();
-        mMat[0] = 2 / (r - l);
-        mMat[5] = 2 / (t - b);
-        mMat[10]= -2 / (f - n);
-        mMat[12]= -(r + l) / (r - l);
-        mMat[13]= -(t + b) / (t - b);
-        mMat[14]= -(f + n) / (f - n);
-    }
-
-    /**
-    * Set current values to be an orthographic projection matrix
-    * with the right and bottom clipping planes set to the given
-    * values. Left and top clipping planes are set to 0. Near and
-    * far are set to -1, 1 respectively
-    *
-    * @param w location of the right vertical clipping plane
-    * @param h location of the bottom horizontal clipping plane
-    *
-    */
-    public void loadOrthoWindow(int w, int h) {
-        loadOrtho(0,w, h,0, -1,1);
-    }
-
-    /**
-    * Sets current values to be a perspective projection matrix
-    *
-    * @param l location of the left vertical clipping plane
-    * @param r location of the right vertical clipping plane
-    * @param b location of the bottom horizontal clipping plane
-    * @param t location of the top horizontal clipping plane
-    * @param n location of the near clipping plane, must be positive
-    * @param f location of the far clipping plane, must be positive
-    *
-    */
-    public void loadFrustum(float l, float r, float b, float t, float n, float f) {
-        loadIdentity();
-        mMat[0] = 2 * n / (r - l);
-        mMat[5] = 2 * n / (t - b);
-        mMat[8] = (r + l) / (r - l);
-        mMat[9] = (t + b) / (t - b);
-        mMat[10]= -(f + n) / (f - n);
-        mMat[11]= -1;
-        mMat[14]= -2*f*n / (f - n);
-        mMat[15]= 0;
-    }
-
-    /**
-    * Sets current values to be a perspective projection matrix
-    *
-    * @param fovy vertical field of view angle in degrees
-    * @param aspect aspect ratio of the screen
-    * @param near near cliping plane, must be positive
-    * @param far far clipping plane, must be positive
-    */
-    public void loadPerspective(float fovy, float aspect, float near, float far) {
-        float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f));
-        float bottom = -top;
-        float left = bottom * aspect;
-        float right = top * aspect;
-        loadFrustum(left, right, bottom, top, near, far);
-    }
-
-    /**
-    * Helper function to set the current values to a perspective
-    * projection matrix with aspect ratio defined by the parameters
-    * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
-    *
-    * @param w screen width
-    * @param h screen height
-    */
-    public void loadProjectionNormalized(int w, int h) {
-        // range -1,1 in the narrow axis at z = 0.
-        Matrix4f m1 = new Matrix4f();
-        Matrix4f m2 = new Matrix4f();
-
-        if(w > h) {
-            float aspect = ((float)w) / h;
-            m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
-        } else {
-            float aspect = ((float)h) / w;
-            m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
-        }
-
-        m2.loadRotate(180, 0, 1, 0);
-        m1.loadMultiply(m1, m2);
-
-        m2.loadScale(-2, 2, 1);
-        m1.loadMultiply(m1, m2);
-
-        m2.loadTranslate(0, 0, 2);
-        m1.loadMultiply(m1, m2);
-
-        load(m1);
-    }
-
-    /**
-    * Post-multiplies the current matrix by a given parameter
-    *
-    * @param rhs right hand side to multiply by
-    */
-    public void multiply(Matrix4f rhs) {
-        Matrix4f tmp = new Matrix4f();
-        tmp.loadMultiply(this, rhs);
-        load(tmp);
-    }
-    /**
-    * Modifies the current matrix by post-multiplying it with a
-    * rotation matrix of certain angle about a given axis
-    *
-    * @param rot angle of rotation
-    * @param x rotation axis x
-    * @param y rotation axis y
-    * @param z rotation axis z
-    */
-    public void rotate(float rot, float x, float y, float z) {
-        Matrix4f tmp = new Matrix4f();
-        tmp.loadRotate(rot, x, y, z);
-        multiply(tmp);
-    }
-
-    /**
-    * Modifies the current matrix by post-multiplying it with a
-    * scale matrix of given dimensions
-    *
-    * @param x scale component x
-    * @param y scale component y
-    * @param z scale component z
-    */
-    public void scale(float x, float y, float z) {
-        Matrix4f tmp = new Matrix4f();
-        tmp.loadScale(x, y, z);
-        multiply(tmp);
-    }
-
-    /**
-    * Modifies the current matrix by post-multiplying it with a
-    * translation matrix of given dimensions
-    *
-    * @param x translation component x
-    * @param y translation component y
-    * @param z translation component z
-    */
-    public void translate(float x, float y, float z) {
-        Matrix4f tmp = new Matrix4f();
-        tmp.loadTranslate(x, y, z);
-        multiply(tmp);
-    }
-    private float computeCofactor(int i, int j) {
-        int c0 = (i+1) % 4;
-        int c1 = (i+2) % 4;
-        int c2 = (i+3) % 4;
-        int r0 = (j+1) % 4;
-        int r1 = (j+2) % 4;
-        int r2 = (j+3) % 4;
-
-        float minor = (mMat[c0 + 4*r0] * (mMat[c1 + 4*r1] * mMat[c2 + 4*r2] -
-                                            mMat[c1 + 4*r2] * mMat[c2 + 4*r1]))
-                     - (mMat[c0 + 4*r1] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r2] -
-                                            mMat[c1 + 4*r2] * mMat[c2 + 4*r0]))
-                     + (mMat[c0 + 4*r2] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r1] -
-                                            mMat[c1 + 4*r1] * mMat[c2 + 4*r0]));
-
-        float cofactor = ((i+j) & 1) != 0 ? -minor : minor;
-        return cofactor;
-    }
-
-    /**
-    * Sets the current matrix to its inverse
-    */
-    public boolean inverse() {
-
-        Matrix4f result = new Matrix4f();
-
-        for (int i = 0; i < 4; ++i) {
-            for (int j = 0; j < 4; ++j) {
-                result.mMat[4*i + j] = computeCofactor(i, j);
-            }
-        }
-
-        // Dot product of 0th column of source and 0th row of result
-        float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[1] +
-                     mMat[8]*result.mMat[2] + mMat[12]*result.mMat[3];
-
-        if (Math.abs(det) < 1e-6) {
-            return false;
-        }
-
-        det = 1.0f / det;
-        for (int i = 0; i < 16; ++i) {
-            mMat[i] = result.mMat[i] * det;
-        }
-
-        return true;
-    }
-
-    /**
-    * Sets the current matrix to its inverse transpose
-    */
-    public boolean inverseTranspose() {
-
-        Matrix4f result = new Matrix4f();
-
-        for (int i = 0; i < 4; ++i) {
-            for (int j = 0; j < 4; ++j) {
-                result.mMat[4*j + i] = computeCofactor(i, j);
-            }
-        }
-
-        float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[4] +
-                     mMat[8]*result.mMat[8] + mMat[12]*result.mMat[12];
-
-        if (Math.abs(det) < 1e-6) {
-            return false;
-        }
-
-        det = 1.0f / det;
-        for (int i = 0; i < 16; ++i) {
-            mMat[i] = result.mMat[i] * det;
-        }
-
-        return true;
-    }
-
-    /**
-    * Sets the current matrix to its transpose
-    */
-    public void transpose() {
-        for(int i = 0; i < 3; ++i) {
-            for(int j = i + 1; j < 4; ++j) {
-                float temp = mMat[i*4 + j];
-                mMat[i*4 + j] = mMat[j*4 + i];
-                mMat[j*4 + i] = temp;
-            }
-        }
-    }
-
-    final float[] mMat;
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/RSDriverException.java b/v8/renderscript/java/src/android/support/v8/renderscript/RSDriverException.java
deleted file mode 100644
index d4ae341..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/RSDriverException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-
-/**
- * Base class for all exceptions thrown by the Android
- * RenderScript
- */
-public class RSDriverException extends RSRuntimeException {
-    public RSDriverException(String string) {
-        super(string);
-    }
-}
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/RSIllegalArgumentException.java b/v8/renderscript/java/src/android/support/v8/renderscript/RSIllegalArgumentException.java
deleted file mode 100644
index 378a49c..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/RSIllegalArgumentException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-
-/**
- * Base class for all exceptions thrown by the Android
- * RenderScript
- */
-public class RSIllegalArgumentException extends RSRuntimeException {
-    public RSIllegalArgumentException(String string) {
-        super(string);
-    }
-}
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/RSInvalidStateException.java b/v8/renderscript/java/src/android/support/v8/renderscript/RSInvalidStateException.java
deleted file mode 100644
index a5676a3..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/RSInvalidStateException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-
-/**
- * Base class for all exceptions thrown by the Android
- * RenderScript
- */
-public class RSInvalidStateException extends RSRuntimeException {
-    public RSInvalidStateException(String string) {
-        super(string);
-    }
-}
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/RSRuntimeException.java b/v8/renderscript/java/src/android/support/v8/renderscript/RSRuntimeException.java
deleted file mode 100644
index ec83365..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/RSRuntimeException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-
-/**
- * Base class for all exceptions thrown by the Android
- * RenderScript
- */
-public class RSRuntimeException
-  extends java.lang.RuntimeException {
-    public RSRuntimeException(String string) {
-        super(string);
-    }
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java b/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
deleted file mode 100644
index a5c6f93..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
+++ /dev/null
@@ -1,1721 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.io.File;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.ArrayList;
-import java.nio.ByteBuffer;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.Process;
-import android.util.Log;
-import android.view.Surface;
-
-/**
- * This class provides access to a RenderScript context, which controls RenderScript
- * initialization, resource management, and teardown. An instance of the RenderScript
- * class must be created before any other RS objects can be created.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses RenderScript, read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
- * </div>
- **/
-public class RenderScript {
-    static final String LOG_TAG = "RenderScript_jni";
-    static final boolean DEBUG  = false;
-    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
-    static final boolean LOG_ENABLED = false;
-    static final int SUPPORT_LIB_API = 23;
-    static final int SUPPORT_LIB_VERSION = 2301;
-
-    static private ArrayList<RenderScript> mProcessContextList = new ArrayList<RenderScript>();
-    private boolean mIsProcessContext = false;
-    private boolean mEnableMultiInput = false;
-    private int mDispatchAPILevel = 0;
-
-    private int mContextFlags = 0;
-    private int mContextSdkVersion = 0;
-
-    private Context mApplicationContext;
-    private String mNativeLibDir;
-
-    static private String mBlackList = "";
-     /**
-     * Sets the blackList of Models to only use support lib runtime.
-     * Should be used before context create.
-     *
-     * @param blackList User provided black list string.
-     *
-     * Format: "(MANUFACTURER1:PRODUCT1:MODEL1), (MANUFACTURER2:PRODUCT2:MODEL2)..."
-     * e.g. : To Blacklist Nexus 7(2013) and Nexus 5.
-     *        mBlackList = "(asus:razor:Nexus 7), (LGE:hammerhead:Nexus 5)";
-     */
-    static public void setBlackList(String blackList) {
-        if (blackList != null) {
-            mBlackList = blackList;
-        }
-    }
-     /**
-     * Force using support lib runtime.
-     * Should be used before context create.
-     *
-     */
-    static public void forceCompat() {
-        sNative = 0;
-    }
-    /*
-     * We use a class initializer to allow the native code to cache some
-     * field offsets.
-     */
-    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
-    static boolean sInitialized;
-    static boolean sUseGCHooks;
-    static Object sRuntime;
-    static Method registerNativeAllocation;
-    static Method registerNativeFree;
-
-    static Object lock = new Object();
-
-    // Non-threadsafe functions.
-    native boolean nLoadSO(boolean useNative, int deviceApi, String libPath);
-    native boolean nLoadIOSO();
-    native long nDeviceCreate();
-    native void nDeviceDestroy(long dev);
-    native void nDeviceSetConfig(long dev, int param, int value);
-    native int nContextGetUserMessage(long con, int[] data);
-    native String nContextGetErrorMessage(long con);
-    native int  nContextPeekMessage(long con, int[] subID);
-    native void nContextInitToClient(long con);
-    native void nContextDeinitToClient(long con);
-
-    static private int sNative = -1;
-    static private int sSdkVersion = -1;
-    static private boolean useIOlib = false;
-    static private boolean useNative;
-
-    /*
-     * Context creation flag that specifies a normal context.
-     * RenderScript Support lib only support normal context.
-     */
-    public static final int CREATE_FLAG_NONE = 0x0000;
-
-    int getDispatchAPILevel() {
-        return mDispatchAPILevel;
-    }
-
-    boolean isUseNative() {
-        return useNative;
-    }
-    /*
-     * Detect the bitness of the VM to allow FieldPacker to do the right thing.
-     */
-    static native int rsnSystemGetPointerSize();
-    static int sPointerSize;
-
-    /**
-     * Determines whether or not we should be thunking into the native
-     * RenderScript layer or actually using the compatibility library.
-     */
-    static private boolean setupNative(int sdkVersion, Context ctx) {
-        // if targetSdkVersion is higher than the device api version, always use compat mode.
-        // Workaround for KK
-        if (android.os.Build.VERSION.SDK_INT < sdkVersion &&
-            android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
-            sNative = 0;
-        }
-
-        if (sNative == -1) {
-
-            // get the value of the debug.rs.forcecompat property
-            int forcecompat = 0;
-            try {
-                Class<?> sysprop = Class.forName("android.os.SystemProperties");
-                Class[] signature = {String.class, Integer.TYPE};
-                Method getint = sysprop.getDeclaredMethod("getInt", signature);
-                Object[] args = {"debug.rs.forcecompat", new Integer(0)};
-                forcecompat = ((java.lang.Integer)getint.invoke(null, args)).intValue();
-            } catch (Exception e) {
-
-            }
-
-            if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
-                     && forcecompat == 0) {
-                sNative = 1;
-            } else {
-                sNative = 0;
-            }
-
-
-            if (sNative == 1) {
-                // Workarounds that may disable thunking go here
-                ApplicationInfo info;
-                try {
-                    info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
-                                                                      PackageManager.GET_META_DATA);
-                } catch (PackageManager.NameNotFoundException e) {
-                    // assume no workarounds needed
-                    return true;
-                }
-                long minorVersion = 0;
-
-                // load minorID from reflection
-                try {
-                    Class<?> javaRS = Class.forName("android.renderscript.RenderScript");
-                    Method getMinorID = javaRS.getDeclaredMethod("getMinorID");
-                    minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue();
-                } catch (Exception e) {
-                    // minor version remains 0 on devices with no possible WARs
-                }
-
-                if (info.metaData != null) {
-                    // asynchronous teardown: minor version 1+
-                    if (info.metaData.getBoolean("com.android.support.v8.renderscript.EnableAsyncTeardown") == true) {
-                        if (minorVersion == 0) {
-                            sNative = 0;
-                        }
-                    }
-
-                    // blur issues on some drivers with 4.4
-                    if (info.metaData.getBoolean("com.android.support.v8.renderscript.EnableBlurWorkaround") == true) {
-                        if (android.os.Build.VERSION.SDK_INT <= 19) {
-                            //android.util.Log.e("rs", "war on");
-                            sNative = 0;
-                        }
-                    }
-                }
-                // end of workarounds
-            }
-        }
-
-        if (sNative == 1) {
-            // check against the blacklist
-            if (mBlackList.length() > 0) {
-                String deviceInfo = '(' +
-                                    android.os.Build.MANUFACTURER +
-                                    ':' +
-                                    android.os.Build.PRODUCT +
-                                    ':' +
-                                    android.os.Build.MODEL +
-                                    ')';
-                if (mBlackList.contains(deviceInfo)) {
-                    sNative = 0;
-                    return false;
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Name of the file that holds the object cache.
-     */
-    private static final String CACHE_PATH = "com.android.renderscript.cache";
-    static String mCachePath;
-
-     /**
-     * Sets the directory to use as a persistent storage for the
-     * renderscript object file cache.
-     *
-     * @hide
-     * @param cacheDir A directory the current process can write to
-     */
-    public static void setupDiskCache(File cacheDir) {
-        File f = new File(cacheDir, CACHE_PATH);
-        mCachePath = f.getAbsolutePath();
-        f.mkdirs();
-    }
-
-    /**
-     * ContextType specifies the specific type of context to be created.
-     *
-     */
-    public enum ContextType {
-        /**
-         * NORMAL context, this is the default and what shipping apps should
-         * use.
-         */
-        NORMAL (0),
-
-        /**
-         * DEBUG context, perform extra runtime checks to validate the
-         * kernels and APIs are being used as intended.  Get and SetElementAt
-         * will be bounds checked in this mode.
-         */
-        DEBUG (1),
-
-        /**
-         * PROFILE context, Intended to be used once the first time an
-         * application is run on a new device.  This mode allows the runtime to
-         * do additional testing and performance tuning.
-         */
-        PROFILE (2);
-
-        int mID;
-        ContextType(int id) {
-            mID = id;
-        }
-    }
-
-    ContextType mContextType;
-    // Methods below are wrapped to protect the non-threadsafe
-    // lockless fifo.
-
-    native long  rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir);
-    synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir) {
-        return rsnContextCreate(dev, ver, sdkVer, contextType, nativeLibDir);
-    }
-    native void rsnContextDestroy(long con);
-    synchronized void nContextDestroy() {
-        validate();
-
-        // take teardown lock
-        // teardown lock can only be taken when no objects are being destroyed
-        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
-        wlock.lock();
-
-        long curCon = mContext;
-        // context is considered dead as of this point
-        mContext = 0;
-
-        wlock.unlock();
-        rsnContextDestroy(curCon);
-    }
-    native void rsnContextSetPriority(long con, int p);
-    synchronized void nContextSetPriority(int p) {
-        validate();
-        rsnContextSetPriority(mContext, p);
-    }
-    native void rsnContextDump(long con, int bits);
-    synchronized void nContextDump(int bits) {
-        validate();
-        rsnContextDump(mContext, bits);
-    }
-    native void rsnContextFinish(long con);
-    synchronized void nContextFinish() {
-        validate();
-        rsnContextFinish(mContext);
-    }
-
-    native void rsnContextSendMessage(long con, int id, int[] data);
-    synchronized void nContextSendMessage(int id, int[] data) {
-        validate();
-        rsnContextSendMessage(mContext, id, data);
-    }
-
-    // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
-    native void rsnObjDestroy(long con, long id);
-    void nObjDestroy(long id) {
-        // There is a race condition here.  The calling code may be run
-        // by the gc while teardown is occuring.  This protects againts
-        // deleting dead objects.
-        if (mContext != 0) {
-            rsnObjDestroy(mContext, id);
-        }
-    }
-
-    native long  rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
-    synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
-        validate();
-        return rsnElementCreate(mContext, type, kind, norm, vecSize);
-    }
-    native long  rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes);
-    synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) {
-        validate();
-        return rsnElementCreate2(mContext, elements, names, arraySizes);
-    }
-    native void rsnElementGetNativeData(long con, long id, int[] elementData);
-    synchronized void nElementGetNativeData(long id, int[] elementData) {
-        validate();
-        rsnElementGetNativeData(mContext, id, elementData);
-    }
-    native void rsnElementGetSubElements(long con, long id,
-                                         long[] IDs, String[] names, int[] arraySizes);
-    synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) {
-        validate();
-        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
-    }
-
-    native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
-    synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
-        validate();
-        return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
-    }
-
-    native void rsnTypeGetNativeData(long con, long id, long[] typeData);
-    synchronized void nTypeGetNativeData(long id, long[] typeData) {
-        validate();
-        rsnTypeGetNativeData(mContext, id, typeData);
-    }
-
-    native long  rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer);
-    synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) {
-        validate();
-        return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
-    }
-    native long  rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
-    synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
-        validate();
-        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
-    }
-
-    native long  rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
-    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
-        validate();
-        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
-    }
-
-
-    native long  rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
-    synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
-        validate();
-        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
-    }
-    native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
-    synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
-        validate();
-        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
-    }
-    native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
-    synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
-        validate();
-        return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
-    }
-
-    native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
-    synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
-        validate();
-        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
-    }
-
-
-    native void rsnAllocationSyncAll(long con, long alloc, int src);
-    synchronized void nAllocationSyncAll(long alloc, int src) {
-        validate();
-        rsnAllocationSyncAll(mContext, alloc, src);
-    }
-
-    native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
-    synchronized void nAllocationSetSurface(long alloc, Surface sur) {
-        validate();
-        rsnAllocationSetSurface(mContext, alloc, sur);
-    }
-
-    native void rsnAllocationIoSend(long con, long alloc);
-    synchronized void nAllocationIoSend(long alloc) {
-        validate();
-        rsnAllocationIoSend(mContext, alloc);
-    }
-    native void rsnAllocationIoReceive(long con, long alloc);
-    synchronized void nAllocationIoReceive(long alloc) {
-        validate();
-        rsnAllocationIoReceive(mContext, alloc);
-    }
-    native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, int xBytesSize, int dimY, int dimZ);
-    synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, int xBytesSize, int dimY, int dimZ) {
-        validate();
-        return rsnAllocationGetByteBuffer(mContext, alloc, xBytesSize, dimY, dimZ);
-    }
-    native long rsnAllocationGetStride(long con, long alloc);
-    synchronized long nAllocationGetStride(long alloc) {
-        validate();
-        return rsnAllocationGetStride(mContext, alloc);
-    }
-
-    native void rsnAllocationGenerateMipmaps(long con, long alloc);
-    synchronized void nAllocationGenerateMipmaps(long alloc) {
-        validate();
-        rsnAllocationGenerateMipmaps(mContext, alloc);
-    }
-    native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
-    synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
-        validate();
-        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
-    }
-
-
-    native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt,
-                                    int mSize, boolean usePadding);
-    synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt,
-                                        int mSize, boolean usePadding) {
-        validate();
-        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
-    }
-
-    native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
-    synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
-        validate();
-        rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
-    }
-    /*
-    native void rsnAllocationElementData(long con,long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes);
-    synchronized void nAllocationElementData(long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes) {
-        validate();
-        rsnAllocationElementData(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
-    }
-    */
-
-    native void rsnAllocationData2D(long con,
-                                    long dstAlloc, int dstXoff, int dstYoff,
-                                    int dstMip, int dstFace,
-                                    int width, int height,
-                                    long srcAlloc, int srcXoff, int srcYoff,
-                                    int srcMip, int srcFace);
-    synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
-                                        int dstMip, int dstFace,
-                                        int width, int height,
-                                        long srcAlloc, int srcXoff, int srcYoff,
-                                        int srcMip, int srcFace) {
-        validate();
-        rsnAllocationData2D(mContext,
-                            dstAlloc, dstXoff, dstYoff,
-                            dstMip, dstFace,
-                            width, height,
-                            srcAlloc, srcXoff, srcYoff,
-                            srcMip, srcFace);
-    }
-
-    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
-                                    int w, int h, Object d, int sizeBytes, int dt,
-                                    int mSize, boolean usePadding);
-    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
-                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
-                                        int mSize, boolean usePadding) {
-        validate();
-        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
-    }
-
-    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
-    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
-        validate();
-        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
-    }
-
-    native void rsnAllocationData3D(long con,
-                                    long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
-                                    int dstMip,
-                                    int width, int height, int depth,
-                                    long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
-                                    int srcMip);
-    synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
-                                        int dstMip,
-                                        int width, int height, int depth,
-                                        long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
-                                        int srcMip) {
-        validate();
-        rsnAllocationData3D(mContext,
-                            dstAlloc, dstXoff, dstYoff, dstZoff,
-                            dstMip, width, height, depth,
-                            srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
-    }
-
-
-    native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
-                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
-                                    int mSize, boolean usePadding);
-    synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
-                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
-                                        int mSize, boolean usePadding) {
-        validate();
-        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes,
-                            dt.mID, mSize, usePadding);
-    }
-
-    native void rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding);
-    synchronized void nAllocationRead(long id, Object d, Element.DataType dt, int mSize, boolean usePadding) {
-        validate();
-        rsnAllocationRead(mContext, id, d, dt.mID, mSize, usePadding);
-    }
-
-    native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
-                                    int sizeBytes, int dt, int mSize, boolean usePadding);
-    synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
-                                        int sizeBytes, Element.DataType dt, int mSize, boolean usePadding) {
-        validate();
-        rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
-    }
-
-    /*
-    native void rsnAllocationElementRead(long con,long id, int xoff, int yoff, int zoff,
-                                         int mip, int compIdx, byte[] d, int sizeBytes);
-    synchronized void nAllocationElementRead(long id, int xoff, int yoff, int zoff,
-                                             int mip, int compIdx, byte[] d, int sizeBytes) {
-        validate();
-        rsnAllocationElementRead(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
-    }
-    */
-
-    native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
-                                    int w, int h, Object d, int sizeBytes, int dt,
-                                    int mSize, boolean usePadding);
-    synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
-                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
-                                        int mSize, boolean usePadding) {
-        validate();
-        rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
-    }
-
-    /*
-    native void rsnAllocationRead3D(long con, long id, int xoff, int yoff, int zoff, int mip,
-                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
-                                    int mSize, boolean usePadding);
-    synchronized void nAllocationRead3D(long id, int xoff, int yoff, int zoff, int mip,
-                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
-                                        int mSize, boolean usePadding) {
-        validate();
-        rsnAllocationRead3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID, mSize, usePadding);
-    }
-    */
-
-    native long  rsnAllocationGetType(long con, long id);
-    synchronized long nAllocationGetType(long id) {
-        validate();
-        return rsnAllocationGetType(mContext, id);
-    }
-
-    native void rsnAllocationResize1D(long con, long id, int dimX);
-    synchronized void nAllocationResize1D(long id, int dimX) {
-        validate();
-        rsnAllocationResize1D(mContext, id, dimX);
-    }
-    native void rsnAllocationResize2D(long con, long id, int dimX, int dimY);
-    synchronized void nAllocationResize2D(long id, int dimX, int dimY) {
-        validate();
-        rsnAllocationResize2D(mContext, id, dimX, dimY);
-    }
-
-    native void rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc);
-    synchronized void nScriptBindAllocation(long script, long alloc, int slot, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptBindAllocation(curCon, script, alloc, slot, mUseInc);
-    }
-    native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc);
-    synchronized void nScriptSetTimeZone(long script, byte[] timeZone, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptSetTimeZone(curCon, script, timeZone, mUseInc);
-    }
-    native void rsnScriptInvoke(long con, long id, int slot, boolean mUseInc);
-    synchronized void nScriptInvoke(long id, int slot, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptInvoke(curCon, id, slot, mUseInc);
-    }
-    native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc);
-    native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc);
-    native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, byte[] params,
-                                        int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
-    native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout,
-                                        int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
-    synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params, boolean mUseInc) {
-        validate();
-        if (params == null) {
-            rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, mUseInc);
-        } else {
-            rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, params, mUseInc);
-        }
-    }
-
-    synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params,
-                                            int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc) {
-        validate();
-        if (params == null) {
-            rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend, mUseInc);
-        } else {
-            rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend, mUseInc);
-        }
-    }
-
-    native void rsnScriptForEach(long con, long id, int slot, long[] ains,
-                                 long aout, byte[] params, int[] limits);
-
-    synchronized void nScriptForEach(long id, int slot, long[] ains, long aout,
-                                     byte[] params, int[] limits) {
-        if (!mEnableMultiInput) {
-            Log.e(LOG_TAG, "Multi-input kernels are not supported, please change targetSdkVersion to >= 23");
-            throw new RSRuntimeException("Multi-input kernels are not supported before API 23)");
-        }
-        validate();
-        rsnScriptForEach(mContext, id, slot, ains, aout, params, limits);
-    }
-
-    native void rsnScriptReduce(long con, long id, int slot, long[] ains,
-                                long aout, int[] limits);
-    synchronized void nScriptReduce(long id, int slot, long ains[], long aout,
-                                    int[] limits) {
-        validate();
-        rsnScriptReduce(mContext, id, slot, ains, aout, limits);
-    }
-
-    native void rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc);
-    synchronized void nScriptInvokeV(long id, int slot, byte[] params, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptInvokeV(curCon, id, slot, params, mUseInc);
-    }
-    native void rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc);
-    synchronized void nScriptSetVarI(long id, int slot, int val, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptSetVarI(curCon, id, slot, val, mUseInc);
-    }
-    native void rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc);
-    synchronized void nScriptSetVarJ(long id, int slot, long val, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptSetVarJ(curCon, id, slot, val, mUseInc);
-    }
-    native void rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc);
-    synchronized void nScriptSetVarF(long id, int slot, float val, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptSetVarF(curCon, id, slot, val, mUseInc);
-    }
-    native void rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc);
-    synchronized void nScriptSetVarD(long id, int slot, double val, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptSetVarD(curCon, id, slot, val, mUseInc);
-    }
-    native void rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc);
-    synchronized void nScriptSetVarV(long id, int slot, byte[] val, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptSetVarV(curCon, id, slot, val, mUseInc);
-    }
-    native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
-                                  long e, int[] dims, boolean mUseInc);
-    synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
-                                      long e, int[] dims, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptSetVarVE(curCon, id, slot, val, e, dims, mUseInc);
-    }
-    native void rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc);
-    synchronized void nScriptSetVarObj(long id, int slot, long val, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        rsnScriptSetVarObj(curCon, id, slot, val, mUseInc);
-    }
-
-    native long  rsnScriptCCreate(long con, String resName, String cacheDir,
-                                 byte[] script, int length);
-    synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
-        validate();
-        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
-    }
-
-    native long  rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc);
-    synchronized long nScriptIntrinsicCreate(int id, long eid, boolean mUseInc) {
-        validate();
-        if (mUseInc) {
-            if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
-                Log.e(LOG_TAG, "Incremental Intrinsics are not supported, please change targetSdkVersion to >= 21");
-                throw new RSRuntimeException("Incremental Intrinsics are not supported before Lollipop (API 21)");
-            }
-
-            if (!mIncLoaded) {
-                try {
-                    System.loadLibrary("RSSupport");
-                } catch (UnsatisfiedLinkError e) {
-                    Log.e(LOG_TAG, "Error loading RS Compat library for Incremental Intrinsic Support: " + e);
-                    throw new RSRuntimeException("Error loading RS Compat library for Incremental Intrinsic Support: " + e);
-                }
-                if (!nIncLoadSO(SUPPORT_LIB_API, mNativeLibDir + "/libRSSupport.so")) {
-                    throw new RSRuntimeException("Error loading libRSSupport library for Incremental Intrinsic Support");
-                }
-                mIncLoaded = true;
-            }
-            if (mIncCon == 0) {
-                //Create a dummy compat context (synchronous).
-                long device = nIncDeviceCreate();
-                mIncCon = nIncContextCreate(device, 0, 0, 0);
-            }
-            return rsnScriptIntrinsicCreate(mIncCon, id, eid, mUseInc);
-        } else {
-            return rsnScriptIntrinsicCreate(mContext, id, eid, mUseInc);
-        }
-    }
-
-    native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc);
-    synchronized long nScriptKernelIDCreate(long sid, int slot, int sig, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        return rsnScriptKernelIDCreate(curCon, sid, slot, sig, mUseInc);
-    }
-
-    native long  rsnScriptInvokeIDCreate(long con, long sid, int slot);
-    synchronized long nScriptInvokeIDCreate(long sid, int slot) {
-        validate();
-        return rsnScriptInvokeIDCreate(mContext, sid, slot);
-    }
-
-    native long  rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc);
-    synchronized long nScriptFieldIDCreate(long sid, int slot, boolean mUseInc) {
-        validate();
-        long curCon = mContext;
-        if (mUseInc) {
-            curCon = mIncCon;
-        }
-        return rsnScriptFieldIDCreate(curCon, sid, slot, mUseInc);
-    }
-
-    native long  rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
-    synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
-        validate();
-        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
-    }
-
-    native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
-    synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
-        validate();
-        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
-    }
-
-    native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
-    synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
-        validate();
-        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
-    }
-
-    native void rsnScriptGroupExecute(long con, long group);
-    synchronized void nScriptGroupExecute(long group) {
-        validate();
-        rsnScriptGroupExecute(mContext, group);
-    }
-
-    native long  rsnSamplerCreate(long con, int magFilter, int minFilter,
-                                 int wrapS, int wrapT, int wrapR, float aniso);
-    synchronized long nSamplerCreate(int magFilter, int minFilter,
-                                 int wrapS, int wrapT, int wrapR, float aniso) {
-        validate();
-        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
-    }
-
-// entry points for ScriptGroup2
-    native long rsnClosureCreate(long con, long kernelID, long returnValue,
-        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
-        long[] depFieldIDs);
-    synchronized long nClosureCreate(long kernelID, long returnValue,
-        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
-        long[] depFieldIDs) {
-      validate();
-      long c = rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values,
-          sizes, depClosures, depFieldIDs);
-      if (c == 0) {
-          throw new RSRuntimeException("Failed creating closure.");
-      }
-      return c;
-    }
-
-    native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params,
-        long[] fieldIDs, long[] values, int[] sizes);
-    synchronized long nInvokeClosureCreate(long invokeID, byte[] params,
-        long[] fieldIDs, long[] values, int[] sizes) {
-      validate();
-      long c = rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs,
-          values, sizes);
-      if (c == 0) {
-          throw new RSRuntimeException("Failed creating closure.");
-      }
-      return c;
-    }
-
-    native void rsnClosureSetArg(long con, long closureID, int index,
-      long value, int size);
-    synchronized void nClosureSetArg(long closureID, int index, long value,
-        int size) {
-      validate();
-      rsnClosureSetArg(mContext, closureID, index, value, size);
-    }
-
-    native void rsnClosureSetGlobal(long con, long closureID, long fieldID,
-        long value, int size);
-    // Does this have to be synchronized?
-    synchronized void nClosureSetGlobal(long closureID, long fieldID,
-        long value, int size) {
-      validate(); // TODO: is this necessary?
-      rsnClosureSetGlobal(mContext, closureID, fieldID, value, size);
-    }
-
-    native long rsnScriptGroup2Create(long con, String name, String cachePath,
-                                      long[] closures);
-    synchronized long nScriptGroup2Create(String name, String cachePath,
-                                          long[] closures) {
-      validate();
-      return rsnScriptGroup2Create(mContext, name, cachePath, closures);
-    }
-
-    native void rsnScriptGroup2Execute(long con, long groupID);
-    synchronized void nScriptGroup2Execute(long groupID) {
-      validate();
-      rsnScriptGroup2Execute(mContext, groupID);
-    }
-
-    native void rsnScriptIntrinsicBLAS_Single(long con, long incCon, long id, int func, int TransA,
-                                              int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
-                                              float alpha, long A, long B, float beta, long C, int incX, int incY,
-                                              int KL, int KU, boolean mUseInc);
-    synchronized void nScriptIntrinsicBLAS_Single(long id, int func, int TransA,
-                                                  int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
-                                                  float alpha, long A, long B, float beta, long C, int incX, int incY,
-                                                  int KL, int KU, boolean mUseInc) {
-        validate();
-        rsnScriptIntrinsicBLAS_Single(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
-    }
-
-    native void rsnScriptIntrinsicBLAS_Double(long con, long incCon, long id, int func, int TransA,
-                                              int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
-                                              double alpha, long A, long B, double beta, long C, int incX, int incY,
-                                              int KL, int KU, boolean mUseInc);
-    synchronized void nScriptIntrinsicBLAS_Double(long id, int func, int TransA,
-                                                  int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
-                                                  double alpha, long A, long B, double beta, long C, int incX, int incY,
-                                                  int KL, int KU, boolean mUseInc) {
-        validate();
-        rsnScriptIntrinsicBLAS_Double(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
-    }
-
-    native void rsnScriptIntrinsicBLAS_Complex(long con, long incCon, long id, int func, int TransA,
-                                               int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
-                                               float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
-                                               int KL, int KU, boolean mUseInc);
-    synchronized void nScriptIntrinsicBLAS_Complex(long id, int func, int TransA,
-                                                   int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
-                                                   float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
-                                                   int KL, int KU, boolean mUseInc) {
-        validate();
-        rsnScriptIntrinsicBLAS_Complex(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU, mUseInc);
-    }
-
-    native void rsnScriptIntrinsicBLAS_Z(long con, long incCon, long id, int func, int TransA,
-                                         int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
-                                         double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
-                                         int KL, int KU, boolean mUseInc);
-    synchronized void nScriptIntrinsicBLAS_Z(long id, int func, int TransA,
-                                             int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
-                                             double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
-                                             int KL, int KU, boolean mUseInc) {
-        validate();
-        rsnScriptIntrinsicBLAS_Z(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU, mUseInc);
-    }
-
-    native void rsnScriptIntrinsicBLAS_BNNM(long con, long incCon, long id, int M, int N, int K,
-                                             long A, int a_offset, long B, int b_offset, long C, int c_offset,
-                                             int c_mult_int, boolean mUseInc);
-    synchronized void nScriptIntrinsicBLAS_BNNM(long id, int M, int N, int K,
-                                             long A, int a_offset, long B, int b_offset, long C, int c_offset,
-                                             int c_mult_int, boolean mUseInc) {
-        validate();
-        rsnScriptIntrinsicBLAS_BNNM(mContext, mIncCon, id, M, N, K, A, a_offset, B, b_offset, C, c_offset, c_mult_int, mUseInc);
-    }
-
-// Additional Entry points For inc libRSSupport
-
-    native boolean nIncLoadSO(int deviceApi, String libPath);
-    native long nIncDeviceCreate();
-    native void nIncDeviceDestroy(long dev);
-    // Methods below are wrapped to protect the non-threadsafe
-    // lockless fifo.
-    native long  rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType);
-    synchronized long nIncContextCreate(long dev, int ver, int sdkVer, int contextType) {
-        return rsnIncContextCreate(dev, ver, sdkVer, contextType);
-    }
-    native void rsnIncContextDestroy(long con);
-    synchronized void nIncContextDestroy() {
-        validate();
-
-        // take teardown lock
-        // teardown lock can only be taken when no objects are being destroyed
-        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
-        wlock.lock();
-
-        long curCon = mIncCon;
-        // context is considered dead as of this point
-        mIncCon = 0;
-
-        wlock.unlock();
-        rsnIncContextDestroy(curCon);
-    }
-
-    native void rsnIncContextFinish(long con);
-    synchronized void nIncContextFinish() {
-        validate();
-        rsnIncContextFinish(mIncCon);
-    }
-
-    native void rsnIncObjDestroy(long con, long id);
-    void nIncObjDestroy(long id) {
-        // There is a race condition here.  The calling code may be run
-        // by the gc while teardown is occuring.  This protects againts
-        // deleting dead objects.
-        if (mIncCon != 0) {
-            rsnIncObjDestroy(mIncCon, id);
-        }
-    }
-    native long  rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize);
-    synchronized long nIncElementCreate(long type, int kind, boolean norm, int vecSize) {
-        validate();
-        return rsnIncElementCreate(mIncCon, type, kind, norm, vecSize);
-    }
-    native long rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
-    synchronized long nIncTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
-        validate();
-        return rsnIncTypeCreate(mIncCon, eid, x, y, z, mips, faces, yuv);
-    }
-    native long  rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type, int xBytesSize);
-    synchronized long nIncAllocationCreateTyped(long alloc, long type, int xBytesSize) {
-        validate();
-        return rsnIncAllocationCreateTyped(mContext, mIncCon, alloc, type, xBytesSize);
-    }
-
-    long     mContext;
-    private boolean mDestroyed = false;
-    //Dummy device & context for Inc Support Lib
-    long     mIncCon;
-    //indicator of whether inc support lib has been loaded or not.
-    boolean  mIncLoaded;
-    ReentrantReadWriteLock mRWLock;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    MessageThread mMessageThread;
-
-    Element mElement_U8;
-    Element mElement_I8;
-    Element mElement_U16;
-    Element mElement_I16;
-    Element mElement_U32;
-    Element mElement_I32;
-    Element mElement_U64;
-    Element mElement_I64;
-    Element mElement_F32;
-    Element mElement_F64;
-    Element mElement_BOOLEAN;
-
-    Element mElement_ELEMENT;
-    Element mElement_TYPE;
-    Element mElement_ALLOCATION;
-    Element mElement_SAMPLER;
-    Element mElement_SCRIPT;
-
-    Element mElement_A_8;
-    Element mElement_RGB_565;
-    Element mElement_RGB_888;
-    Element mElement_RGBA_5551;
-    Element mElement_RGBA_4444;
-    Element mElement_RGBA_8888;
-
-    Element mElement_FLOAT_2;
-    Element mElement_FLOAT_3;
-    Element mElement_FLOAT_4;
-
-    Element mElement_DOUBLE_2;
-    Element mElement_DOUBLE_3;
-    Element mElement_DOUBLE_4;
-
-    Element mElement_UCHAR_2;
-    Element mElement_UCHAR_3;
-    Element mElement_UCHAR_4;
-
-    Element mElement_CHAR_2;
-    Element mElement_CHAR_3;
-    Element mElement_CHAR_4;
-
-    Element mElement_USHORT_2;
-    Element mElement_USHORT_3;
-    Element mElement_USHORT_4;
-
-    Element mElement_SHORT_2;
-    Element mElement_SHORT_3;
-    Element mElement_SHORT_4;
-
-    Element mElement_UINT_2;
-    Element mElement_UINT_3;
-    Element mElement_UINT_4;
-
-    Element mElement_INT_2;
-    Element mElement_INT_3;
-    Element mElement_INT_4;
-
-    Element mElement_ULONG_2;
-    Element mElement_ULONG_3;
-    Element mElement_ULONG_4;
-
-    Element mElement_LONG_2;
-    Element mElement_LONG_3;
-    Element mElement_LONG_4;
-
-    Element mElement_MATRIX_4X4;
-    Element mElement_MATRIX_3X3;
-    Element mElement_MATRIX_2X2;
-
-    Sampler mSampler_CLAMP_NEAREST;
-    Sampler mSampler_CLAMP_LINEAR;
-    Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
-    Sampler mSampler_WRAP_NEAREST;
-    Sampler mSampler_WRAP_LINEAR;
-    Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
-    Sampler mSampler_MIRRORED_REPEAT_NEAREST;
-    Sampler mSampler_MIRRORED_REPEAT_LINEAR;
-    Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
-
-
-    ///////////////////////////////////////////////////////////////////////////////////
-    //
-
-    /**
-     * The base class from which an application should derive in order
-     * to receive RS messages from scripts. When a script calls {@code
-     * rsSendToClient}, the data fields will be filled, and the run
-     * method will be called on a separate thread.  This will occur
-     * some time after {@code rsSendToClient} completes in the script,
-     * as {@code rsSendToClient} is asynchronous. Message handlers are
-     * not guaranteed to have completed when {@link
-     * android.support.v8.renderscript.RenderScript#finish} returns.
-     *
-     */
-    public static class RSMessageHandler implements Runnable {
-        protected int[] mData;
-        protected int mID;
-        protected int mLength;
-        public void run() {
-        }
-    }
-    /**
-     * If an application is expecting messages, it should set this
-     * field to an instance of {@link RSMessageHandler}.  This
-     * instance will receive all the user messages sent from {@code
-     * sendToClient} by scripts from this context.
-     *
-     */
-    RSMessageHandler mMessageCallback = null;
-
-    public void setMessageHandler(RSMessageHandler msg) {
-        mMessageCallback = msg;
-    }
-    public RSMessageHandler getMessageHandler() {
-        return mMessageCallback;
-    }
-
-    /**
-     * Place a message into the message queue to be sent back to the message
-     * handler once all previous commands have been executed.
-     *
-     * @param id
-     * @param data
-     */
-    public void sendMessage(int id, int[] data) {
-        nContextSendMessage(id, data);
-    }
-
-    /**
-     * The runtime error handler base class.  An application should derive from this class
-     * if it wishes to install an error handler.  When errors occur at runtime,
-     * the fields in this class will be filled, and the run method will be called.
-     *
-     */
-    public static class RSErrorHandler implements Runnable {
-        protected String mErrorMessage;
-        protected int mErrorNum;
-        public void run() {
-        }
-    }
-
-    /**
-     * Application Error handler.  All runtime errors will be dispatched to the
-     * instance of RSAsyncError set here.  If this field is null a
-     * {@link RSRuntimeException} will instead be thrown with details about the error.
-     * This will cause program termaination.
-     *
-     */
-    RSErrorHandler mErrorCallback = null;
-
-    public void setErrorHandler(RSErrorHandler msg) {
-        mErrorCallback = msg;
-    }
-    public RSErrorHandler getErrorHandler() {
-        return mErrorCallback;
-    }
-
-    /**
-     * RenderScript worker thread priority enumeration.  The default value is
-     * NORMAL.  Applications wishing to do background processing should set
-     * their priority to LOW to avoid starving forground processes.
-     */
-    public enum Priority {
-        LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
-        NORMAL (Process.THREAD_PRIORITY_DISPLAY);
-
-        int mID;
-        Priority(int id) {
-            mID = id;
-        }
-    }
-
-    void validateObject(BaseObj o) {
-        if (o != null) {
-            if (o.mRS != this) {
-                throw new RSIllegalArgumentException("Attempting to use an object across contexts.");
-            }
-        }
-    }
-
-    void validate() {
-        if (mContext == 0) {
-            throw new RSInvalidStateException("Calling RS with no Context active.");
-        }
-    }
-
-    /**
-     * check if IO support lib is available.
-     */
-    boolean usingIO() {
-        return useIOlib;
-    }
-    /**
-     * Change the priority of the worker threads for this context.
-     *
-     * @param p New priority to be set.
-     */
-    public void setPriority(Priority p) {
-        validate();
-        nContextSetPriority(p.mID);
-    }
-
-    static class MessageThread extends Thread {
-        RenderScript mRS;
-        boolean mRun = true;
-        int[] mAuxData = new int[2];
-
-        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
-        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
-        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
-        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
-
-        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
-        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
-
-        MessageThread(RenderScript rs) {
-            super("RSMessageThread");
-            mRS = rs;
-
-        }
-
-        public void run() {
-            // This function is a temporary solution.  The final solution will
-            // used typed allocations where the message id is the type indicator.
-            int[] rbuf = new int[16];
-            mRS.nContextInitToClient(mRS.mContext);
-            while(mRun) {
-                rbuf[0] = 0;
-                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
-                int size = mAuxData[1];
-                int subID = mAuxData[0];
-
-                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
-                    if ((size>>2) >= rbuf.length) {
-                        rbuf = new int[(size + 3) >> 2];
-                    }
-                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
-                        RS_MESSAGE_TO_CLIENT_USER) {
-                        throw new RSDriverException("Error processing message from RenderScript.");
-                    }
-
-                    if(mRS.mMessageCallback != null) {
-                        mRS.mMessageCallback.mData = rbuf;
-                        mRS.mMessageCallback.mID = subID;
-                        mRS.mMessageCallback.mLength = size;
-                        mRS.mMessageCallback.run();
-                    } else {
-                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
-                    }
-                    continue;
-                }
-
-                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
-                    String e = mRS.nContextGetErrorMessage(mRS.mContext);
-
-                    if (subID >= RS_ERROR_FATAL_UNKNOWN) {
-                        throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
-                    }
-
-                    if(mRS.mErrorCallback != null) {
-                        mRS.mErrorCallback.mErrorMessage = e;
-                        mRS.mErrorCallback.mErrorNum = subID;
-                        mRS.mErrorCallback.run();
-                    } else {
-                        android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
-                        // Do not throw here. In these cases, we do not have
-                        // a fatal error.
-                    }
-                    continue;
-                }
-
-                // 2: teardown.
-                // But we want to avoid starving other threads during
-                // teardown by yielding until the next line in the destructor
-                // can execute to set mRun = false
-                try {
-                    sleep(1, 0);
-                } catch(InterruptedException e) {
-                }
-            }
-            //Log.d(LOG_TAG, "MessageThread exiting.");
-        }
-    }
-
-    RenderScript(Context ctx) {
-        mContextType = ContextType.NORMAL;
-        if (ctx != null) {
-            mApplicationContext = ctx.getApplicationContext();
-            // Only set mNativeLibDir for API 9+.
-            mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir;
-        }
-        mIncCon = 0;
-        mIncLoaded = false;
-        mRWLock = new ReentrantReadWriteLock();
-    }
-
-    /**
-     * Gets the application context associated with the RenderScript context.
-     *
-     * @return The application context.
-     */
-    public final Context getApplicationContext() {
-        return mApplicationContext;
-    }
-
-    /**
-     * Create a RenderScript context.
-     *
-     * @param ctx The context.
-     * @return RenderScript
-     */
-    private static RenderScript internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags) {
-        RenderScript rs = new RenderScript(ctx);
-
-        if (sSdkVersion == -1) {
-            sSdkVersion = sdkVersion;
-        } else if (sSdkVersion != sdkVersion) {
-            throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib");
-        }
-        useNative = setupNative(sSdkVersion, ctx);
-        synchronized(lock) {
-            if (sInitialized == false) {
-                try {
-                    Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
-                    Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
-                    sRuntime = get_runtime.invoke(null);
-                    registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
-                    registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
-                    sUseGCHooks = true;
-                } catch (Exception e) {
-                    Log.e(LOG_TAG, "No GC methods");
-                    sUseGCHooks = false;
-                }
-                try {
-                    // For API 9 - 22, always use the absolute path of librsjni.so
-                    // http://b/25226912
-                    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
-                        rs.mNativeLibDir != null) {
-                        System.load(rs.mNativeLibDir + "/librsjni.so");
-                    } else {
-                        System.loadLibrary("rsjni");
-                    }
-                    sInitialized = true;
-                    sPointerSize = rsnSystemGetPointerSize();
-                } catch (UnsatisfiedLinkError e) {
-                    Log.e(LOG_TAG, "Error loading RS jni library: " + e);
-                    throw new RSRuntimeException("Error loading RS jni library: " + e + " Support lib API: " + SUPPORT_LIB_VERSION);
-                }
-            }
-        }
-
-        if (useNative) {
-            android.util.Log.v(LOG_TAG, "RS native mode");
-        } else {
-            android.util.Log.v(LOG_TAG, "RS compat mode");
-        }
-
-        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-            useIOlib = true;
-        }
-
-        // The target API level used to init dispatchTable.
-        int dispatchAPI = sdkVersion;
-        if (sdkVersion < android.os.Build.VERSION.SDK_INT) {
-            // If the device API is higher than target API level, init dispatch table based on device API.
-            dispatchAPI = android.os.Build.VERSION.SDK_INT;
-        }
-
-        String rssupportPath = null;
-        // For API 9 - 22, always use the absolute path of libRSSupport.so
-        // http://b/25226912
-        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
-            rs.mNativeLibDir != null) {
-            rssupportPath = rs.mNativeLibDir + "/libRSSupport.so";
-        }
-        if (!rs.nLoadSO(useNative, dispatchAPI, rssupportPath)) {
-            if (useNative) {
-                android.util.Log.v(LOG_TAG, "Unable to load libRS.so, falling back to compat mode");
-                useNative = false;
-            }
-            try {
-                if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
-                    rs.mNativeLibDir != null) {
-                    System.load(rssupportPath);
-                } else {
-                    System.loadLibrary("RSSupport");
-                }
-            } catch (UnsatisfiedLinkError e) {
-                Log.e(LOG_TAG, "Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
-                throw new RSRuntimeException("Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
-            }
-            if (!rs.nLoadSO(false, dispatchAPI, rssupportPath)) {
-                Log.e(LOG_TAG, "Error loading RS Compat library: nLoadSO() failed; Support lib version: " + SUPPORT_LIB_VERSION);
-                throw new RSRuntimeException("Error loading libRSSupport library, Support lib version: " + SUPPORT_LIB_VERSION);
-            }
-        }
-
-        if (useIOlib) {
-            try {
-                System.loadLibrary("RSSupportIO");
-            } catch (UnsatisfiedLinkError e) {
-                useIOlib = false;
-            }
-            if (!useIOlib || !rs.nLoadIOSO()) {
-                android.util.Log.v(LOG_TAG, "Unable to load libRSSupportIO.so, USAGE_IO not supported");
-                useIOlib = false;
-            }
-        }
-
-        // For old APIs with dlopen bug, need to load blas lib in Java first.
-        // Only try load to blasV8 when the desired API level includes IntrinsicBLAS.
-        if (dispatchAPI >= 23) {
-            // Enable multi-input kernels only when diapatchAPI is M+.
-            rs.mEnableMultiInput = true;
-            try {
-                System.loadLibrary("blasV8");
-            } catch (UnsatisfiedLinkError e) {
-                Log.v(LOG_TAG, "Unable to load BLAS lib, ONLY BNNM will be supported: " + e);
-            }
-        }
-
-        long device = rs.nDeviceCreate();
-        rs.mContext = rs.nContextCreate(device, 0, sdkVersion, ct.mID, rs.mNativeLibDir);
-        rs.mContextType = ct;
-        rs.mContextFlags = flags;
-        rs.mContextSdkVersion = sdkVersion;
-        rs.mDispatchAPILevel = dispatchAPI;
-        if (rs.mContext == 0) {
-            throw new RSDriverException("Failed to create RS context.");
-        }
-        rs.mMessageThread = new MessageThread(rs);
-        rs.mMessageThread.start();
-        return rs;
-    }
-
-    /**
-     * Create a RenderScript context.
-     *
-     * See documentation for @create for details
-     *
-     * @param ctx The context.
-     * @return RenderScript
-     */
-    public static RenderScript create(Context ctx) {
-        return create(ctx, ContextType.NORMAL);
-    }
-
-    /**
-     * calls create(ctx, ct, CREATE_FLAG_NONE)
-     *
-     * See documentation for @create for details
-     *
-     * @param ctx The context.
-     * @param ct The type of context to be created.
-     * @return RenderScript
-     */
-    public static RenderScript create(Context ctx, ContextType ct) {
-        return create(ctx, ct, CREATE_FLAG_NONE);
-    }
-
-    /**
-     * Gets or creates a RenderScript context of the specified type.
-     *
-     * The returned context will be cached for future reuse within
-     * the process. When an application is finished using
-     * RenderScript it should call releaseAllContexts()
-     *
-     * A process context is a context designed for easy creation and
-     * lifecycle management.  Multiple calls to this function will
-     * return the same object provided they are called with the same
-     * options.  This allows it to be used any time a RenderScript
-     * context is needed.
-     *
-     *
-     * @param ctx The context.
-     * @param ct The type of context to be created.
-     * @param flags The OR of the CREATE_FLAG_* options desired
-     * @return RenderScript
-     */
-    public static RenderScript create(Context ctx, ContextType ct, int flags) {
-        int v = ctx.getApplicationInfo().targetSdkVersion;
-        return create(ctx, v, ct, flags);
-    }
-
-    /**
-     * calls create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE)
-     *
-     * Used by the RenderScriptThunker to maintain backward compatibility.
-     *
-     * @hide
-     * @param ctx The context.
-     * @param sdkVersion The target SDK Version.
-     * @return RenderScript
-     */
-    public static RenderScript create(Context ctx, int sdkVersion) {
-        return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
-    }
-
-
-    /**
-     * calls create(ctx, sdkVersion, ct, CREATE_FLAG_NONE)
-     * Create a RenderScript context.
-     *
-     * @hide
-     * @param ctx The context.
-     * @return RenderScript
-     */
-    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
-        return create(ctx, sdkVersion, ct, CREATE_FLAG_NONE);
-    }
-
-     /**
-     * Gets or creates a RenderScript context of the specified type.
-     *
-     * @param ctx The context.
-     * @param ct The type of context to be created.
-     * @param sdkVersion The target SDK Version.
-     * @param flags The OR of the CREATE_FLAG_* options desired
-     * @return RenderScript
-     */
-    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
-        synchronized (mProcessContextList) {
-            for (RenderScript prs : mProcessContextList) {
-                if ((prs.mContextType == ct) &&
-                    (prs.mContextFlags == flags) &&
-                    (prs.mContextSdkVersion == sdkVersion)) {
-
-                    return prs;
-                }
-            }
-
-            RenderScript prs = internalCreate(ctx, sdkVersion, ct, flags);
-            prs.mIsProcessContext = true;
-            mProcessContextList.add(prs);
-            return prs;
-        }
-    }
-
-    /**
-     *
-     * Releases all the process contexts.  This is the same as
-     * calling .destroy() on each unique context retreived with
-     * create(...). If no contexts have been created this
-     * function does nothing.
-     *
-     * Typically you call this when your application is losing focus
-     * and will not be using a context for some time.
-     *
-     * This has no effect on a context created with
-     * createMultiContext()
-     */
-    public static void releaseAllContexts() {
-        ArrayList<RenderScript> oldList;
-        synchronized (mProcessContextList) {
-            oldList = mProcessContextList;
-            mProcessContextList = new ArrayList<RenderScript>();
-        }
-
-        for (RenderScript prs : oldList) {
-            prs.mIsProcessContext = false;
-            prs.destroy();
-        }
-        oldList.clear();
-    }
-
-
-
-    /**
-     * Create a RenderScript context.
-     *
-     * This is an advanced function intended for applications which
-     * need to create more than one RenderScript context to be used
-     * at the same time.
-     *
-     * If you need a single context please use create()
-     *
-     * @param ctx The context.
-     * @return RenderScript
-     */
-    public static RenderScript createMultiContext(Context ctx, ContextType ct, int flags, int API_number) {
-        return internalCreate(ctx, API_number, ct, flags);
-    }
-
-    /**
-     * Print the currently available debugging information about the state of
-     * the RS context to the log.
-     *
-     */
-    public void contextDump() {
-        validate();
-        nContextDump(0);
-    }
-
-    /**
-     * Wait for any pending asynchronous opeations (such as copies to a RS
-     * allocation or RS script executions) to complete.
-     *
-     */
-    public void finish() {
-        nContextFinish();
-    }
-
-    private void helpDestroy() {
-        boolean shouldDestroy = false;
-        synchronized(this) {
-            if (!mDestroyed) {
-                shouldDestroy = true;
-                mDestroyed = true;
-            }
-        }
-
-        if (shouldDestroy) {
-            nContextFinish();
-            if (mIncCon != 0) {
-                nIncContextFinish();
-                nIncContextDestroy();
-                mIncCon = 0;
-            }
-            nContextDeinitToClient(mContext);
-            mMessageThread.mRun = false;
-            // Interrupt mMessageThread so it gets to see immediately that mRun is false
-            // and exit rightaway.
-            mMessageThread.interrupt();
-
-            // Wait for mMessageThread to join.  Try in a loop, in case this thread gets interrupted
-            // during the wait.  If interrupted, set the "interrupted" status of the current thread.
-            boolean hasJoined = false, interrupted = false;
-            while (!hasJoined) {
-                try {
-                    mMessageThread.join();
-                    hasJoined = true;
-                } catch (InterruptedException e) {
-                    interrupted = true;
-                }
-            }
-            if (interrupted) {
-                Log.v(LOG_TAG, "Interrupted during wait for MessageThread to join");
-                Thread.currentThread().interrupt();
-            }
-
-            nContextDestroy();
-        }
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        helpDestroy();
-        super.finalize();
-    }
-
-    /**
-     * Destroys this RenderScript context.  Once this function is called,
-     * using this context or any objects belonging to this context is
-     * illegal.
-     *
-     * This function is a NOP if the context was created
-     * with create().  Please use releaseAllContexts() to clean up
-     * contexts created with the create function.
-     */
-    public void destroy() {
-        if (mIsProcessContext) {
-            // users cannot destroy a process context
-            return;
-        }
-        validate();
-        helpDestroy();
-    }
-
-    boolean isAlive() {
-        return mContext != 0;
-    }
-
-    long safeID(BaseObj o) {
-        if(o != null) {
-            return o.getID(this);
-        }
-        return 0;
-    }
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Sampler.java b/v8/renderscript/java/src/android/support/v8/renderscript/Sampler.java
deleted file mode 100644
index 7119e8c..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Sampler.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.util.Log;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
-/**
- * Sampler object that defines how Allocations can be read as textures within a
- * kernel. Samplers are used in conjunction with the {@code rsSample} runtime
- * function to return values from normalized coordinates.
- *
- * Any Allocation used with a Sampler must have been created with {@link
- * android.support.v8.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}; using a
- * Sampler on an {@link android.support.v8.renderscript.Allocation} that was not
- * created with
- * {@link android.support.v8.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} is
- * undefined.
- **/
-public class Sampler extends BaseObj {
-    public enum Value {
-        NEAREST (0),
-        LINEAR (1),
-        LINEAR_MIP_LINEAR (2),
-        LINEAR_MIP_NEAREST (5),
-        WRAP (3),
-        CLAMP (4),
-        MIRRORED_REPEAT (6);
-
-        int mID;
-        Value(int id) {
-            mID = id;
-        }
-    }
-
-    Value mMin;
-    Value mMag;
-    Value mWrapS;
-    Value mWrapT;
-    Value mWrapR;
-    float mAniso;
-
-    Sampler(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * @return minification setting for the sampler
-     */
-    public Value getMinification() {
-        return mMin;
-    }
-
-    /**
-     * @return magnification setting for the sampler
-     */
-    public Value getMagnification() {
-        return mMag;
-    }
-
-    /**
-     * @return S wrapping mode for the sampler
-     */
-    public Value getWrapS() {
-        return mWrapS;
-    }
-
-    /**
-     * @return T wrapping mode for the sampler
-     */
-    public Value getWrapT() {
-        return mWrapT;
-    }
-
-    /**
-     * @return anisotropy setting for the sampler
-     */
-    public float getAnisotropy() {
-        return mAniso;
-    }
-
-    /**
-     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
-     * clamp.
-     *
-     * @param rs Context to which the sampler will belong.
-     *
-     * @return Sampler
-     */
-    public static Sampler CLAMP_NEAREST(RenderScript rs) {
-        if(rs.mSampler_CLAMP_NEAREST == null) {
-            Builder b = new Builder(rs);
-            b.setMinification(Value.NEAREST);
-            b.setMagnification(Value.NEAREST);
-            b.setWrapS(Value.CLAMP);
-            b.setWrapT(Value.CLAMP);
-            rs.mSampler_CLAMP_NEAREST = b.create();
-        }
-        return rs.mSampler_CLAMP_NEAREST;
-    }
-
-    /**
-     * Retrieve a sampler with min and mag set to linear and wrap modes set to
-     * clamp.
-     *
-     * @param rs Context to which the sampler will belong.
-     *
-     * @return Sampler
-     */
-    public static Sampler CLAMP_LINEAR(RenderScript rs) {
-        if(rs.mSampler_CLAMP_LINEAR == null) {
-            Builder b = new Builder(rs);
-            b.setMinification(Value.LINEAR);
-            b.setMagnification(Value.LINEAR);
-            b.setWrapS(Value.CLAMP);
-            b.setWrapT(Value.CLAMP);
-            rs.mSampler_CLAMP_LINEAR = b.create();
-        }
-        return rs.mSampler_CLAMP_LINEAR;
-    }
-
-    /**
-     * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
-     * wrap modes set to clamp.
-     *
-     * @param rs Context to which the sampler will belong.
-     *
-     * @return Sampler
-     */
-    public static Sampler CLAMP_LINEAR_MIP_LINEAR(RenderScript rs) {
-        if(rs.mSampler_CLAMP_LINEAR_MIP_LINEAR == null) {
-            Builder b = new Builder(rs);
-            b.setMinification(Value.LINEAR_MIP_LINEAR);
-            b.setMagnification(Value.LINEAR);
-            b.setWrapS(Value.CLAMP);
-            b.setWrapT(Value.CLAMP);
-            rs.mSampler_CLAMP_LINEAR_MIP_LINEAR = b.create();
-        }
-        return rs.mSampler_CLAMP_LINEAR_MIP_LINEAR;
-    }
-
-    /**
-     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
-     * wrap.
-     *
-     * @param rs Context to which the sampler will belong.
-     *
-     * @return Sampler
-     */
-    public static Sampler WRAP_NEAREST(RenderScript rs) {
-        if(rs.mSampler_WRAP_NEAREST == null) {
-            Builder b = new Builder(rs);
-            b.setMinification(Value.NEAREST);
-            b.setMagnification(Value.NEAREST);
-            b.setWrapS(Value.WRAP);
-            b.setWrapT(Value.WRAP);
-            rs.mSampler_WRAP_NEAREST = b.create();
-        }
-        return rs.mSampler_WRAP_NEAREST;
-    }
-
-    /**
-     * Retrieve a sampler with min and mag set to linear and wrap modes set to
-     * wrap.
-     *
-     * @param rs Context to which the sampler will belong.
-     *
-     * @return Sampler
-     */
-    public static Sampler WRAP_LINEAR(RenderScript rs) {
-        if(rs.mSampler_WRAP_LINEAR == null) {
-            Builder b = new Builder(rs);
-            b.setMinification(Value.LINEAR);
-            b.setMagnification(Value.LINEAR);
-            b.setWrapS(Value.WRAP);
-            b.setWrapT(Value.WRAP);
-            rs.mSampler_WRAP_LINEAR = b.create();
-        }
-        return rs.mSampler_WRAP_LINEAR;
-    }
-
-    /**
-     * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
-     * wrap modes set to wrap.
-     *
-     * @param rs Context to which the sampler will belong.
-     *
-     * @return Sampler
-     */
-    public static Sampler WRAP_LINEAR_MIP_LINEAR(RenderScript rs) {
-        if(rs.mSampler_WRAP_LINEAR_MIP_LINEAR == null) {
-            Builder b = new Builder(rs);
-            b.setMinification(Value.LINEAR_MIP_LINEAR);
-            b.setMagnification(Value.LINEAR);
-            b.setWrapS(Value.WRAP);
-            b.setWrapT(Value.WRAP);
-            rs.mSampler_WRAP_LINEAR_MIP_LINEAR = b.create();
-        }
-        return rs.mSampler_WRAP_LINEAR_MIP_LINEAR;
-    }
-
-    /**
-     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
-     * mirrored repeat.
-     *
-     * @param rs Context to which the sampler will belong.
-     *
-     * @return Sampler
-     */
-    public static Sampler MIRRORED_REPEAT_NEAREST(RenderScript rs) {
-        if(rs.mSampler_MIRRORED_REPEAT_NEAREST == null) {
-            Builder b = new Builder(rs);
-            b.setMinification(Value.NEAREST);
-            b.setMagnification(Value.NEAREST);
-            b.setWrapS(Value.MIRRORED_REPEAT);
-            b.setWrapT(Value.MIRRORED_REPEAT);
-            rs.mSampler_MIRRORED_REPEAT_NEAREST = b.create();
-        }
-        return rs.mSampler_MIRRORED_REPEAT_NEAREST;
-    }
-
-    /**
-     * Retrieve a sampler with min and mag set to linear and wrap modes set to
-     * mirrored repeat.
-     *
-     * @param rs Context to which the sampler will belong.
-     *
-     * @return Sampler
-     */
-    public static Sampler MIRRORED_REPEAT_LINEAR(RenderScript rs) {
-        if(rs.mSampler_MIRRORED_REPEAT_LINEAR == null) {
-            Builder b = new Builder(rs);
-            b.setMinification(Value.LINEAR);
-            b.setMagnification(Value.LINEAR);
-            b.setWrapS(Value.MIRRORED_REPEAT);
-            b.setWrapT(Value.MIRRORED_REPEAT);
-            rs.mSampler_MIRRORED_REPEAT_LINEAR = b.create();
-        }
-        return rs.mSampler_MIRRORED_REPEAT_LINEAR;
-    }
-
-    /**
-     * Builder for creating non-standard samplers.  This is only necessary if
-     * a Sampler with different min and mag modes is desired.
-     */
-    public static class Builder {
-        RenderScript mRS;
-        Value mMin;
-        Value mMag;
-        Value mWrapS;
-        Value mWrapT;
-        Value mWrapR;
-        float mAniso;
-
-        public Builder(RenderScript rs) {
-            mRS = rs;
-            mMin = Value.NEAREST;
-            mMag = Value.NEAREST;
-            mWrapS = Value.WRAP;
-            mWrapT = Value.WRAP;
-            mWrapR = Value.WRAP;
-            mAniso = 1.0f;
-        }
-
-        public void setMinification(Value v) {
-            if (v == Value.NEAREST ||
-                v == Value.LINEAR ||
-                v == Value.LINEAR_MIP_LINEAR ||
-                v == Value.LINEAR_MIP_NEAREST) {
-                mMin = v;
-            } else {
-                throw new IllegalArgumentException("Invalid value");
-            }
-        }
-
-        public void setMagnification(Value v) {
-            if (v == Value.NEAREST || v == Value.LINEAR) {
-                mMag = v;
-            } else {
-                throw new IllegalArgumentException("Invalid value");
-            }
-        }
-
-        public void setWrapS(Value v) {
-            if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
-                mWrapS = v;
-            } else {
-                throw new IllegalArgumentException("Invalid value");
-            }
-        }
-
-        public void setWrapT(Value v) {
-            if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
-                mWrapT = v;
-            } else {
-                throw new IllegalArgumentException("Invalid value");
-            }
-        }
-
-        public void setAnisotropy(float v) {
-            if(v >= 0.0f) {
-                mAniso = v;
-            } else {
-                throw new IllegalArgumentException("Invalid value");
-            }
-        }
-
-        public Sampler create() {
-            mRS.validate();
-            long id = mRS.nSamplerCreate(mMag.mID, mMin.mID,
-                                        mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
-            Sampler sampler = new Sampler(id, mRS);
-            sampler.mMin = mMin;
-            sampler.mMag = mMag;
-            sampler.mWrapS = mWrapS;
-            sampler.mWrapT = mWrapT;
-            sampler.mWrapR = mWrapR;
-            sampler.mAniso = mAniso;
-            return sampler;
-        }
-    }
-
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Script.java b/v8/renderscript/java/src/android/support/v8/renderscript/Script.java
deleted file mode 100644
index ec3a7a9..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Script.java
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.SparseArray;
-
-/**
- * The parent class for all executable scripts. This should not be used by
- * applications.
- **/
-public class Script extends BaseObj {
-    /**
-     * Determine if Incremental Intrinsic Support is needed
-     *
-     */
-    private boolean mUseIncSupp;
-    protected void setIncSupp(boolean useInc) {
-        mUseIncSupp = useInc;
-    }
-    protected boolean isIncSupp() {
-        return mUseIncSupp;
-    }
-    /**
-     * An allocation for the compat context will be created when needed
-     * e.g. foreach(ain, aout), setVar(ain);
-     *
-     */
-    long getDummyAlloc(Allocation ain) {
-        long dInElement = 0;
-        long dInType = 0;
-        long dummyAlloc = 0;
-        if (ain != null) {
-            Type inType = ain.getType();
-            dInElement = inType.getElement().getDummyElement(mRS);
-            dInType = inType.getDummyType(mRS, dInElement);
-            int xBytesSize = inType.getX() * inType.getElement().getBytesSize();
-            dummyAlloc = mRS.nIncAllocationCreateTyped(ain.getID(mRS), dInType, xBytesSize);
-            ain.setIncAllocID(dummyAlloc);
-        }
-
-        return dummyAlloc;
-    }
-    /**
-     * KernelID is an identifier for a Script + root function pair. It is used
-     * as an identifier for ScriptGroup creation.
-     *
-     * This class should not be directly created. Instead use the method in the
-     * reflected or intrinsic code "getKernelID_funcname()".
-     *
-     */
-    public static final class KernelID extends BaseObj {
-        android.renderscript.Script.KernelID mN;
-        Script mScript;
-        int mSlot;
-        int mSig;
-        KernelID(long id, RenderScript rs, Script s, int slot, int sig) {
-            super(id, rs);
-            mScript = s;
-            mSlot = slot;
-            mSig = sig;
-        }
-    }
-
-    private final SparseArray<KernelID> mKIDs = new SparseArray<KernelID>();
-    /**
-     * Only to be used by generated reflected classes.
-     *
-     *
-     * @param slot
-     * @param sig
-     * @param ein
-     * @param eout
-     *
-     * @return KernelID
-     */
-    protected KernelID createKernelID(int slot, int sig, Element ein, Element eout) {
-        KernelID k = mKIDs.get(slot);
-        if (k != null) {
-            return k;
-        }
-
-        long id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig, mUseIncSupp);
-        if (id == 0) {
-            throw new RSDriverException("Failed to create KernelID");
-        }
-
-        k = new KernelID(id, mRS, this, slot, sig);
-
-        mKIDs.put(slot, k);
-        return k;
-    }
-
-    /**
-     * InvokeID is an identifier for a invoke function. It is used
-     * as an identifier for ScriptGroup creation.
-     *
-     * This class should not be directly created. Instead use the method in the
-     * reflected or intrinsic code "getInvokeID_funcname()".
-     *
-     */
-    public static final class InvokeID extends BaseObj {
-        Script mScript;
-        int mSlot;
-        InvokeID(long id, RenderScript rs, Script s, int slot) {
-            super(id, rs);
-            mScript = s;
-            mSlot = slot;
-        }
-    }
-
-    private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
-    /**
-     * Only to be used by generated reflected classes.
-     */
-    protected InvokeID createInvokeID(int slot) {
-        InvokeID i = mIIDs.get(slot);
-        if (i != null) {
-            return i;
-        }
-
-        long id = mRS.nScriptInvokeIDCreate(getID(mRS), slot);
-        if (id == 0) {
-            throw new RSDriverException("Failed to create KernelID");
-        }
-
-        i = new InvokeID(id, mRS, this, slot);
-        mIIDs.put(slot, i);
-        return i;
-    }
-
-    /**
-     * FieldID is an identifier for a Script + exported field pair. It is used
-     * as an identifier for ScriptGroup creation.
-     *
-     * This class should not be directly created. Instead use the method in the
-     * reflected or intrinsic code "getFieldID_funcname()".
-     *
-     */
-    public static final class FieldID extends BaseObj {
-        android.renderscript.Script.FieldID mN;
-        Script mScript;
-        int mSlot;
-        FieldID(long id, RenderScript rs, Script s, int slot) {
-            super(id, rs);
-            mScript = s;
-            mSlot = slot;
-        }
-    }
-
-    private final SparseArray<FieldID> mFIDs = new SparseArray();
-    /**
-     * Only to be used by generated reflected classes.
-     *
-     * @param slot
-     * @param e
-     *
-     * @return FieldID
-     */
-    protected FieldID createFieldID(int slot, Element e) {
-        FieldID f = mFIDs.get(slot);
-        if (f != null) {
-            return f;
-        }
-
-        long id = mRS.nScriptFieldIDCreate(getID(mRS), slot, mUseIncSupp);
-        if (id == 0) {
-            throw new RSDriverException("Failed to create FieldID");
-        }
-
-        f = new FieldID(id, mRS, this, slot);
-        mFIDs.put(slot, f);
-        return f;
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param slot
-     */
-    protected void invoke(int slot) {
-        mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param slot
-     * @param v
-     */
-    protected void invoke(int slot, FieldPacker v) {
-        if (v != null) {
-            mRS.nScriptInvokeV(getID(mRS), slot, v.getData(), mUseIncSupp);
-        } else {
-            mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp);
-        }
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param va
-     * @param slot
-     */
-    public void bindAllocation(Allocation va, int slot) {
-        mRS.validate();
-        if (va != null) {
-            mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot, mUseIncSupp);
-        } else {
-            mRS.nScriptBindAllocation(getID(mRS), 0, slot, mUseIncSupp);
-        }
-    }
-
-    public void setTimeZone(String timeZone) {
-        mRS.validate();
-        try {
-            mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8"), mUseIncSupp);
-        } catch (java.io.UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param slot
-     * @param ain
-     * @param aout
-     * @param v
-     */
-    protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v) {
-        if (ain == null && aout == null) {
-            throw new RSIllegalArgumentException(
-                "At least one of ain or aout is required to be non-null.");
-        }
-        long in_id = 0;
-        long out_id = 0;
-        if (ain != null) {
-            in_id = ain.getID(mRS);
-        }
-        if (aout != null) {
-            out_id = aout.getID(mRS);
-        }
-
-        byte[] params = null;
-        if (v != null) {
-            params = v.getData();
-        }
-
-        if (mUseIncSupp) {
-            long ainInc = getDummyAlloc(ain);
-            long aoutInc = getDummyAlloc(aout);
-            mRS.nScriptForEach(getID(mRS), slot, ainInc, aoutInc, params, mUseIncSupp);
-        } else {
-            mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params, mUseIncSupp);
-        }
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param slot
-     * @param ain
-     * @param aout
-     * @param v
-     * @param sc
-     */
-    protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc) {
-        if (ain == null && aout == null) {
-            throw new RSIllegalArgumentException(
-                "At least one of ain or aout is required to be non-null.");
-        }
-
-        if (sc == null) {
-            forEach(slot, ain, aout, v);
-            return;
-        }
-        long in_id = 0;
-        long out_id = 0;
-        if (ain != null) {
-            in_id = ain.getID(mRS);
-        }
-        if (aout != null) {
-            out_id = aout.getID(mRS);
-        }
-
-        byte[] params = null;
-        if (v != null) {
-            params = v.getData();
-        }
-        if (mUseIncSupp) {
-            long ainInc = getDummyAlloc(ain);
-            long aoutInc = getDummyAlloc(aout);
-            mRS.nScriptForEachClipped(getID(mRS), slot, ainInc, aoutInc, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp);        
-        } else {
-            mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp);
-        }
-    }
-
-    Script(long id, RenderScript rs) {
-        super(id, rs);
-        mUseIncSupp = false;
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @hide
-     */
-    protected void forEach(int slot, Allocation[] ains, Allocation aout,
-                           FieldPacker v) {
-        forEach(slot, ains, aout, v, null);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @hide
-     */
-    protected void forEach(int slot, Allocation[] ains, Allocation aout,
-                           FieldPacker v, LaunchOptions sc) {
-        // TODO: Is this necessary if nScriptForEach calls validate as well?
-        mRS.validate();
-        if (ains != null) {
-            for (Allocation ain : ains) {
-                mRS.validateObject(ain);
-            }
-        }
-        mRS.validateObject(aout);
-
-        if (ains == null && aout == null) {
-            throw new RSIllegalArgumentException(
-                "At least one of ain or aout is required to be non-null.");
-        }
-
-        long[] in_ids;
-        if (ains != null) {
-            in_ids = new long[ains.length];
-            for (int index = 0; index < ains.length; ++index) {
-                in_ids[index] = ains[index].getID(mRS);
-            }
-        } else {
-            in_ids = null;
-        }
-
-        long out_id = 0;
-        if (aout != null) {
-            out_id = aout.getID(mRS);
-        }
-
-        byte[] params = null;
-        if (v != null) {
-            params = v.getData();
-        }
-
-        int[] limits = null;
-        if (sc != null) {
-            limits = new int[6];
-
-            limits[0] = sc.xstart;
-            limits[1] = sc.xend;
-            limits[2] = sc.ystart;
-            limits[3] = sc.yend;
-            limits[4] = sc.zstart;
-            limits[5] = sc.zend;
-        }
-
-        mRS.nScriptForEach(getID(mRS), slot, in_ids, out_id, params, limits);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.  (General reduction)
-     *
-     * @hide
-     */
-    protected void reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc) {
-        mRS.validate();
-        if (ains == null || ains.length < 1) {
-            throw new RSIllegalArgumentException(
-                "At least one input is required.");
-        }
-        if (aout == null) {
-            throw new RSIllegalArgumentException(
-                "aout is required to be non-null.");
-        }
-        for (Allocation ain : ains) {
-            mRS.validateObject(ain);
-        }
-
-        long[] in_ids = new long[ains.length];
-        for (int index = 0; index < ains.length; ++index) {
-            in_ids[index] = ains[index].getID(mRS);
-        }
-        long out_id = aout.getID(mRS);
-
-        int[] limits = null;
-        if (sc != null) {
-            limits = new int[6];
-
-            limits[0] = sc.xstart;
-            limits[1] = sc.xend;
-            limits[2] = sc.ystart;
-            limits[3] = sc.yend;
-            limits[4] = sc.zstart;
-            limits[5] = sc.zend;
-        }
-
-        mRS.nScriptReduce(getID(mRS), slot, in_ids, out_id, limits);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param index
-     * @param v
-     */
-    public void setVar(int index, float v) {
-        mRS.nScriptSetVarF(getID(mRS), index, v, mUseIncSupp);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param index
-     * @param v
-     */
-    public void setVar(int index, double v) {
-        mRS.nScriptSetVarD(getID(mRS), index, v, mUseIncSupp);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param index
-     * @param v
-     */
-    public void setVar(int index, int v) {
-        mRS.nScriptSetVarI(getID(mRS), index, v, mUseIncSupp);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param index
-     * @param v
-     */
-    public void setVar(int index, long v) {
-        mRS.nScriptSetVarJ(getID(mRS), index, v, mUseIncSupp);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param index
-     * @param v
-     */
-    public void setVar(int index, boolean v) {
-        mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0, mUseIncSupp);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param index
-     * @param o
-     */
-    public void setVar(int index, BaseObj o) {
-        if (mUseIncSupp) {
-            long oInc = getDummyAlloc((Allocation)o);
-            mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : oInc, mUseIncSupp);            
-        } else {
-            mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS), mUseIncSupp);
-        }
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param index
-     * @param v
-     */
-    public void setVar(int index, FieldPacker v) {
-        mRS.nScriptSetVarV(getID(mRS), index, v.getData(), mUseIncSupp);
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     * @param index
-     * @param v
-     * @param e
-     * @param dims
-     */
-    public void setVar(int index, FieldPacker v, Element e, int[] dims) {
-        if (mUseIncSupp) {
-            long dElement = e.getDummyElement(mRS);
-            mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), dElement, dims, mUseIncSupp);
-        } else {
-            mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims, mUseIncSupp);
-        }
-    }
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     */
-    public static class Builder {
-        RenderScript mRS;
-
-        Builder(RenderScript rs) {
-            mRS = rs;
-        }
-    }
-
-
-    /**
-     * Only intended for use by generated reflected code.
-     *
-     */
-    public static class FieldBase {
-        protected Element mElement;
-        protected Allocation mAllocation;
-
-        protected void init(RenderScript rs, int dimx) {
-            mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT);
-        }
-
-        protected void init(RenderScript rs, int dimx, int usages) {
-            mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT | usages);
-        }
-
-        protected FieldBase() {
-        }
-
-        public Element getElement() {
-            return mElement;
-        }
-
-        public Type getType() {
-            return mAllocation.getType();
-        }
-
-        public Allocation getAllocation() {
-            return mAllocation;
-        }
-
-        //@Override
-        public void updateAllocation() {
-        }
-    }
-
-
-    /**
-     * Class for specifying the specifics about how a kernel will be
-     * launched.
-     *
-     * This class can specify a potential range of cells on which to
-     * run a kernel.  If no set is called for a dimension then this
-     * class will have no impact on that dimension when the kernel
-     * is executed.
-     *
-     * The forEach kernel launch will operate over the intersection of
-     * the dimensions.
-     *
-     * Example:
-     * LaunchOptions with setX(5, 15)
-     * Allocation with dimension X=10, Y=10
-     * The resulting forEach run would execute over:
-     * x = 5 to 9 (inclusive) and
-     * y = 0 to 9 (inclusive).
-     *
-     */
-    public static final class LaunchOptions {
-        private int xstart = 0;
-        private int ystart = 0;
-        private int xend = 0;
-        private int yend = 0;
-        private int zstart = 0;
-        private int zend = 0;
-        private int strategy;
-
-        /**
-         * Set the X range. xstartArg is the lowest coordinate of the range,
-         * and xendArg-1 is the highest coordinate of the range.
-         *
-         * @param xstartArg Must be >= 0
-         * @param xendArg Must be > xstartArg
-         *
-         * @return LaunchOptions
-         */
-        public LaunchOptions setX(int xstartArg, int xendArg) {
-            if (xstartArg < 0 || xendArg <= xstartArg) {
-                throw new RSIllegalArgumentException("Invalid dimensions");
-            }
-            xstart = xstartArg;
-            xend = xendArg;
-            return this;
-        }
-
-        /**
-         * Set the Y range. ystartArg is the lowest coordinate of the range,
-         * and yendArg-1 is the highest coordinate of the range.
-         *
-         * @param ystartArg Must be >= 0
-         * @param yendArg Must be > ystartArg
-         *
-         * @return LaunchOptions
-         */
-        public LaunchOptions setY(int ystartArg, int yendArg) {
-            if (ystartArg < 0 || yendArg <= ystartArg) {
-                throw new RSIllegalArgumentException("Invalid dimensions");
-            }
-            ystart = ystartArg;
-            yend = yendArg;
-            return this;
-        }
-
-        /**
-         * Set the Z range. zstartArg is the lowest coordinate of the range,
-         * and zendArg-1 is the highest coordinate of the range.
-         *
-         * @param zstartArg Must be >= 0
-         * @param zendArg Must be > zstartArg
-         *
-         * @return LaunchOptions
-         */
-        public LaunchOptions setZ(int zstartArg, int zendArg) {
-            if (zstartArg < 0 || zendArg <= zstartArg) {
-                throw new RSIllegalArgumentException("Invalid dimensions");
-            }
-            zstart = zstartArg;
-            zend = zendArg;
-            return this;
-        }
-
-
-        /**
-         * Returns the current X start
-         *
-         * @return int current value
-         */
-        public int getXStart() {
-            return xstart;
-        }
-        /**
-         * Returns the current X end
-         *
-         * @return int current value
-         */
-        public int getXEnd() {
-            return xend;
-        }
-        /**
-         * Returns the current Y start
-         *
-         * @return int current value
-         */
-        public int getYStart() {
-            return ystart;
-        }
-        /**
-         * Returns the current Y end
-         *
-         * @return int current value
-         */
-        public int getYEnd() {
-            return yend;
-        }
-        /**
-         * Returns the current Z start
-         *
-         * @return int current value
-         */
-        public int getZStart() {
-            return zstart;
-        }
-        /**
-         * Returns the current Z end
-         *
-         * @return int current value
-         */
-        public int getZEnd() {
-            return zend;
-        }
-
-    }
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptC.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptC.java
deleted file mode 100644
index 28e9613..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptC.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map.Entry;
-import java.util.HashMap;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-
-/**
- * The superclass for all user-defined scripts. This is only
- * intended to be used by the generated derived classes.
- **/
-public class ScriptC extends Script {
-    private static final String TAG = "ScriptC";
-
-    /**
-     * Only intended for use by the generated derived classes.
-     *
-     * @param id
-     * @param rs
-     */
-    protected ScriptC(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Only intended for use by the generated derived classes.
-     *
-     *
-     * @param rs
-     * @param resources
-     * @param resourceID
-     */
-    protected ScriptC(RenderScript rs, Resources resources, int resourceID) {
-        super(0, rs);
-        long id = internalCreate(rs, resources, resourceID);
-        if (id == 0) {
-            throw new RSRuntimeException("Loading of ScriptC script failed.");
-        }
-        setID(id);
-    }
-
-    /**
-     * Only intended for use by the generated derived classes.
-     *
-     * @param rs
-     * @param resName
-     * @param bitcode32
-     * @param bitcode64
-     */
-    protected ScriptC(RenderScript rs, String resName, byte[] bitcode32, byte[] bitcode64) {
-        super(0, rs);
-        long id = 0;
-        if (RenderScript.sPointerSize == 4) {
-            id = internalStringCreate(rs, resName, bitcode32);
-        } else {
-            id = internalStringCreate(rs, resName, bitcode64);
-        }
-        if (id == 0) {
-            throw new RSRuntimeException("Loading of ScriptC script failed.");
-        }
-        setID(id);
-    }
-
-    private static synchronized long internalCreate(RenderScript rs, Resources resources, int resourceID) {
-        byte[] pgm;
-        int pgmLength;
-        InputStream is = resources.openRawResource(resourceID);
-        try {
-            try {
-                pgm = new byte[1024];
-                pgmLength = 0;
-                while(true) {
-                    int bytesLeft = pgm.length - pgmLength;
-                    if (bytesLeft == 0) {
-                        byte[] buf2 = new byte[pgm.length * 2];
-                        System.arraycopy(pgm, 0, buf2, 0, pgm.length);
-                        pgm = buf2;
-                        bytesLeft = pgm.length - pgmLength;
-                    }
-                    int bytesRead = is.read(pgm, pgmLength, bytesLeft);
-                    if (bytesRead <= 0) {
-                        break;
-                    }
-                    pgmLength += bytesRead;
-                }
-            } finally {
-                is.close();
-            }
-        } catch(IOException e) {
-            throw new Resources.NotFoundException();
-        }
-
-        String resName = resources.getResourceEntryName(resourceID);
-        String cachePath = rs.getApplicationContext().getCacheDir().toString();
-
-        //        Log.v(TAG, "Create script for resource = " + resName + ", " + pgmLength + ", " + pgm);
-        //Log.v(TAG, " path = " + cachePath);
-        return rs.nScriptCCreate(resName, cachePath, pgm, pgmLength);
-    }
-
-    private static synchronized long internalStringCreate(RenderScript rs, String resName, byte[] bitcode) {
-        //        Log.v(TAG, "Create script for resource = " + resName);
-        String cachePath = rs.getApplicationContext().getCacheDir().toString();
-        return rs.nScriptCCreate(resName, cachePath, bitcode, bitcode.length);
-    }
-
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptGroup.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptGroup.java
deleted file mode 100644
index 139fde2..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptGroup.java
+++ /dev/null
@@ -1,1180 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.Log;
-import android.util.Pair;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A group of kernels that are executed
- * together with one execution call as if they were a single kernel
- * <p>
- * In addition to kernels, a script group may contain invocable functions as well.
- * A script group may take inputs and generate outputs, which are consumed and
- * produced by its member kernels.
- * Inside a script group, outputs from one kernel can be passed to another kernel as inputs.
- * The API disallows cyclic dependencies among kernels in a script group,
- * effectively making it a directed acyclic graph (DAG) of kernels.
- * <p>
- * Grouping kernels together allows for more efficient execution. For example,
- * runtime and compiler optimization can be applied to reduce computation and
- * communication overhead, and to make better use of the CPU and the GPU.
- **/
-public final class ScriptGroup extends BaseObj {
-    //FIXME: Change 23 to the codename when that is decided.
-    private static final int MIN_API_VERSION = 23;
-    private static final String TAG = "ScriptGroup";
-    IO mOutputs[];
-    IO mInputs[];
-    private boolean mUseIncSupp = false;
-    private ArrayList<Node> mNodes = new ArrayList<Node>();
-
-    static class IO {
-        Script.KernelID mKID;
-        Allocation mAllocation;
-
-        IO(Script.KernelID s) {
-            mKID = s;
-        }
-    }
-
-    static class ConnectLine {
-        ConnectLine(Type t, Script.KernelID from, Script.KernelID to) {
-            mFrom = from;
-            mToK = to;
-            mAllocationType = t;
-        }
-
-        ConnectLine(Type t, Script.KernelID from, Script.FieldID to) {
-            mFrom = from;
-            mToF = to;
-            mAllocationType = t;
-        }
-
-        Script.FieldID mToF;
-        Script.KernelID mToK;
-        Script.KernelID mFrom;
-        Type mAllocationType;
-        Allocation mAllocation;
-    }
-
-    static class Node {
-        Script mScript;
-        ArrayList<Script.KernelID> mKernels = new ArrayList<Script.KernelID>();
-        ArrayList<ConnectLine> mInputs = new ArrayList<ConnectLine>();
-        ArrayList<ConnectLine> mOutputs = new ArrayList<ConnectLine>();
-        int dagNumber;
-        boolean mSeen;
-        int mOrder;
-
-        Node mNext;
-
-        Node(Script s) {
-            mScript = s;
-        }
-    }
-
-    /**
-     * An opaque class for closures
-     * <p>
-     * A closure represents a function call to a kernel or invocable function,
-     * combined with arguments and values for global variables. A closure is
-     * created using the {@link Builder2#addKernel} or
-     * {@link Builder2#addInvoke}
-     * method.
-     */
-
-    public static final class Closure extends BaseObj {
-        private Object[] mArgs;
-        private Allocation mReturnValue;
-        private Map<Script.FieldID, Object> mBindings;
-
-        private Future mReturnFuture;
-        private Map<Script.FieldID, Future> mGlobalFuture;
-
-        private FieldPacker mFP;
-
-        private static final String TAG = "Closure";
-
-        Closure(long id, RenderScript rs) {
-            super(id, rs);
-        }
-
-        Closure(RenderScript rs, Script.KernelID kernelID, Type returnType,
-                       Object[] args, Map<Script.FieldID, Object> globals) {
-            super(0, rs);
-
-            if (android.os.Build.VERSION.SDK_INT < MIN_API_VERSION && rs.isUseNative()) {
-                throw new RSRuntimeException("ScriptGroup2 not supported in this API level");
-            }
-
-            mArgs = args;
-            mReturnValue = Allocation.createTyped(rs, returnType);
-            mBindings = globals;
-            mGlobalFuture = new HashMap<Script.FieldID, Future>();
-
-            int numValues = args.length + globals.size();
-
-            long[] fieldIDs = new long[numValues];
-            long[] values = new long[numValues];
-            int[] sizes = new int[numValues];
-            long[] depClosures = new long[numValues];
-            long[] depFieldIDs = new long[numValues];
-
-            int i;
-            for (i = 0; i < args.length; i++) {
-                fieldIDs[i] = 0;
-                retrieveValueAndDependenceInfo(rs, i, null, args[i],
-                                               values, sizes, depClosures, depFieldIDs);
-            }
-            for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
-                Object obj = entry.getValue();
-                Script.FieldID fieldID = entry.getKey();
-                fieldIDs[i] = fieldID.getID(rs);
-                retrieveValueAndDependenceInfo(rs, i, fieldID, obj,
-                                               values, sizes, depClosures, depFieldIDs);
-                i++;
-            }
-
-            long id = rs.nClosureCreate(kernelID.getID(rs), mReturnValue.getID(rs),
-                                        fieldIDs, values, sizes, depClosures, depFieldIDs);
-
-            setID(id);
-        }
-
-        Closure(RenderScript rs, Script.InvokeID invokeID,
-                Object[] args, Map<Script.FieldID, Object> globals) {
-            super(0, rs);
-
-            if (android.os.Build.VERSION.SDK_INT < MIN_API_VERSION && rs.isUseNative()) {
-                throw new RSRuntimeException("ScriptGroup2 not supported in this API level");
-            }
-
-            mFP = FieldPacker.createFromArray(args);
-
-            mArgs = args;
-            mBindings = globals;
-            mGlobalFuture = new HashMap<Script.FieldID, Future>();
-
-            int numValues = globals.size();
-
-            long[] fieldIDs = new long[numValues];
-            long[] values = new long[numValues];
-            int[] sizes = new int[numValues];
-            long[] depClosures = new long[numValues];
-            long[] depFieldIDs = new long[numValues];
-
-            int i = 0;
-            for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
-                Object obj = entry.getValue();
-                Script.FieldID fieldID = entry.getKey();
-                fieldIDs[i] = fieldID.getID(rs);
-                retrieveValueAndDependenceInfo(rs, i, fieldID, obj, values,
-                                               sizes, depClosures, depFieldIDs);
-                i++;
-            }
-
-            long id = rs.nInvokeClosureCreate(invokeID.getID(rs), mFP.getData(), fieldIDs,
-                                              values, sizes);
-
-            setID(id);
-        }
-
-        private void retrieveValueAndDependenceInfo(RenderScript rs,
-                                                    int index, Script.FieldID fid, Object obj,
-                                                    long[] values, int[] sizes,
-                                                    long[] depClosures,
-                                                    long[] depFieldIDs) {
-
-            if (obj instanceof Future) {
-                Future f = (Future)obj;
-                obj = f.getValue();
-                depClosures[index] = f.getClosure().getID(rs);
-                Script.FieldID fieldID = f.getFieldID();
-                depFieldIDs[index] = fieldID != null ? fieldID.getID(rs) : 0;
-            } else {
-                depClosures[index] = 0;
-                depFieldIDs[index] = 0;
-            }
-
-            if (obj instanceof Input) {
-                Input unbound = (Input)obj;
-                if (index < mArgs.length) {
-                    unbound.addReference(this, index);
-                } else {
-                    unbound.addReference(this, fid);
-                }
-                values[index] = 0;
-                sizes[index] = 0;
-            } else {
-                ValueAndSize vs = new ValueAndSize(rs, obj);
-                values[index] = vs.value;
-                sizes[index] = vs.size;
-            }
-        }
-
-        /**
-         * Returns the future for the return value
-         *
-         * @return a future
-         */
-
-        public Future getReturn() {
-            if (mReturnFuture == null) {
-                mReturnFuture = new Future(this, null, mReturnValue);
-            }
-
-            return mReturnFuture;
-        }
-
-        /**
-         * Returns the future for a global variable
-         *
-         * @param field the field ID for the global variable
-         * @return a future
-         */
-
-        public Future getGlobal(Script.FieldID field) {
-            Future f = mGlobalFuture.get(field);
-
-            if (f == null) {
-                // If the field is not bound to this closure, this will return a future
-                // without an associated value (reference). So this is not working for
-                // cross-module (cross-script) linking in this case where a field not
-                // explicitly bound.
-                Object obj = mBindings.get(field);
-                if (obj instanceof Future) {
-                    obj = ((Future)obj).getValue();
-                }
-                f = new Future(this, field, obj);
-                mGlobalFuture.put(field, f);
-            }
-
-            return f;
-        }
-
-        void setArg(int index, Object obj) {
-            if (obj instanceof Future) {
-                obj = ((Future)obj).getValue();
-            }
-            mArgs[index] = obj;
-            ValueAndSize vs = new ValueAndSize(mRS, obj);
-            mRS.nClosureSetArg(getID(mRS), index, vs.value, vs.size);
-        }
-
-        void setGlobal(Script.FieldID fieldID, Object obj) {
-            if (obj instanceof Future) {
-                obj = ((Future)obj).getValue();
-            }
-            mBindings.put(fieldID, obj);
-            ValueAndSize vs = new ValueAndSize(mRS, obj);
-            mRS.nClosureSetGlobal(getID(mRS), fieldID.getID(mRS), vs.value, vs.size);
-        }
-
-        private static final class ValueAndSize {
-            public ValueAndSize(RenderScript rs, Object obj) {
-                if (obj instanceof Allocation) {
-                    value = ((Allocation)obj).getID(rs);
-                    size = -1;
-                } else if (obj instanceof Boolean) {
-                    value = ((Boolean)obj).booleanValue() ? 1 : 0;
-                    size = 4;
-                } else if (obj instanceof Integer) {
-                    value = ((Integer)obj).longValue();
-                    size = 4;
-                } else if (obj instanceof Long) {
-                    value = ((Long)obj).longValue();
-                    size = 8;
-                } else if (obj instanceof Float) {
-                    value = Float.floatToRawIntBits(((Float)obj).floatValue());
-                    size = 4;
-                } else if (obj instanceof Double) {
-                    value = Double.doubleToRawLongBits(((Double)obj).doubleValue());
-                    size = 8;
-                }
-            }
-            public long value;
-            public int size;
-        }
-    }
-
-    /**
-     * An opaque class for futures
-     * <p>
-     * A future represents an output of a closure, either the return value of
-     * the function, or the value of a global variable written by the function.
-     * A future is created by calling the {@link Closure#getReturn}  or
-     * {@link Closure#getGlobal} method.
-     */
-
-    public static final class Future {
-        Closure mClosure;
-        Script.FieldID mFieldID;
-        Object mValue;
-
-        Future(Closure closure, Script.FieldID fieldID, Object value) {
-            mClosure = closure;
-            mFieldID = fieldID;
-            mValue = value;
-        }
-
-        Closure getClosure() { return mClosure; }
-        Script.FieldID getFieldID() { return mFieldID; }
-        Object getValue() { return mValue; }
-    }
-
-    /**
-     * An opaque class for unbound values (used for script group inputs)
-     * <p>
-     * Created by calling the {@link Builder2#addInput} method. The value
-     * is assigned in {@link ScriptGroup#execute(Object...)} method as
-     * one of its arguments. Arguments to the execute method should be in
-     * the same order as intputs are added using the addInput method.
-     */
-
-    public static final class Input {
-        // Either mFieldID or mArgIndex should be set but not both.
-        List<Pair<Closure, Script.FieldID>> mFieldID;
-        // -1 means unset. Legal values are 0 .. n-1, where n is the number of
-        // arguments for the referencing closure.
-        List<Pair<Closure, Integer>> mArgIndex;
-        Object mValue;
-
-        Input() {
-            mFieldID = new ArrayList<Pair<Closure, Script.FieldID>>();
-            mArgIndex = new ArrayList<Pair<Closure, Integer>>();
-        }
-
-        void addReference(Closure closure, int index) {
-            mArgIndex.add(Pair.create(closure, Integer.valueOf(index)));
-        }
-
-        void addReference(Closure closure, Script.FieldID fieldID) {
-            mFieldID.add(Pair.create(closure, fieldID));
-        }
-
-        void set(Object value) {
-            mValue = value;
-            for (Pair<Closure, Integer> p : mArgIndex) {
-                Closure closure = p.first;
-                int index = p.second.intValue();
-                closure.setArg(index, value);
-            }
-            for (Pair<Closure, Script.FieldID> p : mFieldID) {
-                Closure closure = p.first;
-                Script.FieldID fieldID = p.second;
-                closure.setGlobal(fieldID, value);
-            }
-        }
-
-        Object get() { return mValue; }
-    }
-
-    private String mName;
-    private List<Closure> mClosures;
-    private List<Input> mInputs2;
-    private Future[] mOutputs2;
-
-    ScriptGroup(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    ScriptGroup(RenderScript rs, String name, List<Closure> closures,
-                List<Input> inputs, Future[] outputs) {
-        super(0, rs);
-
-        if (android.os.Build.VERSION.SDK_INT < MIN_API_VERSION && rs.isUseNative()) {
-            throw new RSRuntimeException("ScriptGroup2 not supported in this API level");
-        }
-        mName = name;
-        mClosures = closures;
-        mInputs2 = inputs;
-        mOutputs2 = outputs;
-
-        long[] closureIDs = new long[closures.size()];
-        for (int i = 0; i < closureIDs.length; i++) {
-            closureIDs[i] = closures.get(i).getID(rs);
-        }
-        String cachePath = rs.getApplicationContext().getCacheDir().toString();
-        long id = rs.nScriptGroup2Create(name, cachePath, closureIDs);
-        setID(id);
-    }
-
-    /**
-     * Executes a script group
-     *
-     * @param inputs inputs to the script group
-     * @return outputs of the script group as an array of objects
-     */
-
-    public Object[] execute(Object... inputs) {
-        if (inputs.length < mInputs2.size()) {
-            Log.e(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
-                  "less than expected " + mInputs2.size());
-            return null;
-        }
-
-        if (inputs.length > mInputs2.size()) {
-            Log.i(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
-                  "more than expected " + mInputs2.size());
-        }
-
-        for (int i = 0; i < mInputs2.size(); i++) {
-            Object obj = inputs[i];
-            if (obj instanceof Future || obj instanceof Input) {
-                Log.e(TAG, this.toString() + ": input " + i +
-                      " is a future or unbound value");
-                return null;
-            }
-            Input unbound = mInputs2.get(i);
-            unbound.set(obj);
-        }
-
-        mRS.nScriptGroup2Execute(getID(mRS));
-
-        Object[] outputObjs = new Object[mOutputs2.length];
-        int i = 0;
-        for (Future f : mOutputs2) {
-            Object output = f.getValue();
-            if (output instanceof Input) {
-                output = ((Input)output).get();
-            }
-            outputObjs[i++] = output;
-        }
-        return outputObjs;
-    }
-
-    /**
-     * Sets an input of the ScriptGroup. This specifies an
-     * Allocation to be used for kernels that require an input
-     * Allocation provided from outside of the ScriptGroup.
-     *
-     * @deprecated Set arguments to {@link #execute(Object...)} instead.
-     *
-     * @param s The ID of the kernel where the allocation should be
-     *          connected.
-     * @param a The allocation to connect.
-     */
-    @Deprecated
-    public void setInput(Script.KernelID s, Allocation a) {
-        for (int ct=0; ct < mInputs.length; ct++) {
-            if (mInputs[ct].mKID == s) {
-                mInputs[ct].mAllocation = a;
-                if (!mUseIncSupp) {
-                    mRS.nScriptGroupSetInput(getID(mRS), s.getID(mRS), mRS.safeID(a));
-                }
-                return;
-            }
-        }
-        throw new RSIllegalArgumentException("Script not found");
-    }
-
-    /**
-     * Sets an output of the ScriptGroup. This specifies an
-     * Allocation to be used for the kernels that require an output
-     * Allocation visible after the ScriptGroup is executed.
-     *
-     * @deprecated Use return value of {@link #execute(Object...)} instead.
-     *
-     * @param s The ID of the kernel where the allocation should be
-     *          connected.
-     * @param a The allocation to connect.
-     */
-    @Deprecated
-    public void setOutput(Script.KernelID s, Allocation a) {
-        for (int ct=0; ct < mOutputs.length; ct++) {
-            if (mOutputs[ct].mKID == s) {
-                mOutputs[ct].mAllocation = a;
-                if (!mUseIncSupp) {
-                    mRS.nScriptGroupSetOutput(getID(mRS), s.getID(mRS), mRS.safeID(a));
-                }
-                return;
-            }
-        }
-        throw new RSIllegalArgumentException("Script not found");
-    }
-
-    /**
-     * Execute the ScriptGroup.  This will run all the kernels in
-     * the ScriptGroup.  No internal connection results will be visible
-     * after execution of the ScriptGroup.
-     *
-     * If Incremental Support for intrinsics is needed, the execution
-     * will take the naive path: execute kernels one by one in the
-     * correct order.
-     *
-     * @deprecated Use {@link #execute} instead.
-     */
-    @Deprecated
-    public void execute() {
-        if (!mUseIncSupp) {
-            mRS.nScriptGroupExecute(getID(mRS));
-        } else {
-            // setup the allocations.
-            for (int ct=0; ct < mNodes.size(); ct++) {
-                Node n = mNodes.get(ct);
-                for (int ct2=0; ct2 < n.mOutputs.size(); ct2++) {
-                    ConnectLine l = n.mOutputs.get(ct2);
-                    if (l.mAllocation !=null) {
-                        continue;
-                    }
-
-                    //create allocation here
-                    Allocation alloc = Allocation.createTyped(mRS, l.mAllocationType,
-                                                              Allocation.MipmapControl.MIPMAP_NONE,
-                                                              Allocation.USAGE_SCRIPT);
-
-                    l.mAllocation = alloc;
-                    for (int ct3=ct2+1; ct3 < n.mOutputs.size(); ct3++) {
-                        if (n.mOutputs.get(ct3).mFrom == l.mFrom) {
-                            n.mOutputs.get(ct3).mAllocation = alloc;
-                        }
-                    }
-                }
-            }
-            for (Node node : mNodes) {
-                for (Script.KernelID kernel : node.mKernels) {
-                    Allocation ain  = null;
-                    Allocation aout = null;
-
-                    for (ConnectLine nodeInput : node.mInputs) {
-                        if (nodeInput.mToK == kernel) {
-                            ain = nodeInput.mAllocation;
-                        }
-                    }
-
-                    for (IO sgInput : mInputs) {
-                        if (sgInput.mKID == kernel) {
-                            ain = sgInput.mAllocation;
-                        }
-                    }
-
-                    for (ConnectLine nodeOutput : node.mOutputs) {
-                        if (nodeOutput.mFrom == kernel) {
-                            aout = nodeOutput.mAllocation;
-                        }
-                    }
-
-                    for (IO sgOutput : mOutputs) {
-                        if (sgOutput.mKID == kernel) {
-                            aout = sgOutput.mAllocation;
-                        }
-                    }
-
-                    kernel.mScript.forEach(kernel.mSlot, ain, aout, null);
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Helper class to build a ScriptGroup. A ScriptGroup is
-     * created in two steps.
-     * <p>
-     * First, all kernels to be used by the ScriptGroup should be added.
-     * <p>
-     * Second, add connections between kernels. There are two types
-     * of connections: kernel to kernel and kernel to field.
-     * Kernel to kernel allows a kernel's output to be passed to
-     * another kernel as input. Kernel to field allows the output of
-     * one kernel to be bound as a script global. Kernel to kernel is
-     * higher performance and should be used where possible.
-     * <p>
-     * A ScriptGroup must contain a single directed acyclic graph (DAG); it
-     * cannot contain cycles. Currently, all kernels used in a ScriptGroup
-     * must come from different Script objects. Additionally, all kernels
-     * in a ScriptGroup must have at least one input, output, or internal
-     * connection.
-     * <p>
-     * Once all connections are made, a call to {@link #create} will
-     * return the ScriptGroup object.
-     *
-     * @deprecated Use {@link Builder2} instead.
-     *
-     */
-    @Deprecated
-    public static final class Builder {
-        private RenderScript mRS;
-        private ArrayList<Node> mNodes = new ArrayList<Node>();
-        private ArrayList<ConnectLine> mLines = new ArrayList<ConnectLine>();
-        private int mKernelCount;
-        private boolean mUseIncSupp = false;
-
-        /**
-         * Create a Builder for generating a ScriptGroup.
-         *
-         *
-         * @param rs The RenderScript context.
-         */
-        public Builder(RenderScript rs) {
-            mRS = rs;
-        }
-
-        // do a DFS from original node, looking for original node
-        // any cycle that could be created must contain original node
-        private void validateCycle(Node target, Node original) {
-            for (int ct = 0; ct < target.mOutputs.size(); ct++) {
-                final ConnectLine cl = target.mOutputs.get(ct);
-                if (cl.mToK != null) {
-                    Node tn = findNode(cl.mToK.mScript);
-                    if (tn.equals(original)) {
-                        throw new RSInvalidStateException("Loops in group not allowed.");
-                    }
-                    validateCycle(tn, original);
-                }
-                if (cl.mToF != null) {
-                    Node tn = findNode(cl.mToF.mScript);
-                    if (tn.equals(original)) {
-                        throw new RSInvalidStateException("Loops in group not allowed.");
-                    }
-                    validateCycle(tn, original);
-                }
-            }
-        }
-
-        private void mergeDAGs(int valueUsed, int valueKilled) {
-            for (int ct=0; ct < mNodes.size(); ct++) {
-                if (mNodes.get(ct).dagNumber == valueKilled)
-                    mNodes.get(ct).dagNumber = valueUsed;
-            }
-        }
-
-        private void validateDAGRecurse(Node n, int dagNumber) {
-            // combine DAGs if this node has been seen already
-            if (n.dagNumber != 0 && n.dagNumber != dagNumber) {
-                mergeDAGs(n.dagNumber, dagNumber);
-                return;
-            }
-
-            n.dagNumber = dagNumber;
-            for (int ct=0; ct < n.mOutputs.size(); ct++) {
-                final ConnectLine cl = n.mOutputs.get(ct);
-                if (cl.mToK != null) {
-                    Node tn = findNode(cl.mToK.mScript);
-                    validateDAGRecurse(tn, dagNumber);
-                }
-                if (cl.mToF != null) {
-                    Node tn = findNode(cl.mToF.mScript);
-                    validateDAGRecurse(tn, dagNumber);
-                }
-            }
-        }
-
-        private void validateDAG() {
-            for (int ct=0; ct < mNodes.size(); ct++) {
-                Node n = mNodes.get(ct);
-                if (n.mInputs.size() == 0) {
-                    if (n.mOutputs.size() == 0 && mNodes.size() > 1) {
-                        String msg = "Groups cannot contain unconnected scripts";
-                        throw new RSInvalidStateException(msg);
-                    }
-                    validateDAGRecurse(n, ct+1);
-                }
-            }
-            int dagNumber = mNodes.get(0).dagNumber;
-            for (int ct=0; ct < mNodes.size(); ct++) {
-                if (mNodes.get(ct).dagNumber != dagNumber) {
-                    throw new RSInvalidStateException("Multiple DAGs in group not allowed.");
-                }
-            }
-        }
-
-        private Node findNode(Script s) {
-            for (int ct=0; ct < mNodes.size(); ct++) {
-                if (s == mNodes.get(ct).mScript) {
-                    return mNodes.get(ct);
-                }
-            }
-            return null;
-        }
-
-        private Node findNode(Script.KernelID k) {
-            for (int ct=0; ct < mNodes.size(); ct++) {
-                Node n = mNodes.get(ct);
-                for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
-                    if (k == n.mKernels.get(ct2)) {
-                        return n;
-                    }
-                }
-            }
-            return null;
-        }
-
-        /**
-         * Adds a Kernel to the group.
-         *
-         *
-         * @param k The kernel to add.
-         *
-         * @return Builder Returns this.
-         */
-        public Builder addKernel(Script.KernelID k) {
-            if (mLines.size() != 0) {
-                throw new RSInvalidStateException(
-                    "Kernels may not be added once connections exist.");
-            }
-            if (k.mScript.isIncSupp()) {
-                mUseIncSupp = true;
-            }
-            //android.util.Log.v("RSR", "addKernel 1 k=" + k);
-            if (findNode(k) != null) {
-                return this;
-            }
-            //android.util.Log.v("RSR", "addKernel 2 ");
-            mKernelCount++;
-            Node n = findNode(k.mScript);
-            if (n == null) {
-                //android.util.Log.v("RSR", "addKernel 3 ");
-                n = new Node(k.mScript);
-                mNodes.add(n);
-            }
-            n.mKernels.add(k);
-            return this;
-        }
-
-        /**
-         * Adds a connection to the group.
-         *
-         *
-         * @param t The type of the connection. This is used to
-         *          determine the kernel launch sizes on the source side
-         *          of this connection.
-         * @param from The source for the connection.
-         * @param to The destination of the connection.
-         *
-         * @return Builder Returns this
-         */
-        public Builder addConnection(Type t, Script.KernelID from, Script.FieldID to) {
-            //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to);
-            Node nf = findNode(from);
-            if (nf == null) {
-                throw new RSInvalidStateException("From script not found.");
-            }
-
-            Node nt = findNode(to.mScript);
-            if (nt == null) {
-                throw new RSInvalidStateException("To script not found.");
-            }
-
-            ConnectLine cl = new ConnectLine(t, from, to);
-            mLines.add(new ConnectLine(t, from, to));
-
-            nf.mOutputs.add(cl);
-            nt.mInputs.add(cl);
-
-            validateCycle(nf, nf);
-            return this;
-        }
-
-        /**
-         * Adds a connection to the group.
-         *
-         *
-         * @param t The type of the connection. This is used to
-         *          determine the kernel launch sizes for both sides of
-         *          this connection.
-         * @param from The source for the connection.
-         * @param to The destination of the connection.
-         *
-         * @return Builder Returns this
-         */
-        public Builder addConnection(Type t, Script.KernelID from, Script.KernelID to) {
-            //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to);
-            Node nf = findNode(from);
-            if (nf == null) {
-                throw new RSInvalidStateException("From script not found.");
-            }
-
-            Node nt = findNode(to);
-            if (nt == null) {
-                throw new RSInvalidStateException("To script not found.");
-            }
-
-            ConnectLine cl = new ConnectLine(t, from, to);
-            mLines.add(new ConnectLine(t, from, to));
-
-            nf.mOutputs.add(cl);
-            nt.mInputs.add(cl);
-
-            validateCycle(nf, nf);
-            return this;
-        }
-
-        /**
-         * Calculate the order of each node.
-         *
-         *
-         * @return Success or Fail
-         */
-        private boolean calcOrderRecurse(Node node0, int depth) {
-            node0.mSeen = true;
-            if (node0.mOrder < depth) {
-                node0.mOrder = depth;
-            }
-            boolean ret = true;
-
-            for (ConnectLine link : node0.mOutputs) {
-                Node node1 = null;
-                if (link.mToF != null) {
-                    node1 = findNode(link.mToF.mScript);
-                } else {
-                    node1 = findNode(link.mToK.mScript);
-                }
-                if (node1.mSeen) {
-                    return false;
-                }
-                ret &= calcOrderRecurse(node1, node0.mOrder + 1);
-            }
-
-            return ret;
-        }
-
-        private boolean calcOrder() {
-            boolean ret = true;
-            for (Node n0 : mNodes) {
-                if (n0.mInputs.size() == 0) {
-                    for (Node n1 : mNodes) {
-                        n1.mSeen = false;
-                    }
-                    ret &= calcOrderRecurse(n0, 1);
-                }
-            }
-
-            Collections.sort(mNodes, new Comparator<Node>() {
-                public int compare(Node n1, Node n2) {
-                    return n1.mOrder - n2.mOrder;
-                }
-            });
-
-            return ret;
-        }
-
-        /**
-         * Creates the Script group.
-         *
-         *
-         * @return ScriptGroup The new ScriptGroup
-         */
-        public ScriptGroup create() {
-
-            if (mNodes.size() == 0) {
-                throw new RSInvalidStateException("Empty script groups are not allowed");
-            }
-
-            // reset DAG numbers in case we're building a second group
-            for (int ct=0; ct < mNodes.size(); ct++) {
-                mNodes.get(ct).dagNumber = 0;
-            }
-            validateDAG();
-
-            ArrayList<IO> inputs = new ArrayList<IO>();
-            ArrayList<IO> outputs = new ArrayList<IO>();
-
-            long[] kernels = new long[mKernelCount];
-            int idx = 0;
-            for (int ct=0; ct < mNodes.size(); ct++) {
-                Node n = mNodes.get(ct);
-                for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
-                    final Script.KernelID kid = n.mKernels.get(ct2);
-                    kernels[idx++] = kid.getID(mRS);
-
-                    boolean hasInput = false;
-                    boolean hasOutput = false;
-                    for (int ct3=0; ct3 < n.mInputs.size(); ct3++) {
-                        if (n.mInputs.get(ct3).mToK == kid) {
-                            hasInput = true;
-                        }
-                    }
-                    for (int ct3=0; ct3 < n.mOutputs.size(); ct3++) {
-                        if (n.mOutputs.get(ct3).mFrom == kid) {
-                            hasOutput = true;
-                        }
-                    }
-                    if (!hasInput) {
-                        inputs.add(new IO(kid));
-                    }
-                    if (!hasOutput) {
-                        outputs.add(new IO(kid));
-                    }
-                }
-            }
-            if (idx != mKernelCount) {
-                throw new RSRuntimeException("Count mismatch, should not happen.");
-            }
-
-            long id = 0;
-            if (!mUseIncSupp) {
-                long[] src = new long[mLines.size()];
-                long[] dstk = new long[mLines.size()];
-                long[] dstf = new long[mLines.size()];
-                long[] types = new long[mLines.size()];
-
-                for (int ct=0; ct < mLines.size(); ct++) {
-                    ConnectLine cl = mLines.get(ct);
-                    src[ct] = cl.mFrom.getID(mRS);
-                    if (cl.mToK != null) {
-                        dstk[ct] = cl.mToK.getID(mRS);
-                    }
-                    if (cl.mToF != null) {
-                        dstf[ct] = cl.mToF.getID(mRS);
-                    }
-                    types[ct] = cl.mAllocationType.getID(mRS);
-                }
-                id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types);
-                if (id == 0) {
-                    throw new RSRuntimeException("Object creation error, should not happen.");
-                }
-            } else {
-                //Calculate the order of the DAG so that script can run one after another.
-                calcOrder();
-            }
-
-            ScriptGroup sg = new ScriptGroup(id, mRS);
-            sg.mOutputs = new IO[outputs.size()];
-            for (int ct=0; ct < outputs.size(); ct++) {
-                sg.mOutputs[ct] = outputs.get(ct);
-            }
-
-            sg.mInputs = new IO[inputs.size()];
-            for (int ct=0; ct < inputs.size(); ct++) {
-                sg.mInputs[ct] = inputs.get(ct);
-            }
-            sg.mNodes = mNodes;
-            sg.mUseIncSupp = mUseIncSupp;
-            return sg;
-        }
-
-    }
-
-    /**
-     * Represents a binding of a value to a global variable in a
-     * kernel or invocable function. Used in closure creation.
-     */
-
-    public static final class Binding {
-        private final Script.FieldID mField;
-        private final Object mValue;
-
-        /**
-         * Returns a Binding object that binds value to field
-         *
-         * @param field the Script.FieldID of the global variable
-         * @param value the value
-         */
-
-        public Binding(Script.FieldID field, Object value) {
-            mField = field;
-            mValue = value;
-        }
-
-        /**
-         * Returns the field ID
-         */
-
-        public Script.FieldID getField() { return mField; }
-
-        /**
-         * Returns the value
-         */
-
-        public Object getValue() { return mValue; }
-    }
-
-    /**
-     * The builder class for creating script groups
-     * <p>
-     * A script group is created using closures (see class {@link Closure}).
-     * A closure is a function call to a kernel or
-     * invocable function. Each function argument or global variable accessed inside
-     * the function is bound to 1) a known value, 2) a script group input
-     * (see class {@link Input}), or 3) a
-     * future (see class {@link Future}).
-     * A future is the output of a closure, either the return value of the
-     * function or a global variable written by that function.
-     * <p>
-     * Closures are created using the {@link #addKernel} or {@link #addInvoke}
-     * methods.
-     * When a closure is created, futures from previously created closures
-     * can be used as its inputs.
-     * External script group inputs can be used as inputs to individual closures as well.
-     * An external script group input is created using the {@link #addInput} method.
-     * A script group is created by a call to the {@link #create} method, which
-     * accepts an array of futures as the outputs for the script group.
-     * <p>
-     * Closures in a script group can be evaluated in any order as long as the
-     * following conditions are met:
-     * 1) a closure must be evaluated before any other closures that take its
-     * futures as inputs;
-     * 2) all closures added before an invoke closure must be evaluated
-     * before it;
-     * and 3) all closures added after an invoke closure must be evaluated after
-     * it.
-     * As a special case, the order that the closures are added is a legal
-     * evaluation order. However, other evaluation orders are possible, including
-     * concurrently evaluating independent closures.
-     */
-
-    public static final class Builder2 {
-        RenderScript mRS;
-        List<Closure> mClosures;
-        List<Input> mInputs;
-        private static final String TAG = "ScriptGroup.Builder2";
-
-        /**
-         * Returns a Builder object
-         *
-         * @param rs the RenderScript context
-         */
-        public Builder2(RenderScript rs) {
-            mRS = rs;
-            mClosures = new ArrayList<Closure>();
-            mInputs = new ArrayList<Input>();
-        }
-
-        /**
-         * Adds a closure for a kernel
-         *
-         * @param k Kernel ID for the kernel function
-         * @param returnType Allocation type for the return value
-         * @param args arguments to the kernel function
-         * @param globalBindings bindings for global variables
-         * @return a closure
-         */
-
-        private Closure addKernelInternal(Script.KernelID k, Type returnType, Object[] args,
-                                          Map<Script.FieldID, Object> globalBindings) {
-            Closure c = new Closure(mRS, k, returnType, args, globalBindings);
-            mClosures.add(c);
-            return c;
-        }
-
-        /**
-         * Adds a closure for an invocable function
-         *
-         * @param invoke Invoke ID for the invocable function
-         * @param args arguments to the invocable function
-         * @param globalBindings bindings for global variables
-         * @return a closure
-         */
-
-        private Closure addInvokeInternal(Script.InvokeID invoke, Object[] args,
-                                          Map<Script.FieldID, Object> globalBindings) {
-            Closure c = new Closure(mRS, invoke, args, globalBindings);
-            mClosures.add(c);
-            return c;
-        }
-
-        /**
-         * Adds a script group input
-         *
-         * @return a script group input, which can be used as an argument or a value to
-         *     a global variable for creating closures
-         */
-
-        public Input addInput() {
-            Input unbound = new Input();
-            mInputs.add(unbound);
-            return unbound;
-        }
-
-        /**
-         * Adds a closure for a kernel
-         *
-         * @param k Kernel ID for the kernel function
-         * @param argsAndBindings arguments followed by bindings for global variables
-         * @return a closure
-         */
-
-        public Closure addKernel(Script.KernelID k, Type returnType, Object... argsAndBindings) {
-            ArrayList<Object> args = new ArrayList<Object>();
-            Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
-            if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
-                return null;
-            }
-            return addKernelInternal(k, returnType, args.toArray(), bindingMap);
-        }
-
-        /**
-         * Adds a closure for an invocable function
-         *
-         * @param invoke Invoke ID for the invocable function
-         * @param argsAndBindings arguments followed by bindings for global variables
-         * @return a closure
-         */
-
-        public Closure addInvoke(Script.InvokeID invoke, Object... argsAndBindings) {
-            ArrayList<Object> args = new ArrayList<Object>();
-            Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
-            if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
-                return null;
-            }
-            return addInvokeInternal(invoke, args.toArray(), bindingMap);
-        }
-
-        /**
-         * Creates a script group
-         *
-         * @param name name for the script group. Legal names can only contain letters, digits,
-         *        '-', or '_'. The name can be no longer than 100 characters.
-         * @param outputs futures intended as outputs of the script group
-         * @return a script group
-         */
-
-        public ScriptGroup create(String name, Future... outputs) {
-            if (name == null || name.isEmpty() || name.length() > 100 ||
-                !name.equals(name.replaceAll("[^a-zA-Z0-9-]", "_"))) {
-                throw new RSIllegalArgumentException("invalid script group name");
-            }
-            ScriptGroup ret = new ScriptGroup(mRS, name, mClosures, mInputs, outputs);
-            return ret;
-        }
-
-        private boolean seperateArgsAndBindings(Object[] argsAndBindings,
-                                                ArrayList<Object> args,
-                                                Map<Script.FieldID, Object> bindingMap) {
-            int i;
-            for (i = 0; i < argsAndBindings.length; i++) {
-                if (argsAndBindings[i] instanceof Binding) {
-                    break;
-                }
-                args.add(argsAndBindings[i]);
-            }
-
-            for (; i < argsAndBindings.length; i++) {
-                if (!(argsAndBindings[i] instanceof Binding)) {
-                    return false;
-                }
-                Binding b = (Binding)argsAndBindings[i];
-                bindingMap.put(b.getField(), b.getValue());
-            }
-
-            return true;
-        }
-
-    }
-
-}
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic.java
deleted file mode 100644
index e59cf6d..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-/**
- * Base class for all Intrinsic scripts. An intrinsic a script
- * which implements a pre-defined function. Intrinsics are
- * provided to provide effecient implemtations of common
- * operations.
- *
- * Not intended for direct use.
- **/
-public abstract class ScriptIntrinsic extends Script {
-    ScriptIntrinsic(long id, RenderScript rs) {
-        super(id, rs);
-        if (id == 0) {
-            throw new RSRuntimeException("Loading of ScriptIntrinsic failed.");
-        }
-    }
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic3DLUT.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic3DLUT.java
deleted file mode 100644
index 7fc71f3..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsic3DLUT.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.Log;
-
-/**
- *
- * Intrinsic for converting RGB to RGBA by using a 3D lookup table.  The
- * incoming r,g,b values are use as normalized x,y,z coordinates into a 3D
- * allocation.  The 8 nearest values are sampled and linearly interpolated.  The
- * result is placed in the output.
- *
- **/
-public class ScriptIntrinsic3DLUT extends ScriptIntrinsic {
-    private Allocation mLUT;
-    private Element mElement;
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 19;
-
-    protected ScriptIntrinsic3DLUT(long id, RenderScript rs, Element e) {
-        super(id, rs);
-        mElement = e;
-    }
-
-    /**
-     * Supported elements types are {@link Element#U8_4}
-     *
-     * The defaults tables are identity.
-     *
-     * @param rs The RenderScript context
-     * @param e Element type for intputs and outputs
-     *
-     * @return ScriptIntrinsic3DLUT
-     */
-    public static ScriptIntrinsic3DLUT create(RenderScript rs, Element e) {
-        if (!e.isCompatible(Element.U8_4(rs))) {
-            throw new RSIllegalArgumentException("Element must be compatible with uchar4.");
-        }
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(8, e.getID(rs), mUseIncSupp);
-
-        ScriptIntrinsic3DLUT si = new ScriptIntrinsic3DLUT(id, rs, e);
-        si.setIncSupp(mUseIncSupp);
-        return si;
-    }
-
-    /**
-     * Sets the {@link android.support.v8.renderscript.Allocation} to be used as
-     * the lookup table.
-     *
-     * The lookup table must use the same
-     * {@link android.support.v8.renderscript.Element} as the intrinsic.
-     *
-     */
-
-    public void setLUT(Allocation lut) {
-        final Type t = lut.getType();
-
-        if (t.getZ() == 0) {
-            throw new RSIllegalArgumentException("LUT must be 3d.");
-        }
-
-        if (!t.getElement().isCompatible(mElement)) {
-            throw new RSIllegalArgumentException("LUT element type must match.");
-        }
-
-        mLUT = lut;
-        setVar(0, mLUT);
-    }
-
-
-    /**
-     * Invoke the kernel and apply the lookup to each cell of ain
-     * and copy to aout.
-     *
-     * @param ain Input allocation
-     * @param aout Output allocation
-     */
-    public void forEach(Allocation ain, Allocation aout) {
-        forEach(0, ain, aout, null);
-    }
-
-    /**
-     * Get a KernelID for this intrinsic kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelID() {
-        return createKernelID(0, 3, null, null);
-    }
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicBLAS.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicBLAS.java
deleted file mode 100644
index fe32989..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicBLAS.java
+++ /dev/null
@@ -1,4190 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.support.annotation.IntDef;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- *
- * ScriptIntrinsicBLAS class provides high performance RenderScript APIs to BLAS.
- *
- * The BLAS (Basic Linear Algebra Subprograms) are routines that provide standard
- * building blocks for performing basic vector and matrix operations.
- *
- * For detailed description of BLAS, please refer to http://www.netlib.org/blas/
- *
- **/
-public final class ScriptIntrinsicBLAS extends ScriptIntrinsic {
-    private Allocation mLUT;
-    private static final int INTRINSIC_API_LEVEL = 23;
-
-    private ScriptIntrinsicBLAS(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    private static final int RsBlas_sdsdot = 1;
-    private static final int RsBlas_dsdot = 2;
-    private static final int RsBlas_sdot = 3;
-    private static final int RsBlas_ddot = 4;
-    private static final int RsBlas_cdotu_sub = 5;
-    private static final int RsBlas_cdotc_sub = 6;
-    private static final int RsBlas_zdotu_sub = 7;
-    private static final int RsBlas_zdotc_sub = 8;
-    private static final int RsBlas_snrm2 = 9;
-    private static final int RsBlas_sasum = 10;
-    private static final int RsBlas_dnrm2 = 11;
-    private static final int RsBlas_dasum = 12;
-    private static final int RsBlas_scnrm2 = 13;
-    private static final int RsBlas_scasum = 14;
-    private static final int RsBlas_dznrm2 = 15;
-    private static final int RsBlas_dzasum = 16;
-    private static final int RsBlas_isamax = 17;
-    private static final int RsBlas_idamax = 18;
-    private static final int RsBlas_icamax = 19;
-    private static final int RsBlas_izamax = 20;
-    private static final int RsBlas_sswap = 21;
-    private static final int RsBlas_scopy = 22;
-    private static final int RsBlas_saxpy = 23;
-    private static final int RsBlas_dswap = 24;
-    private static final int RsBlas_dcopy = 25;
-    private static final int RsBlas_daxpy = 26;
-    private static final int RsBlas_cswap = 27;
-    private static final int RsBlas_ccopy = 28;
-    private static final int RsBlas_caxpy = 29;
-    private static final int RsBlas_zswap = 30;
-    private static final int RsBlas_zcopy = 31;
-    private static final int RsBlas_zaxpy = 32;
-    private static final int RsBlas_srotg = 33;
-    private static final int RsBlas_srotmg = 34;
-    private static final int RsBlas_srot = 35;
-    private static final int RsBlas_srotm = 36;
-    private static final int RsBlas_drotg = 37;
-    private static final int RsBlas_drotmg = 38;
-    private static final int RsBlas_drot = 39;
-    private static final int RsBlas_drotm = 40;
-    private static final int RsBlas_sscal = 41;
-    private static final int RsBlas_dscal = 42;
-    private static final int RsBlas_cscal = 43;
-    private static final int RsBlas_zscal = 44;
-    private static final int RsBlas_csscal = 45;
-    private static final int RsBlas_zdscal = 46;
-    private static final int RsBlas_sgemv = 47;
-    private static final int RsBlas_sgbmv = 48;
-    private static final int RsBlas_strmv = 49;
-    private static final int RsBlas_stbmv = 50;
-    private static final int RsBlas_stpmv = 51;
-    private static final int RsBlas_strsv = 52;
-    private static final int RsBlas_stbsv = 53;
-    private static final int RsBlas_stpsv = 54;
-    private static final int RsBlas_dgemv = 55;
-    private static final int RsBlas_dgbmv = 56;
-    private static final int RsBlas_dtrmv = 57;
-    private static final int RsBlas_dtbmv = 58;
-    private static final int RsBlas_dtpmv = 59;
-    private static final int RsBlas_dtrsv = 60;
-    private static final int RsBlas_dtbsv = 61;
-    private static final int RsBlas_dtpsv = 62;
-    private static final int RsBlas_cgemv = 63;
-    private static final int RsBlas_cgbmv = 64;
-    private static final int RsBlas_ctrmv = 65;
-    private static final int RsBlas_ctbmv = 66;
-    private static final int RsBlas_ctpmv = 67;
-    private static final int RsBlas_ctrsv = 68;
-    private static final int RsBlas_ctbsv = 69;
-    private static final int RsBlas_ctpsv = 70;
-    private static final int RsBlas_zgemv = 71;
-    private static final int RsBlas_zgbmv = 72;
-    private static final int RsBlas_ztrmv = 73;
-    private static final int RsBlas_ztbmv = 74;
-    private static final int RsBlas_ztpmv = 75;
-    private static final int RsBlas_ztrsv = 76;
-    private static final int RsBlas_ztbsv = 77;
-    private static final int RsBlas_ztpsv = 78;
-    private static final int RsBlas_ssymv = 79;
-    private static final int RsBlas_ssbmv = 80;
-    private static final int RsBlas_sspmv = 81;
-    private static final int RsBlas_sger = 82;
-    private static final int RsBlas_ssyr = 83;
-    private static final int RsBlas_sspr = 84;
-    private static final int RsBlas_ssyr2 = 85;
-    private static final int RsBlas_sspr2 = 86;
-    private static final int RsBlas_dsymv = 87;
-    private static final int RsBlas_dsbmv = 88;
-    private static final int RsBlas_dspmv = 89;
-    private static final int RsBlas_dger = 90;
-    private static final int RsBlas_dsyr = 91;
-    private static final int RsBlas_dspr = 92;
-    private static final int RsBlas_dsyr2 = 93;
-    private static final int RsBlas_dspr2 = 94;
-    private static final int RsBlas_chemv = 95;
-    private static final int RsBlas_chbmv = 96;
-    private static final int RsBlas_chpmv = 97;
-    private static final int RsBlas_cgeru = 98;
-    private static final int RsBlas_cgerc = 99;
-    private static final int RsBlas_cher = 100;
-    private static final int RsBlas_chpr = 101;
-    private static final int RsBlas_cher2 = 102;
-    private static final int RsBlas_chpr2 = 103;
-    private static final int RsBlas_zhemv = 104;
-    private static final int RsBlas_zhbmv = 105;
-    private static final int RsBlas_zhpmv = 106;
-    private static final int RsBlas_zgeru = 107;
-    private static final int RsBlas_zgerc = 108;
-    private static final int RsBlas_zher = 109;
-    private static final int RsBlas_zhpr = 110;
-    private static final int RsBlas_zher2 = 111;
-    private static final int RsBlas_zhpr2 = 112;
-    private static final int RsBlas_sgemm = 113;
-    private static final int RsBlas_ssymm = 114;
-    private static final int RsBlas_ssyrk = 115;
-    private static final int RsBlas_ssyr2k = 116;
-    private static final int RsBlas_strmm = 117;
-    private static final int RsBlas_strsm = 118;
-    private static final int RsBlas_dgemm = 119;
-    private static final int RsBlas_dsymm = 120;
-    private static final int RsBlas_dsyrk = 121;
-    private static final int RsBlas_dsyr2k = 122;
-    private static final int RsBlas_dtrmm = 123;
-    private static final int RsBlas_dtrsm = 124;
-    private static final int RsBlas_cgemm = 125;
-    private static final int RsBlas_csymm = 126;
-    private static final int RsBlas_csyrk = 127;
-    private static final int RsBlas_csyr2k = 128;
-    private static final int RsBlas_ctrmm = 129;
-    private static final int RsBlas_ctrsm = 130;
-    private static final int RsBlas_zgemm = 131;
-    private static final int RsBlas_zsymm = 132;
-    private static final int RsBlas_zsyrk = 133;
-    private static final int RsBlas_zsyr2k = 134;
-    private static final int RsBlas_ztrmm = 135;
-    private static final int RsBlas_ztrsm = 136;
-    private static final int RsBlas_chemm = 137;
-    private static final int RsBlas_cherk = 138;
-    private static final int RsBlas_cher2k = 139;
-    private static final int RsBlas_zhemm = 140;
-    private static final int RsBlas_zherk = 141;
-    private static final int RsBlas_zher2k = 142;
-
-    // BLAS extensions start here
-    private static final int RsBlas_bnnm = 1000;
-
-    /**
-     * Create an intrinsic to access BLAS subroutines.
-     *
-     * @param rs The RenderScript context
-     * @return ScriptIntrinsicBLAS
-     */
-    public static ScriptIntrinsicBLAS create(RenderScript rs) {
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(13, Element.U32(rs).getID(rs), mUseIncSupp);
-        ScriptIntrinsicBLAS si = new ScriptIntrinsicBLAS(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        return si;
-    }
-
-    /**
-     * @hide
-     */
-    @IntDef({NO_TRANSPOSE, TRANSPOSE, CONJ_TRANSPOSE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Transpose {}
-
-    /**
-     * @hide
-     */
-    @IntDef({UPPER, LOWER})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Uplo {}
-
-    /**
-     * @hide
-     */
-    @IntDef({NON_UNIT, UNIT})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Diag {}
-
-    /**
-     * @hide
-     */
-    @IntDef({LEFT, RIGHT})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Side {}
-
-    public static final int NO_TRANSPOSE = 111;
-    public static final int TRANSPOSE = 112;
-    public static final int CONJ_TRANSPOSE = 113;
-
-    public static final int UPPER = 121;
-    public static final int LOWER = 122;
-
-    public static final int NON_UNIT = 131;
-    public static final int UNIT = 132;
-
-    public static final int LEFT = 141;
-    public static final int RIGHT = 142;
-
-    static void validateSide(@Side int Side) {
-        if (Side != LEFT && Side != RIGHT) {
-            throw new RSRuntimeException("Invalid side passed to BLAS");
-        }
-    }
-
-    static void validateTranspose(@Transpose int Trans) {
-        if (Trans != NO_TRANSPOSE && Trans != TRANSPOSE &&
-            Trans != CONJ_TRANSPOSE) {
-            throw new RSRuntimeException("Invalid transpose passed to BLAS");
-        }
-    }
-
-    static void validateConjTranspose(@Transpose int Trans) {
-        if (Trans != NO_TRANSPOSE &&
-            Trans != CONJ_TRANSPOSE) {
-            throw new RSRuntimeException("Invalid transpose passed to BLAS");
-        }
-    }
-
-    static void validateDiag(@Diag int Diag) {
-        if (Diag != NON_UNIT && Diag != UNIT) {
-            throw new RSRuntimeException("Invalid diag passed to BLAS");
-        }
-    }
-
-    static void validateUplo(@Uplo int Uplo) {
-        if (Uplo != UPPER && Uplo != LOWER) {
-            throw new RSRuntimeException("Invalid uplo passed to BLAS");
-        }
-    }
-
-
-    /**
-     * Level 2 BLAS
-     */
-
-    static void validateGEMV(Element e, int TransA, Allocation A, Allocation X, int incX, Allocation Y, int incY) {
-        validateTranspose(TransA);
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        if (incX <= 0 || incY <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = -1, expectedYDim = -1;
-        if (TransA == NO_TRANSPOSE) {
-            expectedXDim = 1 + (N - 1) * incX;
-            expectedYDim = 1 + (M - 1) * incY;
-        } else {
-            expectedXDim = 1 + (M - 1) * incX;
-            expectedYDim = 1 + (N - 1) * incY;
-        }
-        if (X.getType().getX() != expectedXDim ||
-            Y.getType().getX() != expectedYDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for GEMV");
-        }
-    }
-
-    /**
-     * SGEMV performs one of the matrix-vector operations
-     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/d58/sgemv_8f.html
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void SGEMV(@Transpose int TransA, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
-        validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DGEMV performs one of the matrix-vector operations
-     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/dc/da8/dgemv_8f.html
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void DGEMV(@Transpose int TransA, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
-        validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CGEMV performs one of the matrix-vector operations
-     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y   or   y := alpha*A**H*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d4/d8a/cgemv_8f.html
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void CGEMV(@Transpose int TransA, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
-        validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZGEMV performs one of the matrix-vector operations
-     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y   or   y := alpha*A**H*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/d40/zgemv_8f.html
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void ZGEMV(@Transpose int TransA, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
-        validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SGBMV performs one of the matrix-vector operations
-     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d6/d46/sgbmv_8f.html
-     *
-     * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
-     *       but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, m):
-     *              for j in range(max(0, i-kl), min(i+ku+1, n)):
-     *                  b[i, j-i+kl] = a[i, j]
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param KL The number of sub-diagonals of the matrix A.
-     * @param KU The number of super-diagonals of the matrix A.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void SGBMV(@Transpose int TransA, int KL, int KU, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
-        // GBMV has the same validation requirements as GEMV + KL and KU >= 0
-        validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
-        if (KL < 0 || KU < 0) {
-            throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
-        }
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, KL, KU, mUseIncSupp);
-    }
-
-    /**
-     * DGBMV performs one of the matrix-vector operations
-     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d2/d3f/dgbmv_8f.html
-     *
-     * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
-     *       but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, m):
-     *              for j in range(max(0, i-kl), min(i+ku+1, n)):
-     *                  b[i, j-i+kl] = a[i, j]
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param KL The number of sub-diagonals of the matrix A.
-     * @param KU The number of super-diagonals of the matrix A.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void DGBMV(@Transpose int TransA, int KL, int KU, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
-        // GBMV has the same validation requirements as GEMV + KL and KU >= 0
-        validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
-        if (KL < 0 || KU < 0) {
-            throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
-        }
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, KL, KU, mUseIncSupp);
-    }
-
-    /**
-     * CGBMV performs one of the matrix-vector operations
-     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y   or   y := alpha*A**H*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d0/d75/cgbmv_8f.html
-     *
-     * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
-     *       but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, m):
-     *              for j in range(max(0, i-kl), min(i+ku+1, n)):
-     *                  b[i, j-i+kl] = a[i, j]
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param KL The number of sub-diagonals of the matrix A.
-     * @param KU The number of super-diagonals of the matrix A.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void CGBMV(@Transpose int TransA, int KL, int KU, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
-        // GBMV has the same validation requirements as GEMV + KL and KU >= 0
-        validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
-        if (KL < 0 || KU < 0) {
-            throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
-        }
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, KL, KU, mUseIncSupp);
-    }
-
-    /**
-     * ZGBMV performs one of the matrix-vector operations
-     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y   or   y := alpha*A**H*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d9/d46/zgbmv_8f.html
-     *
-     * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
-     *       but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, m):
-     *              for j in range(max(0, i-kl), min(i+ku+1, n)):
-     *                  b[i, j-i+kl] = a[i, j]
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param KL The number of sub-diagonals of the matrix A.
-     * @param KU The number of super-diagonals of the matrix A.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void ZGBMV(@Transpose int TransA, int KL, int KU, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
-        // GBMV has the same validation requirements as GEMV + KL and KU >= 0
-        validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
-        if (KL < 0 || KU < 0) {
-            throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
-        }
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, KL, KU, mUseIncSupp);
-    }
-
-    static void validateTRMV(Element e, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
-        validateTranspose(TransA);
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        int N = A.getType().getY();
-        if (A.getType().getX() != N) {
-            throw new RSRuntimeException("A must be a square matrix for TRMV");
-        }
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        if (X.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        if (incX <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for TRMV");
-        }
-    }
-
-    static int validateTPMV(Element e, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
-        validateTranspose(TransA);
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        if (!Ap.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        if (X.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        if (Ap.getType().getY() > 1) {
-            throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
-        }
-
-        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
-        //is it really doing anything?
-        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
-            throw new RSRuntimeException("Invalid dimension for Ap");
-        }
-        if (incX <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for TPMV");
-        }
-
-        return N;
-    }
-
-    /**
-     * STRMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/de/d45/strmv_8f.html
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void STRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
-        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DTRMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/dc/d7e/dtrmv_8f.html
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void DTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
-        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CTRMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x   or   x := A**H*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/df/d78/ctrmv_8f.html
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void CTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
-        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZTRMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x   or   x := A**H*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d0/dd1/ztrmv_8f.html
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void ZTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
-        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * STBMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d6/d7d/stbmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param K The number of off-diagonals of the matrix A
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void STBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBMV has the same requirements as TRMV + K >= 0
-        if (K < 0) {
-            throw new RSRuntimeException("K must be greater than or equal to 0");
-        }
-        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DTBMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/df/d29/dtbmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param K The number of off-diagonals of the matrix A
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void DTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBMV has the same requirements as TRMV + K >= 0
-        if (K < 0) {
-            throw new RSRuntimeException("K must be greater than or equal to 0");
-        }
-        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CTBMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x   or   x := A**H*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d3/dcd/ctbmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param K The number of off-diagonals of the matrix A
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void CTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBMV has the same requirements as TRMV + K >= 0
-        if (K < 0) {
-            throw new RSRuntimeException("K must be greater than or equal to 0");
-        }
-        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZTBMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x   or   x := A**H*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d3/d39/ztbmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param K The number of off-diagonals of the matrix A
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void ZTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBMV has the same requirements as TRMV + K >= 0
-        if (K < 0) {
-            throw new RSRuntimeException("K must be greater than or equal to 0");
-        }
-        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * STPMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/db1/stpmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void STPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
-        int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DTPMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/dc/dcd/dtpmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void DTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
-        int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CTPMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x   or   x := A**H*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d4/dbb/ctpmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void CTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
-        int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZTPMV performs one of the matrix-vector operations
-     * x := A*x   or   x := A**T*x   or   x := A**H*x
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d2/d9e/ztpmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void ZTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
-        int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * STRSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d0/d2a/strsv_8f.html
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void STRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
-        // TRSV is the same as TRMV
-        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-
-    }
-
-    /**
-     * DTRSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d6/d96/dtrsv_8f.html
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void DTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
-        // TRSV is the same as TRMV
-        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-
-    }
-
-    /**
-     * CTRSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b   or   A**H*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d4/dc8/ctrsv_8f.html
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void CTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
-        // TRSV is the same as TRMV
-        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-
-    }
-
-    /**
-     * ZTRSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b   or   A**H*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d1/d2f/ztrsv_8f.html
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void ZTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
-        // TRSV is the same as TRMV
-        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-
-    }
-
-    /**
-     * STBSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d0/d1f/stbsv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param K The number of off-diagonals of the matrix A
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void STBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBSV is the same as TRMV + K >= 0
-        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-        if (K < 0) {
-            throw new RSRuntimeException("Number of diagonals must be positive");
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DTBSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d4/dcf/dtbsv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param K The number of off-diagonals of the matrix A
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void DTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBSV is the same as TRMV + K >= 0
-        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-        if (K < 0) {
-            throw new RSRuntimeException("Number of diagonals must be positive");
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CTBSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b   or   A**H*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d9/d5f/ctbsv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param K The number of off-diagonals of the matrix A
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void CTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBSV is the same as TRMV + K >= 0
-        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-        if (K < 0) {
-            throw new RSRuntimeException("Number of diagonals must be positive");
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZTBSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b   or   A**H*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d4/d5a/ztbsv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param K The number of off-diagonals of the matrix A
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void ZTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
-        // TBSV is the same as TRMV + K >= 0
-        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
-        int N = A.getType().getY();
-        if (K < 0) {
-            throw new RSRuntimeException("Number of diagonals must be positive");
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * STPSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d0/d7c/stpsv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void STPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
-        // TPSV is same as TPMV
-        int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DTPSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d9/d84/dtpsv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void DTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
-        // TPSV is same as TPMV
-        int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CTPSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b   or   A**H*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d8/d56/ctpsv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void CTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
-        // TPSV is same as TPMV
-        int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZTPSV solves one of the systems of equations
-     * A*x = b   or   A**T*x = b   or   A**H*x = b
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/da/d57/ztpsv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     */
-    public void ZTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
-        // TPSV is same as TPMV
-        int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * Level 2, S and D only
-     */
-    static int validateSYMV(Element e, @Uplo int Uplo, Allocation A, Allocation X, Allocation Y, int incX, int incY) {
-        validateUplo(Uplo);
-        int N = A.getType().getY();
-        if (A.getType().getX() != N) {
-            throw new RSRuntimeException("A must be a square matrix for SYMV");
-        }
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e) ) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        if (incX <= 0 || incY <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SYMV");
-        }
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (Y.getType().getX() != expectedYDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SYMV");
-        }
-        return N;
-    }
-    static int validateSPMV(Element e, @Uplo int Uplo, Allocation Ap, Allocation X, int incX, Allocation Y, int incY) {
-        validateUplo(Uplo);
-        if (!Ap.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        if (Ap.getType().getY() > 1) {
-            throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
-        }
-
-        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
-        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
-            throw new RSRuntimeException("Invalid dimension for Ap");
-        }
-        if (incX <= 0 || incY <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SPMV");
-        }
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (Y.getType().getX() != expectedYDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SPMV");
-        }
-
-        return N;
-    }
-    static void validateGER(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e) ) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        if (N < 1 || M < 1) {
-            throw new RSRuntimeException("M and N must be 1 or greater for GER");
-        }
-        if (incX <= 0 || incY <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (M - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for GER");
-        }
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (Y.getType().getX() != expectedYDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for GER");
-        }
-
-
-    }
-    static int validateSYR(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation A) {
-        validateUplo(Uplo);
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-
-        int N = A.getType().getX();
-
-        if (X.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-        if (N != A.getType().getY()) {
-            throw new RSRuntimeException("A must be a symmetric matrix");
-        }
-        if (incX <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SYR");
-        }
-        return N;
-    }
-    static int validateSPR(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation Ap) {
-        validateUplo(Uplo);
-        if (!Ap.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        if (X.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        if (Ap.getType().getY() > 1) {
-            throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
-        }
-
-        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
-        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
-            throw new RSRuntimeException("Invalid dimension for Ap");
-        }
-        if (incX <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SPR");
-        }
-
-        return N;
-    }
-
-    static int validateSYR2(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        validateUplo(Uplo);
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        int N = A.getType().getX();
-
-        if (N != A.getType().getY()) {
-            throw new RSRuntimeException("A must be a symmetric matrix");
-        }
-        if (incX <= 0 || incY <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SYR");
-        }
-        return N;
-
-    }
-    static int validateSPR2(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
-        validateUplo(Uplo);
-        if (!Ap.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        if (Ap.getType().getY() > 1) {
-            throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
-        }
-
-        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
-        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
-            throw new RSRuntimeException("Invalid dimension for Ap");
-        }
-        if (incX <= 0 || incY <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (N - 1) * incX;
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for SPR2");
-        }
-
-        return N;
-    }
-
-    /**
-     * SSYMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d2/d94/ssymv_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void SSYMV(@Uplo int Uplo, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
-        int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SSBMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d3/da1/ssbmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
-     * @param K The number of off-diagonals of the matrix A
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void SSBMV(@Uplo int Uplo, int K, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
-        // SBMV is the same as SYMV + K >= 0
-        if (K < 0) {
-            throw new RSRuntimeException("K must be greater than or equal to 0");
-        }
-        int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SSPMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d8/d68/sspmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
-     * @param alpha The scalar alpha.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void SSPMV(@Uplo int Uplo, float alpha, Allocation Ap, Allocation X, int incX, float beta, Allocation Y, int incY) {
-        int N = validateSPMV(Element.F32(mRS), Uplo, Ap, X, incX, Y, incY);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, apID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SGER performs the rank 1 operation
-     * A := alpha*x*y**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/d5c/sger_8f.html
-     *
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     */
-    public void SGER(float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-        validateGER(Element.F32(mRS), X, incX, Y, incY, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sger, 0, 0, 0, 0, 0, M, N, 0, alpha, xID, yID, 0.f, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SSYR performs the rank 1 operation
-     * A := alpha*x*x**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d6/dac/ssyr_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     */
-    public void SSYR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
-        int N = validateSYR(Element.F32(mRS), Uplo, X, incX, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, aID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SSPR performs the rank 1 operation
-     * A := alpha*x*x**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d2/d9b/sspr_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     */
-    public void SSPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
-        int N = validateSPR(Element.F32(mRS), Uplo, X, incX, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, apID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SSYR2 performs the symmetric rank 2 operation
-     * A := alpha*x*y**T + alpha*y*x**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/d99/ssyr2_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     */
-    public void SSYR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        int N = validateSYR2(Element.F32(mRS), Uplo, X, incX, Y, incY, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SSPR2 performs the symmetric rank 2 operation
-     * A := alpha*x*y**T + alpha*y*x**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/d3e/sspr2_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     */
-    public void SSPR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
-        int N = validateSPR2(Element.F32(mRS), Uplo, X, incX, Y, incY, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, apID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSYMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d8/dbe/dsymv_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void DSYMV(@Uplo int Uplo, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
-        int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSBMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d8/d1e/dsbmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
-     * @param K The number of off-diagonals of the matrix A
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void DSBMV(@Uplo int Uplo, int K, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
-        // SBMV is the same as SYMV + K >= 0
-        if (K < 0) {
-            throw new RSRuntimeException("K must be greater than or equal to 0");
-        }
-        int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSPMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d4/d85/dspmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
-     * @param alpha The scalar alpha.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void DSPMV(@Uplo int Uplo, double alpha, Allocation Ap, Allocation X, int incX, double beta, Allocation Y, int incY) {
-        int N = validateSPMV(Element.F64(mRS), Uplo, Ap, X, incX, Y, incY);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, apID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DGER performs the rank 1 operation
-     * A := alpha*x*y**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/dc/da8/dger_8f.html
-     *
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     */
-    public void DGER(double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-        validateGER(Element.F64(mRS), X, incX, Y, incY, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dger, 0, 0, 0, 0, 0, M, N, 0, alpha, xID, yID, 0.f, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSYR performs the rank 1 operation
-     * A := alpha*x*x**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d3/d60/dsyr_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     */
-    public void DSYR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
-        int N = validateSYR(Element.F64(mRS), Uplo, X, incX, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, aID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSPR performs the rank 1 operation
-     * A := alpha*x*x**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/dd/dba/dspr_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     */
-    public void DSPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
-        int N = validateSPR(Element.F64(mRS), Uplo, X, incX, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, apID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSYR2 performs the symmetric rank 2 operation
-     * A := alpha*x*y**T + alpha*y*x**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/de/d41/dsyr2_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     */
-    public void DSYR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        int N = validateSYR2(Element.F64(mRS), Uplo, X, incX, Y, incY, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSPR2 performs the symmetric rank 2 operation
-     * A := alpha*x*y**T + alpha*y*x**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/dd/d9e/dspr2_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     */
-    public void DSPR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
-        int N = validateSPR2(Element.F64(mRS), Uplo, X, incX, Y, incY, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, apID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-
-    /**
-     * Level 2, C and Z only
-     */
-
-    static void validateGERU(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        if (!A.getType().getElement().isCompatible(e) ||
-            !X.getType().getElement().isCompatible(e) ||
-            !Y.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
-            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
-        }
-
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-        if (incX <= 0 || incY <= 0) {
-            throw new RSRuntimeException("Vector increments must be greater than 0");
-        }
-        int expectedXDim = 1 + (M - 1) * incX;
-        if (X.getType().getX() != expectedXDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for GERU");
-        }
-        int expectedYDim = 1 + (N - 1) * incY;
-        if (Y.getType().getX() != expectedYDim) {
-            throw new RSRuntimeException("Incorrect vector dimensions for GERU");
-        }
-
-    }
-
-    /**
-     * CHEMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d7/d51/chemv_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void CHEMV(@Uplo int Uplo, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
-        // HEMV is the same as SYR2 validation-wise
-        int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CHBMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/dc2/chbmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
-     * @param K The number of off-diagonals of the matrix A
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void CHBMV(@Uplo int Uplo, int K, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
-        // HBMV is the same as SYR2 validation-wise
-        int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
-        if (K < 0) {
-            throw new RSRuntimeException("K must be 0 or greater for HBMV");
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CHPMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d2/d06/chpmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
-     * @param alpha The scalar alpha.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void CHPMV(@Uplo int Uplo, Float2 alpha, Allocation Ap, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
-        // HPMV is the same as SPR2
-        int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, apID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CGERU performs the rank 1 operation
-     * A := alpha*x*y**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/d5f/cgeru_8f.html
-     *
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     */
-    public void CGERU(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CGERC performs the rank 1 operation
-     * A := alpha*x*y**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/dd/d84/cgerc_8f.html
-     *
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     */
-    public void CGERC(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        // same as GERU
-        validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CHER performs the rank 1 operation
-     * A := alpha*x*x**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d3/d6d/cher_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     */
-    public void CHER(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
-        // same as SYR
-        int N = validateSYR(Element.F32_2(mRS), Uplo, X, incX, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, aID, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CHPR performs the rank 1 operation
-     * A := alpha*x*x**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/dcd/chpr_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     */
-    public void CHPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
-        // equivalent to SPR for validation
-        int N = validateSPR(Element.F32_2(mRS), Uplo, X, incX, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, apID, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CHER2 performs the symmetric rank 2 operation
-     * A := alpha*x*y**H + alpha*y*x**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/d87/cher2_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     */
-    public void CHER2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        // same as SYR2
-        int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CHPR2 performs the symmetric rank 2 operation
-     * A := alpha*x*y**H + alpha*y*x**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d6/d44/chpr2_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     */
-    public void CHPR2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
-        // same as SPR2
-        int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, apID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHEMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d0/ddd/zhemv_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void ZHEMV(@Uplo int Uplo, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
-        // HEMV is the same as SYR2 validation-wise
-        int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHBMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d3/d1a/zhbmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
-     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
-     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
-     *           for i in range(0, n):
-     *              for j in range(i, min(i+k+1, n)):
-     *                  b[i, j-i] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
-     * @param K The number of off-diagonals of the matrix A
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void ZHBMV(@Uplo int Uplo, int K, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
-        // HBMV is the same as SYR2 validation-wise
-        int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
-        if (K < 0) {
-            throw new RSRuntimeException("K must be 0 or greater for HBMV");
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHPMV performs the matrix-vector operation
-     * y := alpha*A*x + beta*y
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d0/d60/zhpmv_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
-     * @param alpha The scalar alpha.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param beta The scalar beta.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     */
-    public void ZHPMV(@Uplo int Uplo, Double2 alpha, Allocation Ap, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
-        // HPMV is the same as SPR2
-        int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, apID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZGERU performs the rank 1 operation
-     * A := alpha*x*y**T + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d7/d12/zgeru_8f.html
-     *
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     */
-    public void ZGERU(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZGERC performs the rank 1 operation
-     * A := alpha*x*y**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d3/dad/zgerc_8f.html
-     *
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     */
-    public void ZGERC(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        // same as GERU
-        validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
-        int M = A.getType().getY();
-        int N = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHER performs the rank 1 operation
-     * A := alpha*x*x**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/de/d0e/zher_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     */
-    public void ZHER(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
-        // same as SYR
-        int N = validateSYR(Element.F64_2(mRS), Uplo, X, incX, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, aID, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHPR performs the rank 1 operation
-     * A := alpha*x*x**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/de/de1/zhpr_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     */
-    public void ZHPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
-        // equivalent to SPR for validation
-        int N = validateSPR(Element.F64_2(mRS), Uplo, X, incX, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, apID, incX, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHER2 performs the symmetric rank 2 operation
-     * A := alpha*x*y**H + alpha*y*x**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/da/d8a/zher2_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     */
-    public void ZHER2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
-        // same as SYR2
-        int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHPR2 performs the symmetric rank 2 operation
-     * A := alpha*x*y**H + alpha*y*x**H + A
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d5/d52/zhpr2_8f.html
-     *
-     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
-     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
-     *       'a' to packed matrix 'b'.
-     *           k = 0
-     *           for i in range(0, n):
-     *              for j in range(i, n):
-     *                  b[k++] = a[i, j]
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
-     * @param alpha The scalar alpha.
-     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
-     * @param incX The increment for the elements of vector x, must be larger than zero.
-     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
-     * @param incY The increment for the elements of vector y, must be larger than zero.
-     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     */
-    public void ZHPR2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
-        // same as SPR2
-        int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
-
-        boolean mUseIncSupp = isIncSupp();
-        long apID = Ap.getID(mRS);
-        long xID = X.getID(mRS);
-        long yID = Y.getID(mRS);
-        if (mUseIncSupp) {
-            apID = getDummyAlloc(Ap);
-            xID = getDummyAlloc(X);
-            yID = getDummyAlloc(Y);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, apID, incX, incY, 0, 0, mUseIncSupp);
-    }
-
-
-    /**
-     * Level 3 BLAS
-     */
-
-    static void validateL3(Element e, int TransA, int TransB, int Side, Allocation A, Allocation B, Allocation C) {
-        int aM = -1, aN = -1, bM = -1, bN = -1, cM = -1, cN = -1;
-        if ((A != null && !A.getType().getElement().isCompatible(e)) ||
-            (B != null && !B.getType().getElement().isCompatible(e)) ||
-            (C != null && !C.getType().getElement().isCompatible(e))) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        if (C == null) {
-            //since matrix C is used to store the result, it cannot be null.
-            throw new RSRuntimeException("Allocation C cannot be null");
-        }
-        cM = C.getType().getY();
-        cN = C.getType().getX();
-
-        if (Side == RIGHT) {
-            if ((A == null && B != null) || (A != null && B == null)) {
-                throw new RSRuntimeException("Provided Matrix A without Matrix B, or vice versa");
-            }
-            if (B != null) {
-                bM = A.getType().getY();
-                bN = A.getType().getX();
-            }
-            if (A != null) {
-                aM = B.getType().getY();
-                aN = B.getType().getX();
-            }
-        } else {
-            if (A != null) {
-                if (TransA == TRANSPOSE || TransA == CONJ_TRANSPOSE) {
-                    aN = A.getType().getY();
-                    aM = A.getType().getX();
-                } else {
-                    aM = A.getType().getY();
-                    aN = A.getType().getX();
-                }
-            }
-            if (B != null) {
-                if (TransB == TRANSPOSE || TransB == CONJ_TRANSPOSE) {
-                    bN = B.getType().getY();
-                    bM = B.getType().getX();
-                } else {
-                    bM = B.getType().getY();
-                    bN = B.getType().getX();
-                }
-            }
-        }
-        if (A != null && B != null && C != null) {
-            if (aN != bM || aM != cM || bN != cN) {
-                throw new RSRuntimeException("Called BLAS with invalid dimensions");
-            }
-        } else if (A != null && C != null) {
-            // A and C only, for SYRK
-            if (cM != cN) {
-                throw new RSRuntimeException("Matrix C is not symmetric");
-            }
-            if (aM != cM) {
-                throw new RSRuntimeException("Called BLAS with invalid dimensions");
-            }
-        } else if (A != null && B != null) {
-            // A and B only
-            if (aN != bM) {
-                throw new RSRuntimeException("Called BLAS with invalid dimensions");
-            }
-        }
-
-    }
-
-    /**
-     * SGEMM performs one of the matrix-matrix operations
-     * C := alpha*op(A)*op(B) + beta*C   where op(X) is one of op(X) = X  or  op(X) = X**T
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d4/de2/sgemm_8f.html
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param TransB The type of transpose applied to matrix B.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
-     */
-    public void SGEMM(@Transpose int TransA, @Transpose int TransB, float alpha, Allocation A,
-                      Allocation B, float beta, Allocation C) {
-        validateTranspose(TransA);
-        validateTranspose(TransB);
-        validateL3(Element.F32(mRS), TransA, TransB, 0, A, B, C);
-
-        int M = -1, N = -1, K = -1;
-        if (TransA != NO_TRANSPOSE) {
-            M = A.getType().getX();
-            K = A.getType().getY();
-        } else {
-            M = A.getType().getY();
-            K = A.getType().getX();
-        }
-        if (TransB != NO_TRANSPOSE) {
-            N = B.getType().getY();
-        } else {
-            N = B.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemm, TransA, TransB, 0, 0, 0, M, N, K,  alpha, aID, bID,
-                                        beta, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DGEMM performs one of the matrix-matrix operations
-     * C := alpha*op(A)*op(B) + beta*C   where op(X) is one of op(X) = X  or  op(X) = X**T
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d7/d2b/dgemm_8f.html
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param TransB The type of transpose applied to matrix B.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
-     */
-    public void DGEMM(@Transpose int TransA, @Transpose int TransB, double alpha, Allocation A,
-                      Allocation B, double beta, Allocation C) {
-        validateTranspose(TransA);
-        validateTranspose(TransB);
-        validateL3(Element.F64(mRS), TransA, TransB, 0, A, B, C);
-        int M = -1, N = -1, K = -1;
-        if (TransA != NO_TRANSPOSE) {
-            M = A.getType().getX();
-            K = A.getType().getY();
-        } else {
-            M = A.getType().getY();
-            K = A.getType().getX();
-        }
-        if (TransB != NO_TRANSPOSE) {
-            N = B.getType().getY();
-        } else {
-            N = B.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemm, TransA, TransB, 0, 0, 0, M, N, K,  alpha, aID, bID,
-                                        beta, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CGEMM performs one of the matrix-matrix operations
-     * C := alpha*op(A)*op(B) + beta*C   where op(X) is one of op(X) = X  or  op(X) = X**T  or  op(X) = X**H
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d6/d5b/cgemm_8f.html
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param TransB The type of transpose applied to matrix B.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
-     */
-    public void CGEMM(@Transpose int TransA, @Transpose int TransB, Float2 alpha, Allocation A,
-                      Allocation B, Float2 beta, Allocation C) {
-        validateTranspose(TransA);
-        validateTranspose(TransB);
-        validateL3(Element.F32_2(mRS), TransA, TransB, 0, A, B, C);
-        int M = -1, N = -1, K = -1;
-        if (TransA != NO_TRANSPOSE) {
-            M = A.getType().getX();
-            K = A.getType().getY();
-        } else {
-            M = A.getType().getY();
-            K = A.getType().getX();
-        }
-        if (TransB != NO_TRANSPOSE) {
-            N = B.getType().getY();
-        } else {
-            N = B.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemm, TransA, TransB, 0, 0, 0, M, N, K,  alpha.x, alpha.y, aID, bID,
-                                         beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZGEMM performs one of the matrix-matrix operations
-     * C := alpha*op(A)*op(B) + beta*C   where op(X) is one of op(X) = X  or  op(X) = X**T  or  op(X) = X**H
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d7/d76/zgemm_8f.html
-     *
-     * @param TransA The type of transpose applied to matrix A.
-     * @param TransB The type of transpose applied to matrix B.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2
-     */
-    public void ZGEMM(@Transpose int TransA, @Transpose int TransB, Double2 alpha, Allocation A,
-                      Allocation B, Double2 beta, Allocation C) {
-        validateTranspose(TransA);
-        validateTranspose(TransB);
-        validateL3(Element.F64_2(mRS), TransA, TransB, 0, A, B, C);
-        int M = -1, N = -1, K = -1;
-        if (TransA != NO_TRANSPOSE) {
-            M = A.getType().getX();
-            K = A.getType().getY();
-        } else {
-            M = A.getType().getY();
-            K = A.getType().getX();
-        }
-        if (TransB != NO_TRANSPOSE) {
-            N = B.getType().getY();
-        } else {
-            N = B.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemm, TransA, TransB, 0, 0, 0, M, N, K,  alpha.x, alpha.y, aID, bID,
-                                   beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SSYMM performs one of the matrix-matrix operations
-     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d7/d42/ssymm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
-     */
-    public void SSYMM(@Side int Side, @Uplo int Uplo, float alpha, Allocation A,
-                      Allocation B, float beta, Allocation C) {
-        validateSide(Side);
-        validateUplo(Uplo);
-        //For SYMM, Matrix A should be symmetric
-        if (A.getType().getX() != A.getType().getY()) {
-            throw new RSRuntimeException("Matrix A is not symmetric");
-        }
-        validateL3(Element.F32(mRS), 0, 0, Side, A, B, C);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, aID, bID,
-                                        beta, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSYMM performs one of the matrix-matrix operations
-     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d8/db0/dsymm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
-     */
-    public void DSYMM(@Side int Side, @Uplo int Uplo, double alpha, Allocation A,
-                      Allocation B, double beta, Allocation C) {
-        validateSide(Side);
-        validateUplo(Uplo);
-        if (A.getType().getX() != A.getType().getY()) {
-            throw new RSRuntimeException("Matrix A is not symmetric");
-        }
-        validateL3(Element.F64(mRS), 0, 0, Side, A, B, C);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, aID, bID,
-                                        beta, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CSYMM performs one of the matrix-matrix operations
-     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/db/d59/csymm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
-     */
-    public void CSYMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A,
-                      Allocation B, Float2 beta, Allocation C) {
-        validateSide(Side);
-        validateUplo(Uplo);
-        if (A.getType().getX() != A.getType().getY()) {
-            throw new RSRuntimeException("Matrix A is not symmetric");
-        }
-        validateL3(Element.F32_2(mRS), 0, 0, Side, A, B, C);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, aID, bID,
-                                         beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZSYMM performs one of the matrix-matrix operations
-     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/df/d51/zsymm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
-     */
-    public void ZSYMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A,
-                      Allocation B, Double2 beta, Allocation C) {
-        validateSide(Side);
-        validateUplo(Uplo);
-        if (A.getType().getX() != A.getType().getY()) {
-            throw new RSRuntimeException("Matrix A is not symmetric");
-        }
-        validateL3(Element.F64_2(mRS), 0, 0, Side, A, B, C);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, aID, bID,
-                                   beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * SSYRK performs one of the symmetric rank k operations
-     * C := alpha*A*A**T + beta*C   or   C := alpha*A**T*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d0/d40/ssyrk_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
-     */
-    public void SSYRK(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, float beta, Allocation C) {
-        validateTranspose(Trans);
-        validateUplo(Uplo);
-        validateL3(Element.F32(mRS), Trans, 0, 0, A, null, C);
-        int K = -1;
-        if (Trans != NO_TRANSPOSE) {
-            K = A.getType().getY();
-        } else {
-            K = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, 0, beta, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSYRK performs one of the symmetric rank k operations
-     * C := alpha*A*A**T + beta*C   or   C := alpha*A**T*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/dc/d05/dsyrk_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
-     */
-    public void DSYRK(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, double beta, Allocation C) {
-        validateTranspose(Trans);
-        validateUplo(Uplo);
-        validateL3(Element.F64(mRS), Trans, 0, 0, A, null, C);
-        int K = -1;
-        if (Trans != NO_TRANSPOSE) {
-            K = A.getType().getY();
-        } else {
-            K = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, 0, beta, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CSYRK performs one of the symmetric rank k operations
-     * C := alpha*A*A**T + beta*C   or   C := alpha*A**T*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d3/d6a/csyrk_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
-     */
-    public void CSYRK(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Float2 beta, Allocation C) {
-        validateTranspose(Trans);
-        validateUplo(Uplo);
-        validateL3(Element.F32_2(mRS), Trans, 0, 0, A, null, C);
-        int K = -1;
-        if (Trans != NO_TRANSPOSE) {
-            K = A.getType().getY();
-        } else {
-            K = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, 0, beta.x, beta.y,
-                                         C.getID(mRS), 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZSYRK performs one of the symmetric rank k operations
-     * C := alpha*A*A**T + beta*C   or   C := alpha*A**T*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/de/d54/zsyrk_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
-     */
-    public void ZSYRK(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Double2 beta, Allocation C) {
-        validateTranspose(Trans);
-        validateUplo(Uplo);
-        validateL3(Element.F64_2(mRS), Trans, 0, 0, A, null, C);
-        int K = -1;
-        if (Trans != NO_TRANSPOSE) {
-            K = A.getType().getY();
-        } else {
-            K = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, 0, beta.x, beta.y,
-                                   C.getID(mRS), 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    static void validateSYR2K(Element e, @Transpose int Trans, Allocation A, Allocation B, Allocation C) {
-        validateTranspose(Trans);
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e) ||
-            !C.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        int Cdim = -1;
-        // A is n x k if no transpose, k x n if transpose
-        // C is n x n
-        if (Trans == TRANSPOSE) {
-            // check columns versus C
-            Cdim = A.getType().getX();
-        } else {
-            // check rows versus C
-            Cdim = A.getType().getY();
-        }
-        if (C.getType().getX() != Cdim || C.getType().getY() != Cdim) {
-            throw new RSRuntimeException("Invalid symmetric matrix in SYR2K");
-        }
-        // A dims == B dims
-        if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
-            throw new RSRuntimeException("Invalid A and B in SYR2K");
-        }
-    }
-
-    /**
-     * SSYR2K performs one of the symmetric rank 2k operations
-     * C := alpha*A*B**T + alpha*B*A**T + beta*C   or   C := alpha*A**T*B + alpha*B**T*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/df/d3d/ssyr2k_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
-     */
-    public void SSYR2K(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, Allocation B, float beta, Allocation C) {
-        validateUplo(Uplo);
-        validateSYR2K(Element.F32(mRS), Trans, A, B, C);
-        int K = -1;
-        if (Trans != NO_TRANSPOSE) {
-            K = A.getType().getY();
-        } else {
-            K = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, bID, beta, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DSYR2K performs one of the symmetric rank 2k operations
-     * C := alpha*A*B**T + alpha*B*A**T + beta*C   or   C := alpha*A**T*B + alpha*B**T*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d1/dec/dsyr2k_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
-     */
-    public void DSYR2K(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, Allocation B, double beta, Allocation C) {
-        validateUplo(Uplo);
-        validateSYR2K(Element.F64(mRS), Trans, A, B, C);
-        int K = -1;
-        if (Trans != NO_TRANSPOSE) {
-            K = A.getType().getY();
-        } else {
-            K = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, bID, beta, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CSYR2K performs one of the symmetric rank 2k operations
-     * C := alpha*A*B**T + alpha*B*A**T + beta*C   or   C := alpha*A**T*B + alpha*B**T*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/de/d7e/csyr2k_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
-     */
-    public void CSYR2K(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Allocation B, Float2 beta, Allocation C) {
-        validateUplo(Uplo);
-        validateSYR2K(Element.F32_2(mRS), Trans, A, B, C);
-        int K = -1;
-        if (Trans != NO_TRANSPOSE) {
-            K = A.getType().getY();
-        } else {
-            K = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZSYR2K performs one of the symmetric rank 2k operations
-     * C := alpha*A*B**T + alpha*B*A**T + beta*C   or   C := alpha*A**T*B + alpha*B**T*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/df/d20/zsyr2k_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
-     */
-    public void ZSYR2K(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Allocation B, Double2 beta, Allocation C) {
-        validateUplo(Uplo);
-        validateSYR2K(Element.F64_2(mRS), Trans, A, B, C);
-        int K = -1;
-        if (Trans != NO_TRANSPOSE) {
-            K = A.getType().getY();
-        } else {
-            K = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    static void validateTRMM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) {
-        validateSide(Side);
-        validateTranspose(TransA);
-        int aM = -1, aN = -1, bM = -1, bN = -1;
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-
-        aM = A.getType().getY();
-        aN = A.getType().getX();
-        if (aM != aN) {
-            throw new RSRuntimeException("Called TRMM with a non-symmetric matrix A");
-        }
-
-        bM = B.getType().getY();
-        bN = B.getType().getX();
-        if (Side == LEFT) {
-            if (aN != bM) {
-                throw new RSRuntimeException("Called TRMM with invalid matrices");
-            }
-        } else {
-            if (bN != aM) {
-                throw new RSRuntimeException("Called TRMM with invalid matrices");
-            }
-        }
-    }
-
-    /**
-     * STRMM performs one of the matrix-matrix operations
-     * B := alpha*op(A)*B   or   B := alpha*B*op(A)
-     * op(A) is one of  op(A) = A  or  op(A) = A**T
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/df/d01/strmm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether matrix A is upper or lower triangular.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
-     */
-    public void STRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, float alpha, Allocation A, Allocation B) {
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        validateTRMM(Element.F32(mRS), Side, TransA, A, B);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
-                                        alpha, aID, bID, 0.f, 0, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DTRMM performs one of the matrix-matrix operations
-     * B := alpha*op(A)*B   or   B := alpha*B*op(A)
-     * op(A) is one of  op(A) = A  or  op(A) = A**T
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/dd/d19/dtrmm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether matrix A is upper or lower triangular.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
-     */
-    public void DTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, double alpha, Allocation A, Allocation B) {
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        validateTRMM(Element.F64(mRS), Side, TransA, A, B);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
-                                        alpha, aID, bID, 0, 0, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CTRMM performs one of the matrix-matrix operations
-     * B := alpha*op(A)*B   or   B := alpha*B*op(A)
-     * op(A) is one of  op(A) = A  or  op(A) = A**T  or  op(A) = A**H
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d4/d9b/ctrmm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether matrix A is upper or lower triangular.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
-     */
-    public void CTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Float2 alpha, Allocation A, Allocation B) {
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        validateTRMM(Element.F32_2(mRS), Side, TransA, A, B);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
-                                         alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZTRMM performs one of the matrix-matrix operations
-     * B := alpha*op(A)*B   or   B := alpha*B*op(A)
-     * op(A) is one of  op(A) = A  or  op(A) = A**T  or  op(A) = A**H
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d8/de1/ztrmm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether matrix A is upper or lower triangular.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
-     */
-    public void ZTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Double2 alpha, Allocation A, Allocation B) {
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        validateTRMM(Element.F64_2(mRS), Side, TransA, A, B);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
-                                   alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    static void validateTRSM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) {
-        int adim = -1, bM = -1, bN = -1;
-        validateSide(Side);
-        validateTranspose(TransA);
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        adim = A.getType().getX();
-        if (adim != A.getType().getY()) {
-            // this may be unnecessary, the restriction could potentially be relaxed
-            // A needs to contain at least that symmetric matrix but could theoretically be larger
-            // for now we assume adapters are sufficient, will reevaluate in the future
-            throw new RSRuntimeException("Called TRSM with a non-symmetric matrix A");
-        }
-        bM = B.getType().getY();
-        bN = B.getType().getX();
-        if (Side == LEFT) {
-            // A is M*M
-            if (adim != bM) {
-                throw new RSRuntimeException("Called TRSM with invalid matrix dimensions");
-            }
-        } else {
-            // A is N*N
-            if (adim != bN) {
-                throw new RSRuntimeException("Called TRSM with invalid matrix dimensions");
-            }
-        }
-    }
-
-    /**
-     * STRSM solves one of the matrix equations
-     * op(A)*X := alpha*B   or   X*op(A) := alpha*B
-     * op(A) is one of  op(A) = A  or  op(A) = A**T
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d2/d8b/strsm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether matrix A is upper or lower triangular.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
-     */
-    public void STRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, float alpha, Allocation A, Allocation B) {
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        validateTRSM(Element.F32(mRS), Side, TransA, A, B);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-        }
-        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
-                                        alpha, aID, bID, 0, 0, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * DTRSM solves one of the matrix equations
-     * op(A)*X := alpha*B   or   X*op(A) := alpha*B
-     * op(A) is one of  op(A) = A  or  op(A) = A**T
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/de/da7/dtrsm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether matrix A is upper or lower triangular.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
-     */
-    public void DTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, double alpha, Allocation A, Allocation B) {
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        validateTRSM(Element.F64(mRS), Side, TransA, A, B);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-        }
-        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
-                                        alpha, aID, bID, 0, 0, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * CTRSM solves one of the matrix equations
-     * op(A)*X := alpha*B   or   X*op(A) := alpha*B
-     * op(A) is one of  op(A) = A  or  op(A) = A**T  or  op(A) = A**H
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/de/d30/ctrsm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether matrix A is upper or lower triangular.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
-     */
-    public void CTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Float2 alpha, Allocation A, Allocation B) {
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        validateTRSM(Element.F32_2(mRS), Side, TransA, A, B);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
-                                         alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZTRSM solves one of the matrix equations
-     * op(A)*X := alpha*B   or   X*op(A) := alpha*B
-     * op(A) is one of  op(A) = A  or  op(A) = A**T  or  op(A) = A**H
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d1/d39/ztrsm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether matrix A is upper or lower triangular.
-     * @param TransA The type of transpose applied to matrix A.
-     * @param Diag Specifies whether or not A is unit triangular.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
-     */
-    public void ZTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Double2 alpha, Allocation A, Allocation B) {
-        validateUplo(Uplo);
-        validateDiag(Diag);
-        validateTRSM(Element.F64_2(mRS), Side, TransA, A, B);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
-                                   alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    static void validateHEMM(Element e, @Side int Side, Allocation A, Allocation B, Allocation C) {
-        validateSide(Side);
-
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e) ||
-            !C.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-
-        // A must be square; can potentially be relaxed similar to TRSM
-        int adim = A.getType().getX();
-        if (adim != A.getType().getY()) {
-            throw new RSRuntimeException("Called HEMM with non-square A");
-        }
-        if ((Side == LEFT && adim != B.getType().getY()) ||
-            (Side == RIGHT && adim != B.getType().getX())) {
-            throw new RSRuntimeException("Called HEMM with invalid B");
-        }
-        if (B.getType().getX() != C.getType().getX() ||
-            B.getType().getY() != C.getType().getY()) {
-            throw new RSRuntimeException("Called HEMM with mismatched B and C");
-        }
-    }
-
-    /**
-     * CHEMM performs one of the matrix-matrix operations
-     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d3/d66/chemm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
-     */
-    public void CHEMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A, Allocation B, Float2 beta, Allocation C) {
-        validateUplo(Uplo);
-        validateHEMM(Element.F32_2(mRS), Side, A, B, C);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0,
-                                         alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHEMM performs one of the matrix-matrix operations
-     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d6/d3e/zhemm_8f.html
-     *
-     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
-     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
-     */
-    public void ZHEMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A, Allocation B, Double2 beta, Allocation C) {
-        validateUplo(Uplo);
-        validateHEMM(Element.F64_2(mRS), Side, A, B, C);
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0,
-                                   alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    static void validateHERK(Element e, @Transpose int Trans, Allocation A, Allocation C) {
-        if (!A.getType().getElement().isCompatible(e) ||
-            !C.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        validateConjTranspose(Trans);
-        int cdim = C.getType().getX();
-        if (cdim != C.getType().getY()) {
-            throw new RSRuntimeException("Called HERK with non-square C");
-        }
-        if (Trans == NO_TRANSPOSE) {
-            if (cdim != A.getType().getY()) {
-                throw new RSRuntimeException("Called HERK with invalid A");
-            }
-        } else {
-            if (cdim != A.getType().getX()) {
-                throw new RSRuntimeException("Called HERK with invalid A");
-            }
-        }
-    }
-
-    /**
-     * CHERK performs one of the hermitian rank k operations
-     * C := alpha*A*A**H + beta*C   or   C := alpha*A**H*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d8/d52/cherk_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
-     */
-    public void CHERK(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, float beta, Allocation C) {
-        validateUplo(Uplo);
-        validateHERK(Element.F32_2(mRS), Trans, A, C);
-        int k = 0;
-        if (Trans == CONJ_TRANSPOSE) {
-            k = A.getType().getY();
-        } else {
-            k = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cherk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k,
-                                         alpha, 0, aID, 0, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHERK performs one of the hermitian rank k operations
-     * C := alpha*A*A**H + beta*C   or   C := alpha*A**H*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d1/db1/zherk_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
-     */
-    public void ZHERK(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, double beta, Allocation C) {
-        validateUplo(Uplo);
-        validateHERK(Element.F64_2(mRS), Trans, A, C);
-        int k = 0;
-        if (Trans == CONJ_TRANSPOSE) {
-            k = A.getType().getY();
-        } else {
-            k = A.getType().getX();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zherk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k,
-                                   alpha, 0, aID, 0, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    static void validateHER2K(Element e, @Transpose int Trans, Allocation A, Allocation B, Allocation C) {
-        if (!A.getType().getElement().isCompatible(e) ||
-            !B.getType().getElement().isCompatible(e) ||
-            !C.getType().getElement().isCompatible(e)) {
-            throw new RSRuntimeException("Called BLAS with wrong Element type");
-        }
-        validateConjTranspose(Trans);
-        int cdim = C.getType().getX();
-        if (cdim != C.getType().getY()) {
-            throw new RSRuntimeException("Called HER2K with non-square C");
-        }
-        if (Trans == NO_TRANSPOSE) {
-            if (A.getType().getY() != cdim) {
-                throw new RSRuntimeException("Called HER2K with invalid matrices");
-            }
-        } else {
-            if (A.getType().getX() != cdim) {
-                throw new RSRuntimeException("Called HER2K with invalid matrices");
-            }
-        }
-        if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
-            throw new RSRuntimeException("Called HER2K with invalid A and B matrices");
-        }
-    }
-
-    /**
-     * CHER2K performs one of the hermitian rank 2k operations
-     * C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C   or   C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d1/d82/cher2k_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
-     */
-    public void CHER2K(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Allocation B, float beta, Allocation C) {
-        validateUplo(Uplo);
-        validateHER2K(Element.F32_2(mRS), Trans, A, B, C);
-        int k = 0;
-        if (Trans == NO_TRANSPOSE) {
-            k = A.getType().getX();
-        } else {
-            k = A.getType().getY();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, alpha.x, alpha.y,
-                                         A.getID(mRS), bID, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-    /**
-     * ZHER2K performs one of the hermitian rank 2k operations
-     * C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C   or   C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C
-     *
-     * Details: http://www.netlib.org/lapack/explore-html/d7/dfa/zher2k_8f.html
-     *
-     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
-     * @param Trans The type of transpose applied to the operation.
-     * @param alpha The scalar alpha.
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
-     * @param beta The scalar beta.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
-     */
-    public void ZHER2K(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Allocation B, double beta, Allocation C) {
-        validateUplo(Uplo);
-        validateHER2K(Element.F64_2(mRS), Trans, A, B, C);
-        int k = 0;
-        if (Trans == NO_TRANSPOSE) {
-            k = A.getType().getX();
-        } else {
-            k = A.getType().getY();
-        }
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, alpha.x, alpha.y,
-                                   A.getID(mRS), bID, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
-    }
-
-
-    /**
-     * 8-bit GEMM-like operation for neural networks: C = A * Transpose(B)
-     * Calculations are done in 1.10.21 fixed-point format for the final output,
-     * just before there's a shift down to drop the fractional parts. The output
-     * values are gated to 0 to 255 to fit in a byte, but the 10-bit format
-     * gives some headroom to avoid wrapping around on small overflows.
-     *
-     * @param A The input allocation contains matrix A, supported elements type {@link Element#U8}.
-     * @param a_offset The offset for all values in matrix A, e.g A[i,j] = A[i,j] - a_offset. Value should be from 0 to 255.
-     * @param B The input allocation contains matrix B, supported elements type {@link Element#U8}.
-     * @param b_offset The offset for all values in matrix B, e.g B[i,j] = B[i,j] - b_offset. Value should be from 0 to 255.
-     * @param C The input allocation contains matrix C, supported elements type {@link Element#U8}.
-     * @param c_offset The offset for all values in matrix C.
-     * @param c_mult The multiplier for all values in matrix C, e.g C[i,j] = (C[i,j] + c_offset) * c_mult.
-     **/
-    public void BNNM(Allocation A, int a_offset, Allocation B, int b_offset, Allocation C, int c_offset, int c_mult) {
-        validateL3(Element.U8(mRS), NO_TRANSPOSE, TRANSPOSE, 0, A, B, C);
-
-        if (a_offset < 0 || a_offset > 255) {
-            throw new RSRuntimeException("Invalid a_offset passed to BNNM");
-        }
-        if (b_offset < 0 || b_offset > 255) {
-            throw new RSRuntimeException("Invalid b_offset passed to BNNM");
-        }
-        int M = -1, N = -1, K = -1;
-        M = A.getType().getY();
-        N = B.getType().getY();
-        K = A.getType().getX();
-
-        boolean mUseIncSupp = isIncSupp();
-        long aID = A.getID(mRS);
-        long bID = B.getID(mRS);
-        long cID = C.getID(mRS);
-        if (mUseIncSupp) {
-            aID = getDummyAlloc(A);
-            bID = getDummyAlloc(B);
-            cID = getDummyAlloc(C);
-        }
-        mRS.nScriptIntrinsicBLAS_BNNM(getID(mRS), M, N, K, aID, a_offset, bID, b_offset, cID, c_offset, c_mult, mUseIncSupp);
-
-    }
-
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicBlend.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicBlend.java
deleted file mode 100644
index eef581e..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicBlend.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-
-/**
- * Intrinsic kernels for blending two
- * {@link android.support.v8.renderscript.Allocation} objects.
- **/
-public class ScriptIntrinsicBlend extends ScriptIntrinsic {
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 19;
-
-    ScriptIntrinsicBlend(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Supported elements types are {@link Element#U8_4}
-     *
-     * @param rs The RenderScript context
-     * @param e Element type for inputs and outputs
-     *
-     * @return ScriptIntrinsicBlend
-     */
-    public static ScriptIntrinsicBlend create(RenderScript rs, Element e) {
-        // 7 comes from RS_SCRIPT_INTRINSIC_ID_BLEND in rsDefines.h
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(7, e.getID(rs), mUseIncSupp);
-
-        ScriptIntrinsicBlend si = new ScriptIntrinsicBlend(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        return si;
-
-    }
-
-    private void blend(int id, Allocation ain, Allocation aout) {
-        if (!ain.getElement().isCompatible(Element.U8_4(mRS))) {
-            throw new RSIllegalArgumentException("Input is not of expected format.");
-        }
-        if (!aout.getElement().isCompatible(Element.U8_4(mRS))) {
-            throw new RSIllegalArgumentException("Output is not of expected format.");
-        }
-        forEach(id, ain, aout, null);
-    }
-
-    /**
-     * Sets dst = {0, 0, 0, 0}
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachClear(Allocation ain, Allocation aout) {
-        blend(0, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the Clear kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDClear() {
-        return createKernelID(0, 3, null, null);
-    }
-
-
-    /**
-     * Sets dst = src
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachSrc(Allocation ain, Allocation aout) {
-        blend(1, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the Src kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDSrc() {
-        return createKernelID(1, 3, null, null);
-    }
-
-    /**
-     * Sets dst = dst
-     *
-     * This is a NOP.
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachDst(Allocation ain, Allocation aout) {
-        // NOP
-    }
-
-    /**
-     * Get a KernelID for the Dst kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDDst() {
-        return createKernelID(2, 3, null, null);
-    }
-
-    /**
-     * Sets dst = src + dst * (1.0 - src.a)
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachSrcOver(Allocation ain, Allocation aout) {
-        blend(3, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the SrcOver kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDSrcOver() {
-        return createKernelID(3, 3, null, null);
-    }
-
-    /**
-     * Sets dst = dst + src * (1.0 - dst.a)
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachDstOver(Allocation ain, Allocation aout) {
-        blend(4, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the DstOver kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDDstOver() {
-        return createKernelID(4, 3, null, null);
-    }
-
-    /**
-     * Sets dst = src * dst.a
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachSrcIn(Allocation ain, Allocation aout) {
-        blend(5, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the SrcIn kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDSrcIn() {
-        return createKernelID(5, 3, null, null);
-    }
-
-    /**
-     * Sets dst = dst * src.a
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachDstIn(Allocation ain, Allocation aout) {
-        blend(6, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the DstIn kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDDstIn() {
-        return createKernelID(6, 3, null, null);
-    }
-
-    /**
-     * Sets dst = src * (1.0 - dst.a)
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachSrcOut(Allocation ain, Allocation aout) {
-        blend(7, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the SrcOut kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDSrcOut() {
-        return createKernelID(7, 3, null, null);
-    }
-
-    /**
-     * Sets dst = dst * (1.0 - src.a)
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachDstOut(Allocation ain, Allocation aout) {
-        blend(8, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the DstOut kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDDstOut() {
-        return createKernelID(8, 3, null, null);
-    }
-
-    /**
-     * dst.rgb = src.rgb * dst.a + (1.0 - src.a) * dst.rgb
-     * dst.a = dst.a
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachSrcAtop(Allocation ain, Allocation aout) {
-        blend(9, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the SrcAtop kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDSrcAtop() {
-        return createKernelID(9, 3, null, null);
-    }
-
-    /**
-     * dst = dst.rgb * src.a + (1.0 - dst.a) * src.rgb
-     * dst.a = src.a
-     * Note: Before API 23, the alpha channel was not correctly set.
-     *       Please use with caution when targeting older APIs.
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachDstAtop(Allocation ain, Allocation aout) {
-        blend(10, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the DstAtop kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDDstAtop() {
-        return createKernelID(10, 3, null, null);
-    }
-
-    /**
-     * Sets dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a}
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachXor(Allocation ain, Allocation aout) {
-        blend(11, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the Xor kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDXor() {
-        return createKernelID(11, 3, null, null);
-    }
-
-    ////////
-/*
-    public void forEachNormal(Allocation ain, Allocation aout) {
-        blend(12, ain, aout);
-    }
-
-    public void forEachAverage(Allocation ain, Allocation aout) {
-        blend(13, ain, aout);
-    }
-*/
-    /**
-     * Sets dst = src * dst
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachMultiply(Allocation ain, Allocation aout) {
-        blend(14, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the Multiply kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDMultiply() {
-        return createKernelID(14, 3, null, null);
-    }
-
-/*
-    public void forEachScreen(Allocation ain, Allocation aout) {
-        blend(15, ain, aout);
-    }
-
-    public void forEachDarken(Allocation ain, Allocation aout) {
-        blend(16, ain, aout);
-    }
-
-    public void forEachLighten(Allocation ain, Allocation aout) {
-        blend(17, ain, aout);
-    }
-
-    public void forEachOverlay(Allocation ain, Allocation aout) {
-        blend(18, ain, aout);
-    }
-
-    public void forEachHardlight(Allocation ain, Allocation aout) {
-        blend(19, ain, aout);
-    }
-
-    public void forEachSoftlight(Allocation ain, Allocation aout) {
-        blend(20, ain, aout);
-    }
-
-    public void forEachDifference(Allocation ain, Allocation aout) {
-        blend(21, ain, aout);
-    }
-
-    public void forEachNegation(Allocation ain, Allocation aout) {
-        blend(22, ain, aout);
-    }
-
-    public void forEachExclusion(Allocation ain, Allocation aout) {
-        blend(23, ain, aout);
-    }
-
-    public void forEachColorDodge(Allocation ain, Allocation aout) {
-        blend(24, ain, aout);
-    }
-
-    public void forEachInverseColorDodge(Allocation ain, Allocation aout) {
-        blend(25, ain, aout);
-    }
-
-    public void forEachSoftDodge(Allocation ain, Allocation aout) {
-        blend(26, ain, aout);
-    }
-
-    public void forEachColorBurn(Allocation ain, Allocation aout) {
-        blend(27, ain, aout);
-    }
-
-    public void forEachInverseColorBurn(Allocation ain, Allocation aout) {
-        blend(28, ain, aout);
-    }
-
-    public void forEachSoftBurn(Allocation ain, Allocation aout) {
-        blend(29, ain, aout);
-    }
-
-    public void forEachReflect(Allocation ain, Allocation aout) {
-        blend(30, ain, aout);
-    }
-
-    public void forEachGlow(Allocation ain, Allocation aout) {
-        blend(31, ain, aout);
-    }
-
-    public void forEachFreeze(Allocation ain, Allocation aout) {
-        blend(32, ain, aout);
-    }
-
-    public void forEachHeat(Allocation ain, Allocation aout) {
-        blend(33, ain, aout);
-    }
-*/
-    /**
-     * Sets dst = min(src + dst, 1.0)
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachAdd(Allocation ain, Allocation aout) {
-        blend(34, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the Add kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDAdd() {
-        return createKernelID(34, 3, null, null);
-    }
-
-    /**
-     * Sets dst = max(dst - src, 0.0)
-     *
-     * @param ain The source buffer
-     * @param aout The destination buffer
-     */
-    public void forEachSubtract(Allocation ain, Allocation aout) {
-        blend(35, ain, aout);
-    }
-
-    /**
-     * Get a KernelID for the Subtract kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelIDSubtract() {
-        return createKernelID(35, 3, null, null);
-    }
-
-/*
-    public void forEachStamp(Allocation ain, Allocation aout) {
-        blend(36, ain, aout);
-    }
-
-    public void forEachRed(Allocation ain, Allocation aout) {
-        blend(37, ain, aout);
-    }
-
-    public void forEachGreen(Allocation ain, Allocation aout) {
-        blend(38, ain, aout);
-    }
-
-    public void forEachBlue(Allocation ain, Allocation aout) {
-        blend(39, ain, aout);
-    }
-
-    public void forEachHue(Allocation ain, Allocation aout) {
-        blend(40, ain, aout);
-    }
-
-    public void forEachSaturation(Allocation ain, Allocation aout) {
-        blend(41, ain, aout);
-    }
-
-    public void forEachColor(Allocation ain, Allocation aout) {
-        blend(42, ain, aout);
-    }
-
-    public void forEachLuminosity(Allocation ain, Allocation aout) {
-        blend(43, ain, aout);
-    }
-*/
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicBlur.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicBlur.java
deleted file mode 100644
index e1a134a..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicBlur.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-/**
- * Intrinsic Gausian blur filter. Applies a gaussian blur of the
- * specified radius to all elements of an allocation.
- *
- *
- **/
-public class ScriptIntrinsicBlur extends ScriptIntrinsic {
-    private final float[] mValues = new float[9];
-    private Allocation mInput;
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 19;
-
-    protected ScriptIntrinsicBlur(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Create an intrinsic for applying a blur to an allocation. The
-     * default radius is 5.0.
-     *
-     * Supported elements types are {@link Element#U8},
-     * {@link Element#U8_4}.
-     *
-     * @param rs The RenderScript context
-     * @param e Element type for inputs and outputs
-     *
-     * @return ScriptIntrinsicBlur
-     */
-    public static ScriptIntrinsicBlur create(RenderScript rs, Element e) {
-        if ((!e.isCompatible(Element.U8_4(rs))) && (!e.isCompatible(Element.U8(rs)))) {
-            throw new RSIllegalArgumentException("Unsupported element type.");
-        }
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(5, e.getID(rs), mUseIncSupp);
-
-        ScriptIntrinsicBlur si = new ScriptIntrinsicBlur(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        si.setRadius(5.f);
-
-        return si;
-    }
-
-    /**
-     * Set the input of the blur.
-     * Must match the element type supplied during create.
-     *
-     * @param ain The input allocation
-     */
-    public void setInput(Allocation ain) {
-        mInput = ain;
-        setVar(1, ain);
-    }
-
-    /**
-     * Set the radius of the Blur.
-     *
-     * Supported range 0 < radius <= 25
-     *
-     * @param radius The radius of the blur
-     */
-    public void setRadius(float radius) {
-        if (radius <= 0 || radius > 25) {
-            throw new RSIllegalArgumentException("Radius out of range (0 < r <= 25).");
-        }
-        setVar(0, radius);
-    }
-
-    /**
-     * Apply the filter to the input and save to the specified
-     * allocation.
-     *
-     * @param aout Output allocation. Must match creation element
-     *             type.
-     */
-    public void forEach(Allocation aout) {
-        forEach(0, (Allocation) null, aout, null);
-    }
-
-    /**
-     * Get a KernelID for this intrinsic kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelID() {
-        return createKernelID(0, 2, null, null);
-    }
-
-    /**
-     * Get a FieldID for the input field of this intrinsic.
-     *
-     * @return Script.FieldID The FieldID object.
-     */
-    public Script.FieldID getFieldID_Input() {
-        return createFieldID(1, null);
-    }
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicColorMatrix.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicColorMatrix.java
deleted file mode 100644
index f03526e..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicColorMatrix.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.Log;
-
-/**
- * Intrinsic for applying a color matrix to allocations.
- *
- * This has the same effect as loading each element and
- * converting it to a {@link Element#F32_4}, multiplying the
- * result by the 4x4 color matrix as performed by
- * rsMatrixMultiply() and writing it to the output after
- * conversion back to {@link Element#U8_4}.
- **/
-public class ScriptIntrinsicColorMatrix extends ScriptIntrinsic {
-    private final Matrix4f mMatrix = new Matrix4f();
-    private final Float4 mAdd = new Float4();
-    private Allocation mInput;
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 19;
-
-    protected ScriptIntrinsicColorMatrix(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Create an intrinsic for applying a color matrix to an
-     * allocation.
-     *
-     * Supported elements types are {@link Element#U8_4}
-     *
-     * @param rs The RenderScript context
-     * @param e Element type for intputs and outputs
-     *
-     * @return ScriptIntrinsicColorMatrix
-     */
-    public static ScriptIntrinsicColorMatrix create(RenderScript rs, Element e) {
-        if (!e.isCompatible(Element.U8_4(rs))) {
-            throw new RSIllegalArgumentException("Unsupported element type.");
-        }
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(2, e.getID(rs), mUseIncSupp);
-
-        ScriptIntrinsicColorMatrix si = new ScriptIntrinsicColorMatrix(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        return si;
-
-    }
-
-    private void setMatrix() {
-        FieldPacker fp = new FieldPacker(16*4);
-        fp.addMatrix(mMatrix);
-        setVar(0, fp);
-    }
-
-    /**
-     * Set the color matrix which will be applied to each cell of
-     * the image.
-     *
-     * @param m The 4x4 matrix to set.
-     */
-    public void setColorMatrix(Matrix4f m) {
-        mMatrix.load(m);
-        setMatrix();
-    }
-
-    /**
-     * Set the color matrix which will be applied to each cell of the image.
-     * This will set the alpha channel to be a copy.
-     *
-     * @param m The 3x3 matrix to set.
-     */
-    public void setColorMatrix(Matrix3f m) {
-        mMatrix.load(m);
-        setMatrix();
-    }
-
-    /**
-     * Set the value to be added after the color matrix has been
-     * applied. The default value is {0, 0, 0, 0}
-     *
-     * @param f The float4 value to be added.
-     */
-    public void setAdd(Float4 f) {
-        mAdd.x = f.x;
-        mAdd.y = f.y;
-        mAdd.z = f.z;
-        mAdd.w = f.w;
-
-        FieldPacker fp = new FieldPacker(4*4);
-        fp.addF32(f.x);
-        fp.addF32(f.y);
-        fp.addF32(f.z);
-        fp.addF32(f.w);
-        setVar(1, fp);
-    }
-
-    /**
-     * Set the value to be added after the color matrix has been
-     * applied. The default value is {0, 0, 0, 0}
-     *
-     * @param r The red add value.
-     * @param g The green add value.
-     * @param b The blue add value.
-     * @param a The alpha add value.
-     */
-    public void setAdd(float r, float g, float b, float a) {
-        mAdd.x = r;
-        mAdd.y = g;
-        mAdd.z = b;
-        mAdd.w = a;
-
-        FieldPacker fp = new FieldPacker(4*4);
-        fp.addF32(mAdd.x);
-        fp.addF32(mAdd.y);
-        fp.addF32(mAdd.z);
-        fp.addF32(mAdd.w);
-        setVar(1, fp);
-    }
-
-    /**
-     * Set a color matrix to convert from RGB to luminance. The alpha channel
-     * will be a copy.
-     *
-     */
-    public void setGreyscale() {
-        mMatrix.loadIdentity();
-        mMatrix.set(0, 0, 0.299f);
-        mMatrix.set(1, 0, 0.587f);
-        mMatrix.set(2, 0, 0.114f);
-        mMatrix.set(0, 1, 0.299f);
-        mMatrix.set(1, 1, 0.587f);
-        mMatrix.set(2, 1, 0.114f);
-        mMatrix.set(0, 2, 0.299f);
-        mMatrix.set(1, 2, 0.587f);
-        mMatrix.set(2, 2, 0.114f);
-        setMatrix();
-    }
-
-    /**
-     * Set the matrix to convert from YUV to RGB with a direct copy of the 4th
-     * channel.
-     *
-     */
-    public void setYUVtoRGB() {
-        mMatrix.loadIdentity();
-        mMatrix.set(0, 0, 1.f);
-        mMatrix.set(1, 0, 0.f);
-        mMatrix.set(2, 0, 1.13983f);
-        mMatrix.set(0, 1, 1.f);
-        mMatrix.set(1, 1, -0.39465f);
-        mMatrix.set(2, 1, -0.5806f);
-        mMatrix.set(0, 2, 1.f);
-        mMatrix.set(1, 2, 2.03211f);
-        mMatrix.set(2, 2, 0.f);
-        setMatrix();
-    }
-
-    /**
-     * Set the matrix to convert from RGB to YUV with a direct copy of the 4th
-     * channel.
-     *
-     */
-    public void setRGBtoYUV() {
-        mMatrix.loadIdentity();
-        mMatrix.set(0, 0, 0.299f);
-        mMatrix.set(1, 0, 0.587f);
-        mMatrix.set(2, 0, 0.114f);
-        mMatrix.set(0, 1, -0.14713f);
-        mMatrix.set(1, 1, -0.28886f);
-        mMatrix.set(2, 1, 0.436f);
-        mMatrix.set(0, 2, 0.615f);
-        mMatrix.set(1, 2, -0.51499f);
-        mMatrix.set(2, 2, -0.10001f);
-        setMatrix();
-    }
-
-
-    /**
-     * Invoke the kernel and apply the matrix to each cell of ain and copy to
-     * aout.
-     *
-     * @param ain Input allocation
-     * @param aout Output allocation
-     */
-    public void forEach(Allocation ain, Allocation aout) {
-        forEach(0, ain, aout, null);
-    }
-
-    /**
-     * Invoke the kernel and apply the matrix to each cell of input
-     * {@link Allocation} and copy to the output {@link Allocation}.
-     *
-     * If the vector size of the input is less than four, the
-     * remaining components are treated as zero for the matrix
-     * multiply.
-     *
-     * If the output vector size is less than four, the unused
-     * vector components are discarded.
-     *
-     *
-     * @param ain Input allocation
-     * @param aout Output allocation
-     * @param opt LaunchOptions for clipping
-     */
-    public void forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
-        if (!ain.getElement().isCompatible(Element.U8(mRS)) &&
-            !ain.getElement().isCompatible(Element.U8_2(mRS)) &&
-            !ain.getElement().isCompatible(Element.U8_3(mRS)) &&
-            !ain.getElement().isCompatible(Element.U8_4(mRS)) &&
-            !ain.getElement().isCompatible(Element.F32(mRS)) &&
-            !ain.getElement().isCompatible(Element.F32_2(mRS)) &&
-            !ain.getElement().isCompatible(Element.F32_3(mRS)) &&
-            !ain.getElement().isCompatible(Element.F32_4(mRS))) {
-
-            throw new RSIllegalArgumentException("Unsupported element type.");
-        }
-
-        if (!aout.getElement().isCompatible(Element.U8(mRS)) &&
-            !aout.getElement().isCompatible(Element.U8_2(mRS)) &&
-            !aout.getElement().isCompatible(Element.U8_3(mRS)) &&
-            !aout.getElement().isCompatible(Element.U8_4(mRS)) &&
-            !aout.getElement().isCompatible(Element.F32(mRS)) &&
-            !aout.getElement().isCompatible(Element.F32_2(mRS)) &&
-            !aout.getElement().isCompatible(Element.F32_3(mRS)) &&
-            !aout.getElement().isCompatible(Element.F32_4(mRS))) {
-
-            throw new RSIllegalArgumentException("Unsupported element type.");
-        }
-
-        forEach(0, ain, aout, null, opt);
-    }
-
-    /**
-     * Get a KernelID for this intrinsic kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelID() {
-        return createKernelID(0, 3, null, null);
-    }
-
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicConvolve3x3.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicConvolve3x3.java
deleted file mode 100644
index 17889aa..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicConvolve3x3.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.Log;
-
-/**
- * Intrinsic for applying a 3x3 convolve to an allocation.
- *
- **/
-public class ScriptIntrinsicConvolve3x3 extends ScriptIntrinsic {
-    private final float[] mValues = new float[9];
-    private Allocation mInput;
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 19;
-
-    ScriptIntrinsicConvolve3x3(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Supported elements types are {@link Element#U8}, {@link
-     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
-     * {@link Element#F32}, {@link Element#F32_2}, {@link
-     * Element#F32_3}, and {@link Element#F32_4}.
-     *
-     * <p> The default coefficients are:
-     * <code>
-     * <p> [ 0,  0,  0 ]
-     * <p> [ 0,  1,  0 ]
-     * <p> [ 0,  0,  0 ]
-     * </code>
-     *
-     * @param rs The RenderScript context
-     * @param e Element type for intputs and outputs
-     *
-     * @return ScriptIntrinsicConvolve3x3
-     */
-    public static ScriptIntrinsicConvolve3x3 create(RenderScript rs, Element e) {
-        float f[] = { 0, 0, 0, 0, 1, 0, 0, 0, 0};
-        if (!e.isCompatible(Element.U8(rs)) &&
-            !e.isCompatible(Element.U8_2(rs)) &&
-            !e.isCompatible(Element.U8_3(rs)) &&
-            !e.isCompatible(Element.U8_4(rs)) &&
-            !e.isCompatible(Element.F32(rs)) &&
-            !e.isCompatible(Element.F32_2(rs)) &&
-            !e.isCompatible(Element.F32_3(rs)) &&
-            !e.isCompatible(Element.F32_4(rs))) {
-            throw new RSIllegalArgumentException("Unsupported element type.");
-        }
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(1, e.getID(rs), mUseIncSupp);
-
-        ScriptIntrinsicConvolve3x3 si = new ScriptIntrinsicConvolve3x3(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        si.setCoefficients(f);
-        return si;
-    }
-
-    /**
-     * Set the input of the 3x3 convolve.
-     * Must match the element type supplied during create.
-     *
-     * @param ain The input allocation.
-     */
-    public void setInput(Allocation ain) {
-        mInput = ain;
-        setVar(1, ain);
-    }
-
-    /**
-     * Set the coefficients for the convolve.
-     *
-     * <p> The convolve layout is:
-     * <code>
-     * <p> [ 0,  1,  2 ]
-     * <p> [ 3,  4,  5 ]
-     * <p> [ 6,  7,  8 ]
-     * </code>
-     *
-     * @param v The array of coefficients to set
-     */
-    public void setCoefficients(float v[]) {
-        FieldPacker fp = new FieldPacker(9*4);
-        for (int ct=0; ct < mValues.length; ct++) {
-            mValues[ct] = v[ct];
-            fp.addF32(mValues[ct]);
-        }
-        setVar(0, fp);
-    }
-
-    /**
-     * Apply the filter to the input and save to the specified
-     * allocation.
-     *
-     * @param aout Output allocation. Must match creation element
-     *             type.
-     */
-    public void forEach(Allocation aout) {
-        forEach(0, (Allocation) null, aout, null);
-    }
-
-    /**
-     * Apply the filter to the input and save to the specified
-     * allocation.
-     *
-     * @param aout Output allocation. Must match creation element
-     *             type.
-     * @param opt LaunchOptions for clipping
-     */
-    public void forEach(Allocation aout, Script.LaunchOptions opt) {
-        forEach(0, (Allocation) null, aout, null, opt);
-    }
-
-    /**
-     * Get a KernelID for this intrinsic kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelID() {
-        return createKernelID(0, 2, null, null);
-    }
-
-    /**
-     * Get a FieldID for the input field of this intrinsic.
-     *
-     * @return Script.FieldID The FieldID object.
-     */
-    public Script.FieldID getFieldID_Input() {
-        return createFieldID(1, null);
-    }
-
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicConvolve5x5.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicConvolve5x5.java
deleted file mode 100644
index 2c591ba..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicConvolve5x5.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.Log;
-
-/**
- * Intrinsic for applying a 5x5 convolve to an allocation.
- *
- **/
-public class ScriptIntrinsicConvolve5x5 extends ScriptIntrinsic {
-    private final float[] mValues = new float[25];
-    private Allocation mInput;
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 19;
-
-    ScriptIntrinsicConvolve5x5(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Supported elements types are {@link Element#U8}, {@link
-     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
-     * {@link Element#F32}, {@link Element#F32_2}, {@link
-     * Element#F32_3}, and {@link Element#F32_4}.
-     *
-     * <p> The default coefficients are:
-     * <code>
-     * <p> [ 0,  0,  0,  0,  0  ]
-     * <p> [ 0,  0,  0,  0,  0  ]
-     * <p> [ 0,  0,  1,  0,  0  ]
-     * <p> [ 0,  0,  0,  0,  0  ]
-     * <p> [ 0,  0,  0,  0,  0  ]
-     * </code>
-     *
-     * @param rs The RenderScript context
-     * @param e Element type for intputs and outputs
-     *
-     * @return ScriptIntrinsicConvolve5x5
-     */
-    public static ScriptIntrinsicConvolve5x5 create(RenderScript rs, Element e) {
-        if (!e.isCompatible(Element.U8(rs)) &&
-            !e.isCompatible(Element.U8_2(rs)) &&
-            !e.isCompatible(Element.U8_3(rs)) &&
-            !e.isCompatible(Element.U8_4(rs)) &&
-            !e.isCompatible(Element.F32(rs)) &&
-            !e.isCompatible(Element.F32_2(rs)) &&
-            !e.isCompatible(Element.F32_3(rs)) &&
-            !e.isCompatible(Element.F32_4(rs))) {
-            throw new RSIllegalArgumentException("Unsupported element type.");
-        }
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(4, e.getID(rs), mUseIncSupp);
-
-        ScriptIntrinsicConvolve5x5 si = new ScriptIntrinsicConvolve5x5(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        return si;
-
-    }
-
-    /**
-     * Set the input of the 5x5 convolve.
-     * Must match the element type supplied during create.
-     *
-     * @param ain The input allocation.
-     */
-    public void setInput(Allocation ain) {
-        mInput = ain;
-        setVar(1, ain);
-    }
-
-    /**
-    * Set the coefficients for the convolve.
-    *
-    * <p> The convolve layout is:
-    * <code>
-    * <p> [ 0,  1,  2,  3,  4  ]
-    * <p> [ 5,  6,  7,  8,  9  ]
-    * <p> [ 10, 11, 12, 13, 14 ]
-    * <p> [ 15, 16, 17, 18, 19 ]
-    * <p> [ 20, 21, 22, 23, 24 ]
-    * </code>
-    *
-    * @param v The array of coefficients to set
-    */
-    public void setCoefficients(float v[]) {
-        FieldPacker fp = new FieldPacker(25*4);
-        for (int ct=0; ct < mValues.length; ct++) {
-            mValues[ct] = v[ct];
-            fp.addF32(mValues[ct]);
-        }
-        setVar(0, fp);
-    }
-
-    /**
-     * Apply the filter to the input and save to the specified
-     * allocation.
-     *
-     * @param aout Output allocation. Must match creation element
-     *             type.
-     */
-    public void forEach(Allocation aout) {
-        forEach(0, (Allocation) null, aout, null);
-    }
-
-    /**
-     * Apply the filter to the input and save to the specified
-     * allocation.
-     *
-     * @param aout Output allocation. Must match creation element
-     *             type.
-     * @param opt LaunchOptions for clipping
-     */
-    public void forEach(Allocation aout, Script.LaunchOptions opt) {
-        forEach(0, (Allocation) null, aout, null, opt);
-    }
-
-
-    /**
-     * Get a KernelID for this intrinsic kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelID() {
-        return createKernelID(0, 2, null, null);
-    }
-
-    /**
-     * Get a FieldID for the input field of this intrinsic.
-     *
-     * @return Script.FieldID The FieldID object.
-     */
-    public Script.FieldID getFieldID_Input() {
-        return createFieldID(1, null);
-    }
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicHistogram.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicHistogram.java
deleted file mode 100644
index e3e6406..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicHistogram.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.Log;
-
-/**
- * Intrinsic Histogram filter.
- *
- *
- **/
-public class ScriptIntrinsicHistogram extends ScriptIntrinsic {
-    private Allocation mOut;
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 19;
-
-    protected ScriptIntrinsicHistogram(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Create an intrinsic for calculating the histogram of an uchar
-     * or uchar4 image.
-     *
-     * Supported elements types are
-     * {@link Element#U8_4}, {@link Element#U8_3},
-     * {@link Element#U8_2}, {@link Element#U8}
-     *
-     * @param rs The RenderScript context
-     * @param e Element type for inputs
-     *
-     * @return ScriptIntrinsicHistogram
-     */
-    public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
-        if ((!e.isCompatible(Element.U8_4(rs))) &&
-            (!e.isCompatible(Element.U8_3(rs))) &&
-            (!e.isCompatible(Element.U8_2(rs))) &&
-            (!e.isCompatible(Element.U8(rs)))) {
-            throw new RSIllegalArgumentException("Unsupported element type.");
-        }
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(9, e.getID(rs), mUseIncSupp);
-
-        ScriptIntrinsicHistogram si = new ScriptIntrinsicHistogram(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        return si;
-    }
-
-    /**
-     * Process an input buffer and place the histogram into the
-     * output allocation. The output allocation may be a narrower
-     * vector size than the input. In this case the vector size of
-     * the output is used to determine how many of the input
-     * channels are used in the computation. This is useful if you
-     * have an RGBA input buffer but only want the histogram for
-     * RGB.
-     *
-     * 1D and 2D input allocations are supported.
-     *
-     * @param ain The input image
-     */
-    public void forEach(Allocation ain) {
-        forEach(ain, null);
-    }
-
-    /**
-     * Process an input buffer and place the histogram into the
-     * output allocation. The output allocation may be a narrower
-     * vector size than the input. In this case the vector size of
-     * the output is used to determine how many of the input
-     * channels are used in the computation. This is useful if you
-     * have an RGBA input buffer but only want the histogram for
-     * RGB.
-     *
-     * 1D and 2D input allocations are supported.
-     *
-     * @param ain The input image
-     * @param opt LaunchOptions for clipping
-     */
-    public void forEach(Allocation ain, Script.LaunchOptions opt) {
-        if (ain.getType().getElement().getVectorSize() <
-            mOut.getType().getElement().getVectorSize()) {
-
-            throw new RSIllegalArgumentException(
-                "Input vector size must be >= output vector size.");
-        }
-        if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
-            !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
-            !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
-            !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
-            throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
-        }
-
-        forEach(0, ain, null, null, opt);
-    }
-
-
-
-    /**
-     * Set the coefficients used for the RGBA to Luminocity
-     * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
-     *
-     * Coefficients must be >= 0 and sum to 1.0 or less.
-     *
-     * @param r Red coefficient
-     * @param g Green coefficient
-     * @param b Blue coefficient
-     * @param a Alpha coefficient
-     */
-    public void setDotCoefficients(float r, float g, float b, float a) {
-        if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
-            throw new RSIllegalArgumentException("Coefficient may not be negative.");
-        }
-        if ((r + g + b + a) > 1.f) {
-            throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
-        }
-
-        FieldPacker fp = new FieldPacker(16);
-        fp.addF32(r);
-        fp.addF32(g);
-        fp.addF32(b);
-        fp.addF32(a);
-        setVar(0, fp);
-    }
-
-    /**
-     * Set the output of the histogram.  32 bit integer types are
-     * supported.
-     *
-     * @param aout The output allocation
-     */
-    public void setOutput(Allocation aout) {
-        mOut = aout;
-        if (mOut.getType().getElement() != Element.U32(mRS) &&
-            mOut.getType().getElement() != Element.U32_2(mRS) &&
-            mOut.getType().getElement() != Element.U32_3(mRS) &&
-            mOut.getType().getElement() != Element.U32_4(mRS) &&
-            mOut.getType().getElement() != Element.I32(mRS) &&
-            mOut.getType().getElement() != Element.I32_2(mRS) &&
-            mOut.getType().getElement() != Element.I32_3(mRS) &&
-            mOut.getType().getElement() != Element.I32_4(mRS)) {
-
-            throw new RSIllegalArgumentException("Output type must be U32 or I32.");
-        }
-        if ((mOut.getType().getX() != 256) ||
-            (mOut.getType().getY() != 0) ||
-            mOut.getType().hasMipmaps() ||
-            (mOut.getType().getYuv() != 0)) {
-
-            throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
-        }
-        setVar(1, aout);
-    }
-
-
-    /**
-     * Process an input buffer and place the histogram into the
-     * output allocation. The dot product of the input channel and
-     * the coefficients from 'setDotCoefficients' are used to
-     * calculate the output values.
-     *
-     * 1D and 2D input allocations are supported.
-     *
-     * @param ain The input image
-     */
-    public void forEach_Dot(Allocation ain) {
-        forEach_Dot(ain, null);
-    }
-
-    /**
-     * Process an input buffer and place the histogram into the
-     * output allocation. The dot product of the input channel and
-     * the coefficients from 'setDotCoefficients' are used to
-     * calculate the output values.
-     *
-     * 1D and 2D input allocations are supported.
-     *
-     * @param ain The input image
-     * @param opt LaunchOptions for clipping
-     */
-    public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
-        if (mOut.getType().getElement().getVectorSize() != 1) {
-            throw new RSIllegalArgumentException("Output vector size must be one.");
-        }
-        if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
-            !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
-            !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
-            !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
-            throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
-        }
-
-        forEach(1, ain, null, null, opt);
-    }
-
-
-
-    /**
-     * Get a KernelID for this intrinsic kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelID_Separate() {
-        return createKernelID(0, 3, null, null);
-    }
-
-    /**
-     * Get a FieldID for the input field of this intrinsic.
-     *
-     * @return Script.FieldID The FieldID object.
-     */
-    public Script.FieldID getFieldID_Input() {
-        return createFieldID(1, null);
-    }
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicLUT.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicLUT.java
deleted file mode 100644
index 0b905ba..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicLUT.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.Log;
-
-/**
- * Intrinsic for applying a per-channel lookup table. Each
- * channel of the input has an independant lookup table. The
- * tables are 256 entries in size and can cover the full value
- * range of {@link Element#U8_4}.
- **/
-public class ScriptIntrinsicLUT extends ScriptIntrinsic {
-    private final Matrix4f mMatrix = new Matrix4f();
-    private Allocation mTables;
-    private final byte mCache[] = new byte[1024];
-    private boolean mDirty = true;
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 19;
-
-    protected ScriptIntrinsicLUT(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Supported elements types are {@link Element#U8_4}
-     *
-     * The defaults tables are identity.
-     *
-     * @param rs The RenderScript context
-     * @param e Element type for intputs and outputs
-     *
-     * @return ScriptIntrinsicLUT
-     */
-    public static ScriptIntrinsicLUT create(RenderScript rs, Element e) {
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(3, e.getID(rs), mUseIncSupp);
-
-        ScriptIntrinsicLUT si = new ScriptIntrinsicLUT(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        si.mTables = Allocation.createSized(rs, Element.U8(rs), 1024);
-        for (int ct=0; ct < 256; ct++) {
-            si.mCache[ct] = (byte)ct;
-            si.mCache[ct + 256] = (byte)ct;
-            si.mCache[ct + 512] = (byte)ct;
-            si.mCache[ct + 768] = (byte)ct;
-        }
-        si.setVar(0, si.mTables);
-        return si;
-    }
-
-
-    private void validate(int index, int value) {
-        if (index < 0 || index > 255) {
-            throw new RSIllegalArgumentException("Index out of range (0-255).");
-        }
-        if (value < 0 || value > 255) {
-            throw new RSIllegalArgumentException("Value out of range (0-255).");
-        }
-    }
-
-    /**
-     * Set an entry in the red channel lookup table
-     *
-     * @param index Must be 0-255
-     * @param value Must be 0-255
-     */
-    public void setRed(int index, int value) {
-        validate(index, value);
-        mCache[index] = (byte)value;
-        mDirty = true;
-    }
-
-    /**
-     * Set an entry in the green channel lookup table
-     *
-     * @param index Must be 0-255
-     * @param value Must be 0-255
-     */
-    public void setGreen(int index, int value) {
-        validate(index, value);
-        mCache[index+256] = (byte)value;
-        mDirty = true;
-    }
-
-    /**
-     * Set an entry in the blue channel lookup table
-     *
-     * @param index Must be 0-255
-     * @param value Must be 0-255
-     */
-    public void setBlue(int index, int value) {
-        validate(index, value);
-        mCache[index+512] = (byte)value;
-        mDirty = true;
-    }
-
-    /**
-     * Set an entry in the alpha channel lookup table
-     *
-     * @param index Must be 0-255
-     * @param value Must be 0-255
-     */
-    public void setAlpha(int index, int value) {
-        validate(index, value);
-        mCache[index+768] = (byte)value;
-        mDirty = true;
-    }
-
-
-    /**
-     * Invoke the kernel and apply the lookup to each cell of ain
-     * and copy to aout.
-     *
-     * @param ain Input allocation
-     * @param aout Output allocation
-     */
-    public void forEach(Allocation ain, Allocation aout) {
-        if (mDirty) {
-            mDirty = false;
-            mTables.copyFromUnchecked(mCache);
-        }
-        forEach(0, ain, aout, null);
-    }
-
-    /**
-     * Get a KernelID for this intrinsic kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelID() {
-        return createKernelID(0, 3, null, null);
-    }
-}
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicResize.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicResize.java
deleted file mode 100644
index 61c169c..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicResize.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import android.util.Log;
-
-/**
- * Intrinsic for performing a resize of a 2D allocation.
- */
-public class ScriptIntrinsicResize extends ScriptIntrinsic {
-    private Allocation mInput;
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 21;
-
-    protected ScriptIntrinsicResize(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Supported elements types are {@link Element#U8}, {@link
-     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4}
-     * {@link Element#F32}, {@link Element#F32_2}, {@link
-     * Element#F32_3}, {@link Element#F32_4}
-     *
-     * @param rs The RenderScript context
-     *
-     * @return ScriptIntrinsicResize
-     */
-    public static ScriptIntrinsicResize create(RenderScript rs) {
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(12, 0, mUseIncSupp);
-
-        ScriptIntrinsicResize si = new ScriptIntrinsicResize(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        return si;
-
-    }
-
-    /**
-     * Set the input of the resize.
-     * Must match the element type supplied during create.
-     *
-     * @param ain The input allocation.
-     */
-    public void setInput(Allocation ain) {
-        Element e = ain.getElement();
-        if (!e.isCompatible(Element.U8(mRS)) &&
-            !e.isCompatible(Element.U8_2(mRS)) &&
-            !e.isCompatible(Element.U8_3(mRS)) &&
-            !e.isCompatible(Element.U8_4(mRS)) &&
-            !e.isCompatible(Element.F32(mRS)) &&
-            !e.isCompatible(Element.F32_2(mRS)) &&
-            !e.isCompatible(Element.F32_3(mRS)) &&
-            !e.isCompatible(Element.F32_4(mRS))) {
-            throw new RSIllegalArgumentException("Unsupported element type.");
-        }
-
-        mInput = ain;
-        setVar(0, ain);
-    }
-
-    /**
-     * Get a FieldID for the input field of this intrinsic.
-     *
-     * @return Script.FieldID The FieldID object.
-     */
-    public Script.FieldID getFieldID_Input() {
-        return createFieldID(0, null);
-    }
-
-
-    /**
-     * Resize copy the input allocation to the output specified. The
-     * Allocation is rescaled if necessary using bi-cubic
-     * interpolation.
-     *
-     * @param aout Output allocation. Element type must match
-     *             current input.  Must not be same as input.
-     */
-    public void forEach_bicubic(Allocation aout) {
-        if (aout == mInput) {
-            throw new RSIllegalArgumentException("Output cannot be same as Input.");
-        }
-        forEach_bicubic(aout, null);
-    }
-
-    /**
-     * Resize copy the input allocation to the output specified. The
-     * Allocation is rescaled if necessary using bi-cubic
-     * interpolation.
-     *
-     * @param aout Output allocation. Element type must match
-     *             current input.
-     * @param opt LaunchOptions for clipping
-     */
-    public void forEach_bicubic(Allocation aout, Script.LaunchOptions opt) {
-        forEach(0, (Allocation) null, aout, null, opt);
-    }
-
-    /**
-     * Get a KernelID for this intrinsic kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelID_bicubic() {
-        return createKernelID(0, 2, null, null);
-    }
-
-
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicYuvToRGB.java b/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicYuvToRGB.java
deleted file mode 100644
index 6c84020..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ScriptIntrinsicYuvToRGB.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-
-/**
- * Intrinsic for converting an Android YUV buffer to RGB.
- *
- * The input allocation is supplied in NV21 format as a U8
- * element type. The output is RGBA, the alpha channel will be
- * set to 255.
- */
-public class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic {
-    private Allocation mInput;
-    // API level for the intrinsic
-    private static final int INTRINSIC_API_LEVEL = 19;
-
-    ScriptIntrinsicYuvToRGB(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /**
-     * Create an intrinsic for converting YUV to RGB.
-     *
-     * Supported elements types are {@link Element#U8_4}
-     *
-     * @param rs The RenderScript context
-     * @param e Element type for output
-     *
-     * @return ScriptIntrinsicYuvToRGB
-     */
-    public static ScriptIntrinsicYuvToRGB create(RenderScript rs, Element e) {
-        // 6 comes from RS_SCRIPT_INTRINSIC_YUV_TO_RGB in rsDefines.h
-        long id;
-        boolean mUseIncSupp = rs.isUseNative() &&
-                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
-
-        id = rs.nScriptIntrinsicCreate(6, e.getID(rs), mUseIncSupp);
-
-        ScriptIntrinsicYuvToRGB si = new ScriptIntrinsicYuvToRGB(id, rs);
-        si.setIncSupp(mUseIncSupp);
-        return si;
-    }
-
-
-    /**
-     * Set the input yuv allocation, must be {@link Element#U8}.
-     *
-     * @param ain The input allocation.
-     */
-    public void setInput(Allocation ain) {
-        mInput = ain;
-        setVar(0, ain);
-    }
-
-    /**
-     * Convert the image to RGB.
-     *
-     * @param aout Output allocation. Must match creation element
-     *             type.
-     */
-    public void forEach(Allocation aout) {
-        forEach(0, (Allocation) null, aout, null);
-    }
-
-    /**
-     * Get a KernelID for this intrinsic kernel.
-     *
-     * @return Script.KernelID The KernelID object.
-     */
-    public Script.KernelID getKernelID() {
-        return createKernelID(0, 2, null, null);
-    }
-
-    /**
-     * Get a FieldID for the input field of this intrinsic.
-     *
-     * @return Script.FieldID The FieldID object.
-     */
-    public Script.FieldID getFieldID_Input() {
-        return createFieldID(0, null);
-    }
-}
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Short2.java b/v8/renderscript/java/src/android/support/v8/renderscript/Short2.java
deleted file mode 100644
index 365b319..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Short2.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript Short2 type back to the Android system.
- *
- **/
-public class Short2 {
-    public Short2() {
-    }
-
-    public Short2(short initX, short initY) {
-        x = initX;
-        y = initY;
-    }
-
-    public short x;
-    public short y;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Short3.java b/v8/renderscript/java/src/android/support/v8/renderscript/Short3.java
deleted file mode 100644
index abf8196..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Short3.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript short3 type back to the Android system.
- *
- **/
-public class Short3 {
-    public Short3() {
-    }
-
-    public Short3(short initX, short initY, short initZ) {
-        x = initX;
-        y = initY;
-        z = initZ;
-    }
-
-    public short x;
-    public short y;
-    public short z;
-}
-
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Short4.java b/v8/renderscript/java/src/android/support/v8/renderscript/Short4.java
deleted file mode 100644
index d2108e4..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Short4.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-import java.lang.Math;
-import android.util.Log;
-
-
-/**
- * Class for exposing the native RenderScript short4 type back to the Android system.
- *
- **/
-public class Short4 {
-    public Short4() {
-    }
-
-    public Short4(short initX, short initY, short initZ, short initW) {
-        x = initX;
-        y = initY;
-        z = initZ;
-        w = initW;
-    }
-
-    public short x;
-    public short y;
-    public short z;
-    public short w;
-}
-
-
-
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Type.java b/v8/renderscript/java/src/android/support/v8/renderscript/Type.java
deleted file mode 100644
index 6aeb9ea..0000000
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Type.java
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v8.renderscript;
-
-
-import java.lang.reflect.Field;
-
-import android.graphics.ImageFormat;
-import android.util.Log;
-
-/**
- * <p>A Type describes the {@link android.support.v8.renderscript.Element} and
- * dimensions used for an {@link android.support.v8.renderscript.Allocation} or
- * a parallel operation. Types are created through
- * {@link android.support.v8.renderscript.Type.Builder}.</p>
- *
- * <p>A Type always includes an {@link android.support.v8.renderscript.Element}
- * and an X dimension. A Type may be multidimensional, up to three dimensions.
- * A nonzero value in the Y or Z dimensions indicates that the dimension is
- * present. Note that a Type with only a given X dimension and a Type with the
- * same X dimension but Y = 1 are not equivalent.</p>
- *
- * <p>A Type also supports inclusion of level of detail (LOD) or cube map
- * faces. LOD and cube map faces are booleans to indicate present or not
- * present. </p>
- *
- * <p>A Type also supports YUV format information to support an {@link
- * android.support.v8.renderscript.Allocation} in a YUV format. The YUV formats
- * supported are {@link android.graphics.ImageFormat#YV12} and {@link
- * android.graphics.ImageFormat#NV21}.</p>
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses RenderScript,
- * read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
- * developer guide.</p>
- * </div>
- **/
-public class Type extends BaseObj {
-    int mDimX;
-    int mDimY;
-    int mDimZ;
-    boolean mDimMipmaps;
-    boolean mDimFaces;
-    int mDimYuv;
-    int mElementCount;
-    Element mElement;
-
-    public enum CubemapFace {
-        POSITIVE_X (0),
-        NEGATIVE_X (1),
-        POSITIVE_Y (2),
-        NEGATIVE_Y (3),
-        POSITIVE_Z (4),
-        NEGATIVE_Z (5);
-
-        int mID;
-        CubemapFace(int id) {
-            mID = id;
-        }
-    }
-
-    /**
-     * Return the element associated with this Type.
-     *
-     * @return Element
-     */
-    public Element getElement() {
-        return mElement;
-    }
-
-    /**
-     * Return the value of the X dimension.
-     *
-     * @return int
-     */
-    public int getX() {
-        return mDimX;
-    }
-
-    /**
-     * Return the value of the Y dimension or 0 for a 1D allocation.
-     *
-     * @return int
-     */
-    public int getY() {
-        return mDimY;
-    }
-
-    /**
-     * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
-     *
-     * @return int
-     */
-    public int getZ() {
-        return mDimZ;
-    }
-
-    /**
-     * Get the YUV format
-     *
-     * @return int
-     */
-    public int getYuv() {
-        return mDimYuv;
-    }
-
-    /**
-     * Return if the Type has a mipmap chain.
-     *
-     * @return boolean
-     */
-    public boolean hasMipmaps() {
-        return mDimMipmaps;
-    }
-
-    /**
-     * Return if the Type is a cube map.
-     *
-     * @return boolean
-     */
-    public boolean hasFaces() {
-        return mDimFaces;
-    }
-
-    /**
-     * Return the total number of accessable cells in the Type.
-     *
-     * @return int
-     */
-    public int getCount() {
-        return mElementCount;
-    }
-
-    void calcElementCount() {
-        boolean hasLod = hasMipmaps();
-        int x = getX();
-        int y = getY();
-        int z = getZ();
-        int faces = 1;
-        if (hasFaces()) {
-            faces = 6;
-        }
-        if (x == 0) {
-            x = 1;
-        }
-        if (y == 0) {
-            y = 1;
-        }
-        if (z == 0) {
-            z = 1;
-        }
-
-        int count = x * y * z * faces;
-
-        while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
-            if(x > 1) {
-                x >>= 1;
-            }
-            if(y > 1) {
-                y >>= 1;
-            }
-            if(z > 1) {
-                z >>= 1;
-            }
-
-            count += x * y * z * faces;
-        }
-        mElementCount = count;
-    }
-
-
-    Type(long id, RenderScript rs) {
-        super(id, rs);
-    }
-
-    /*
-     * Get an identical dummy Type for Compat Context
-     *
-     */
-    public long getDummyType(RenderScript mRS, long eid) {
-        return mRS.nIncTypeCreate(eid, mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mDimYuv);
-    }
-
-    /**
-     * Utility function for creating basic 1D types. The type is
-     * created without mipmaps enabled.
-     *
-     * @param rs The RenderScript context
-     * @param e The Element for the Type
-     * @param dimX The X dimension, must be > 0
-     *
-     * @return Type
-     */
-    static public Type createX(RenderScript rs, Element e, int dimX) {
-        if (dimX < 1) {
-            throw new RSInvalidStateException("Dimension must be >= 1.");
-        }
-
-        long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0);
-        Type t = new Type(id, rs);
-        t.mElement = e;
-        t.mDimX = dimX;
-        t.calcElementCount();
-        return t;
-    }
-
-    /**
-     * Utility function for creating basic 2D types. The type is
-     * created without mipmaps or cubemaps.
-     *
-     * @param rs The RenderScript context
-     * @param e The Element for the Type
-     * @param dimX The X dimension, must be > 0
-     * @param dimY The Y dimension, must be > 0
-     *
-     * @return Type
-     */
-    static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) {
-        if ((dimX < 1) || (dimY < 1)) {
-            throw new RSInvalidStateException("Dimension must be >= 1.");
-        }
-
-        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0);
-        Type t = new Type(id, rs);
-        t.mElement = e;
-        t.mDimX = dimX;
-        t.mDimY = dimY;
-        t.calcElementCount();
-        return t;
-    }
-
-    /**
-     * Utility function for creating basic 3D types. The type is
-     * created without mipmaps.
-     *
-     * @param rs The RenderScript context
-     * @param e The Element for the Type
-     * @param dimX The X dimension, must be > 0
-     * @param dimY The Y dimension, must be > 0
-     * @param dimZ The Z dimension, must be > 0
-     *
-     * @return Type
-     */
-    static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) {
-        if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) {
-            throw new RSInvalidStateException("Dimension must be >= 1.");
-        }
-
-        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0);
-        Type t = new Type(id, rs);
-        t.mElement = e;
-        t.mDimX = dimX;
-        t.mDimY = dimY;
-        t.mDimZ = dimZ;
-        t.calcElementCount();
-        return t;
-    }
-
-    /**
-     * Builder class for Type.
-     *
-     */
-    public static class Builder {
-        RenderScript mRS;
-        int mDimX = 1;
-        int mDimY;
-        int mDimZ;
-        boolean mDimMipmaps;
-        boolean mDimFaces;
-        int mYuv;
-
-        Element mElement;
-
-        /**
-         * Create a new builder object.
-         *
-         * @param rs
-         * @param e The element for the type to be created.
-         */
-        public Builder(RenderScript rs, Element e) {
-            e.checkValid();
-            mRS = rs;
-            mElement = e;
-        }
-
-        /**
-         * Add a dimension to the Type.
-         *
-         *
-         * @param value
-         */
-        public Builder setX(int value) {
-            if(value < 1) {
-                throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
-            }
-            mDimX = value;
-            return this;
-        }
-
-        public Builder setY(int value) {
-            if(value < 1) {
-                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
-            }
-            mDimY = value;
-            return this;
-        }
-
-        public Builder setZ(int value) {
-            if(value < 1) {
-                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid.");
-            }
-            mDimZ = value;
-            return this;
-        }
-
-        public Builder setMipmaps(boolean value) {
-            mDimMipmaps = value;
-            return this;
-        }
-
-        public Builder setFaces(boolean value) {
-            mDimFaces = value;
-            return this;
-        }
-
-        /**
-         * Set the YUV layout for a Type.
-         *
-         * @param yuvFormat {@link android.graphics.ImageFormat#YV12} or {@link android.graphics.ImageFormat#NV21}
-         */
-        public Builder setYuvFormat(int yuvFormat) {
-            switch (yuvFormat) {
-            case android.graphics.ImageFormat.NV21:
-            case android.graphics.ImageFormat.YV12:
-                break;
-
-            default:
-                throw new RSIllegalArgumentException("Only NV21 and YV12 are supported..");
-            }
-
-            mYuv = yuvFormat;
-            return this;
-        }
-
-
-        /**
-         * Validate structure and create a new Type.
-         *
-         * @return Type
-         */
-        public Type create() {
-            if (mDimZ > 0) {
-                if ((mDimX < 1) || (mDimY < 1)) {
-                    throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
-                }
-                if (mDimFaces) {
-                    throw new RSInvalidStateException("Cube maps not supported with 3D types.");
-                }
-            }
-            if (mDimY > 0) {
-                if (mDimX < 1) {
-                    throw new RSInvalidStateException("X dimension required when Y is present.");
-                }
-            }
-            if (mDimFaces) {
-                if (mDimY < 1) {
-                    throw new RSInvalidStateException("Cube maps require 2D Types.");
-                }
-            }
-
-            if (mYuv != 0) {
-                if ((mDimZ != 0) || mDimFaces || mDimMipmaps) {
-                    throw new RSInvalidStateException("YUV only supports basic 2D.");
-                }
-            }
-
-            Type t;
-            long id = mRS.nTypeCreate(mElement.getID(mRS),
-                                     mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv);
-            t = new Type(id, mRS);
-
-            t.mElement = mElement;
-            t.mDimX = mDimX;
-            t.mDimY = mDimY;
-            t.mDimZ = mDimZ;
-            t.mDimMipmaps = mDimMipmaps;
-            t.mDimFaces = mDimFaces;
-            t.mDimYuv = mYuv;
-
-            t.calcElementCount();
-            return t;
-        }
-    }
-
-}
diff --git a/v8/renderscript/jni/Android.mk b/v8/renderscript/jni/Android.mk
deleted file mode 100644
index d6a800d..0000000
--- a/v8/renderscript/jni/Android.mk
+++ /dev/null
@@ -1,56 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_CLANG := true
-LOCAL_SDK_VERSION := 14
-
-LOCAL_SRC_FILES:= \
-    android_rscompat_usage_io.cpp \
-    android_rscompat_usage_io_driver.cpp
-
-LOCAL_C_INCLUDES += \
-	$(JNI_H_INCLUDE) \
-	frameworks/rs \
-	frameworks/rs/cpp \
-	frameworks/rs/driver
-
-LOCAL_CFLAGS += -Wno-unused-parameter -Werror
-LOCAL_CFLAGS += -DRS_COMPATIBILITY_LIB -std=c++11
-
-LOCAL_MODULE:= libRSSupportIO
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_LDLIBS += -landroid
-LOCAL_LDFLAGS += -ldl -Wl,--exclude-libs,libc++_static.a
-LOCAL_NDK_STL_VARIANT := c++_static
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_CLANG := true
-LOCAL_SDK_VERSION := 9
-
-LOCAL_SRC_FILES:= \
-    android_renderscript_RenderScript.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-        libjnigraphics
-
-LOCAL_STATIC_LIBRARIES := \
-        libRSDispatch
-
-LOCAL_C_INCLUDES += \
-	$(JNI_H_INCLUDE) \
-	frameworks/rs \
-	frameworks/rs/cpp
-
-LOCAL_CFLAGS += -Wno-unused-parameter -Werror -std=c++11
-
-LOCAL_MODULE:= librsjni
-LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := libRSSupport
-
-LOCAL_LDFLAGS += -ldl -llog -Wl,--exclude-libs,libc++_static.a
-LOCAL_NDK_STL_VARIANT := c++_static
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/v8/renderscript/jni/android_renderscript_RenderScript.cpp b/v8/renderscript/jni/android_renderscript_RenderScript.cpp
deleted file mode 100644
index 5642835..0000000
--- a/v8/renderscript/jni/android_renderscript_RenderScript.cpp
+++ /dev/null
@@ -1,2431 +0,0 @@
-/*
- * Copyright (C) 2011-2012 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.
- */
-
-#define LOG_TAG "libRS_jni"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-#include <android/bitmap.h>
-#include <android/log.h>
-
-#include <rsEnv.h>
-#include "rsDispatch.h"
-#include <dlfcn.h>
-
-//#define LOG_API ALOG
-#define LOG_API(...)
-#define LOG_ERR(...) __android_log_print(ANDROID_LOG_ERROR, "RenderScript JNI", __VA_ARGS__);
-#define RS_JNI_VERSION 2301
-
-#define NELEM(m) (sizeof(m) / sizeof((m)[0]))
-
-template <typename... T>
-void UNUSED(T... t) {}
-#define PER_ARRAY_TYPE(flag, fnc, readonly, ...) {                                      \
-    jint len = 0;                                                                       \
-    void *ptr = nullptr;                                                                \
-    void *srcPtr = nullptr;                                                             \
-    size_t typeBytes = 0;                                                               \
-    jint relFlag = 0;                                                                   \
-    if (readonly) {                                                                     \
-        /* The on-release mode should only be JNI_ABORT for read-only accesses. */      \
-        /* readonly = true, also indicates we are copying to the allocation   . */      \
-        relFlag = JNI_ABORT;                                                            \
-    }                                                                                   \
-    switch(dataType) {                                                                  \
-    case RS_TYPE_FLOAT_32:                                                              \
-        len = _env->GetArrayLength((jfloatArray)data);                                  \
-        ptr = _env->GetFloatArrayElements((jfloatArray)data, flag);                     \
-        typeBytes = 4;                                                                  \
-        if (usePadding) {                                                               \
-            srcPtr = ptr;                                                               \
-            len = len / 3 * 4;                                                          \
-            if (count == 0) {                                                           \
-                count = len / 4;                                                        \
-            }                                                                           \
-            ptr = malloc (len * typeBytes);                                             \
-            if (readonly) {                                                             \
-                copyWithPadding(ptr, srcPtr, mSize, count);                             \
-                fnc(__VA_ARGS__);                                                       \
-            } else {                                                                    \
-                fnc(__VA_ARGS__);                                                       \
-                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
-            }                                                                           \
-            free(ptr);                                                                  \
-            ptr = srcPtr;                                                               \
-        } else {                                                                        \
-            fnc(__VA_ARGS__);                                                           \
-        }                                                                               \
-        _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, relFlag);     \
-        return;                                                                         \
-    case RS_TYPE_FLOAT_64:                                                              \
-        len = _env->GetArrayLength((jdoubleArray)data);                                 \
-        ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag);                   \
-        typeBytes = 8;                                                                  \
-        if (usePadding) {                                                               \
-            srcPtr = ptr;                                                               \
-            len = len / 3 * 4;                                                          \
-            if (count == 0) {                                                           \
-                count = len / 4;                                                        \
-            }                                                                           \
-            ptr = malloc (len * typeBytes);                                             \
-            if (readonly) {                                                             \
-                copyWithPadding(ptr, srcPtr, mSize, count);                             \
-                fnc(__VA_ARGS__);                                                       \
-            } else {                                                                    \
-                fnc(__VA_ARGS__);                                                       \
-                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
-            }                                                                           \
-            free(ptr);                                                                  \
-            ptr = srcPtr;                                                               \
-        } else {                                                                        \
-            fnc(__VA_ARGS__);                                                           \
-        }                                                                               \
-        _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, relFlag);  \
-        return;                                                                         \
-    case RS_TYPE_SIGNED_8:                                                              \
-    case RS_TYPE_UNSIGNED_8:                                                            \
-        len = _env->GetArrayLength((jbyteArray)data);                                   \
-        ptr = _env->GetByteArrayElements((jbyteArray)data, flag);                       \
-        typeBytes = 1;                                                                  \
-        if (usePadding) {                                                               \
-            srcPtr = ptr;                                                               \
-            len = len / 3 * 4;                                                          \
-            if (count == 0) {                                                           \
-                count = len / 4;                                                        \
-            }                                                                           \
-            ptr = malloc (len * typeBytes);                                             \
-            if (readonly) {                                                             \
-                copyWithPadding(ptr, srcPtr, mSize, count);                             \
-                fnc(__VA_ARGS__);                                                       \
-            } else {                                                                    \
-                fnc(__VA_ARGS__);                                                       \
-                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
-            }                                                                           \
-            free(ptr);                                                                  \
-            ptr = srcPtr;                                                               \
-        } else {                                                                        \
-            fnc(__VA_ARGS__);                                                           \
-        }                                                                               \
-        _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, relFlag);         \
-        return;                                                                         \
-    case RS_TYPE_SIGNED_16:                                                             \
-    case RS_TYPE_UNSIGNED_16:                                                           \
-        len = _env->GetArrayLength((jshortArray)data);                                  \
-        ptr = _env->GetShortArrayElements((jshortArray)data, flag);                     \
-        typeBytes = 2;                                                                  \
-        if (usePadding) {                                                               \
-            srcPtr = ptr;                                                               \
-            len = len / 3 * 4;                                                          \
-            if (count == 0) {                                                           \
-                count = len / 4;                                                        \
-            }                                                                           \
-            ptr = malloc (len * typeBytes);                                             \
-            if (readonly) {                                                             \
-                copyWithPadding(ptr, srcPtr, mSize, count);                             \
-                fnc(__VA_ARGS__);                                                       \
-            } else {                                                                    \
-                fnc(__VA_ARGS__);                                                       \
-                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
-            }                                                                           \
-            free(ptr);                                                                  \
-            ptr = srcPtr;                                                               \
-        } else {                                                                        \
-            fnc(__VA_ARGS__);                                                           \
-        }                                                                               \
-        _env->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, relFlag);     \
-        return;                                                                         \
-    case RS_TYPE_SIGNED_32:                                                             \
-    case RS_TYPE_UNSIGNED_32:                                                           \
-        len = _env->GetArrayLength((jintArray)data);                                    \
-        ptr = _env->GetIntArrayElements((jintArray)data, flag);                         \
-        typeBytes = 4;                                                                  \
-        if (usePadding) {                                                               \
-            srcPtr = ptr;                                                               \
-            len = len / 3 * 4;                                                          \
-            if (count == 0) {                                                           \
-                count = len / 4;                                                        \
-            }                                                                           \
-            ptr = malloc (len * typeBytes);                                             \
-            if (readonly) {                                                             \
-                copyWithPadding(ptr, srcPtr, mSize, count);                             \
-                fnc(__VA_ARGS__);                                                       \
-            } else {                                                                    \
-                fnc(__VA_ARGS__);                                                       \
-                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
-            }                                                                           \
-            free(ptr);                                                                  \
-            ptr = srcPtr;                                                               \
-        } else {                                                                        \
-            fnc(__VA_ARGS__);                                                           \
-        }                                                                               \
-        _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, relFlag);           \
-        return;                                                                         \
-    case RS_TYPE_SIGNED_64:                                                             \
-    case RS_TYPE_UNSIGNED_64:                                                           \
-        len = _env->GetArrayLength((jlongArray)data);                                   \
-        ptr = _env->GetLongArrayElements((jlongArray)data, flag);                       \
-        typeBytes = 8;                                                                  \
-        if (usePadding) {                                                               \
-            srcPtr = ptr;                                                               \
-            len = len / 3 * 4;                                                          \
-            if (count == 0) {                                                           \
-                count = len / 4;                                                        \
-            }                                                                           \
-            ptr = malloc (len * typeBytes);                                             \
-            if (readonly) {                                                             \
-                copyWithPadding(ptr, srcPtr, mSize, count);                             \
-                fnc(__VA_ARGS__);                                                       \
-            } else {                                                                    \
-                fnc(__VA_ARGS__);                                                       \
-                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
-            }                                                                           \
-            free(ptr);                                                                  \
-            ptr = srcPtr;                                                               \
-        } else {                                                                        \
-            fnc(__VA_ARGS__);                                                           \
-        }                                                                               \
-        _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, relFlag);        \
-        return;                                                                         \
-    default:                                                                            \
-        break;                                                                          \
-    }                                                                                   \
-    UNUSED(len, ptr, srcPtr, typeBytes, relFlag);                                       \
-}
-
-
-class AutoJavaStringToUTF8 {
-public:
-    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
-        fCStr = env->GetStringUTFChars(str, NULL);
-        fLength = env->GetStringUTFLength(str);
-    }
-    ~AutoJavaStringToUTF8() {
-        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
-    }
-    const char* c_str() const { return fCStr; }
-    jsize length() const { return fLength; }
-
-private:
-    JNIEnv*     fEnv;
-    jstring     fJStr;
-    const char* fCStr;
-    jsize       fLength;
-};
-
-class AutoJavaStringArrayToUTF8 {
-public:
-    AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
-    : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
-        mCStrings = NULL;
-        mSizeArray = NULL;
-        if (stringsLength > 0) {
-            mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
-            mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
-            for (jsize ct = 0; ct < stringsLength; ct ++) {
-                jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
-                mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL);
-                mSizeArray[ct] = mEnv->GetStringUTFLength(s);
-            }
-        }
-    }
-    ~AutoJavaStringArrayToUTF8() {
-        for (jsize ct=0; ct < mStringsLength; ct++) {
-            jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
-            mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
-        }
-        free(mCStrings);
-        free(mSizeArray);
-    }
-    const char **c_str() const { return mCStrings; }
-    size_t *c_str_len() const { return mSizeArray; }
-    jsize length() const { return mStringsLength; }
-
-private:
-    JNIEnv      *mEnv;
-    jobjectArray mStrings;
-    const char **mCStrings;
-    size_t      *mSizeArray;
-    jsize        mStringsLength;
-};
-
-
-// ---------------------------------------------------------------------------
-static dispatchTable dispatchTab;
-// Incremental Support lib
-static dispatchTable dispatchTabInc;
-
-static jboolean nLoadSO(JNIEnv *_env, jobject _this, jboolean useNative, jint targetApi, jstring libPath) {
-    void* handle = NULL;
-    if (useNative) {
-        handle = dlopen("libRS.so", RTLD_LAZY | RTLD_LOCAL);
-    } else {
-        // For API 9+, dlopen the full path of libRSSupport.
-        if (libPath != NULL) {
-            const char * libPathJni = _env->GetStringUTFChars(libPath, JNI_FALSE);
-            handle = dlopen(libPathJni, RTLD_LAZY | RTLD_LOCAL);
-            _env->ReleaseStringUTFChars(libPath, libPathJni);
-        } else {
-            handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
-        }
-    }
-    if (handle == NULL) {
-        LOG_ERR("couldn't dlopen %s; librsjni version: %d", dlerror(), RS_JNI_VERSION);
-        return false;
-    }
-
-    if (loadSymbols(handle, dispatchTab, targetApi) == false) {
-        LOG_ERR("Dispatch table init failed! librsjni version: %d", RS_JNI_VERSION);
-        dlclose(handle);
-        return false;
-    }
-    LOG_API("Successfully loaded runtime");
-    return true;
-}
-
-static ioSuppDT ioDispatch;
-static jboolean nLoadIOSO(JNIEnv *_env, jobject _this) {
-    void* handleIO = NULL;
-    handleIO = dlopen("libRSSupportIO.so", RTLD_LAZY | RTLD_LOCAL);
-    if (handleIO == NULL) {
-        LOG_ERR("Couldn't load libRSSupportIO.so, librsjni version: %d", RS_JNI_VERSION);
-        return false;
-    }
-    if (loadIOSuppSyms(handleIO, ioDispatch) == false) {
-        LOG_ERR("libRSSupportIO init failed! librsjni version: %d", RS_JNI_VERSION);
-        return false;
-    }
-    return true;
-}
-
-// ---------------------------------------------------------------------------
-
-static void copyWithPadding(void* ptr, void* srcPtr, int mSize, int count) {
-    int sizeBytesPad = mSize * 4;
-    int sizeBytes = mSize * 3;
-    uint8_t *dst = static_cast<uint8_t *>(ptr);
-    uint8_t *src = static_cast<uint8_t *>(srcPtr);
-    for (int i = 0; i < count; i++) {
-        memcpy(dst, src, sizeBytes);
-        dst += sizeBytesPad;
-        src += sizeBytes;
-    }
-}
-
-static void copyWithUnPadding(void* ptr, void* srcPtr, int mSize, int count) {
-    int sizeBytesPad = mSize * 4;
-    int sizeBytes = mSize * 3;
-    uint8_t *dst = static_cast<uint8_t *>(ptr);
-    uint8_t *src = static_cast<uint8_t *>(srcPtr);
-    for (int i = 0; i < count; i++) {
-        memcpy(dst, src, sizeBytes);
-        dst += sizeBytes;
-        src += sizeBytesPad;
-    }
-}
-
-
-// ---------------------------------------------------------------------------
-
-static void
-nContextFinish(JNIEnv *_env, jobject _this, jlong con)
-{
-    LOG_API("nContextFinish, con(%p)", (RsContext)con);
-    dispatchTab.ContextFinish((RsContext)con);
-}
-
-static jlong
-nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID,
-               jlong returnValue, jlongArray fieldIDArray,
-               jlongArray valueArray, jintArray sizeArray,
-               jlongArray depClosureArray, jlongArray depFieldIDArray) {
-  jlong ret = 0;
-
-  jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
-  jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
-  jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
-  jsize values_length = _env->GetArrayLength(valueArray);
-  jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
-  jsize sizes_length = _env->GetArrayLength(sizeArray);
-  jlong* jDepClosures =
-      _env->GetLongArrayElements(depClosureArray, nullptr);
-  jsize depClosures_length = _env->GetArrayLength(depClosureArray);
-  jlong* jDepFieldIDs =
-      _env->GetLongArrayElements(depFieldIDArray, nullptr);
-  jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray);
-
-  size_t numValues, numDependencies;
-  RsScriptFieldID* fieldIDs;
-  RsClosure* depClosures;
-  RsScriptFieldID* depFieldIDs;
-
-  if (fieldIDs_length != values_length || values_length != sizes_length) {
-      LOG_ERR("Unmatched field IDs, values, and sizes in closure creation.");
-      goto exit;
-  }
-
-  numValues = (size_t)fieldIDs_length;
-
-  if (depClosures_length != depFieldIDs_length) {
-      LOG_ERR("Unmatched closures and field IDs for dependencies in closure creation.");
-      goto exit;
-  }
-
-  numDependencies = (size_t)depClosures_length;
-
-  if (numDependencies > numValues) {
-      LOG_ERR("Unexpected number of dependencies in closure creation");
-      goto exit;
-  }
-
-  if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
-      LOG_ERR("Too many arguments or globals in closure creation");
-      goto exit;
-  }
-
-  if (numValues > 0) {
-      fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
-      if (fieldIDs == nullptr) {
-          goto exit;
-      }
-  } else {
-      // numValues == 0
-      // alloca(0) implementation is platform dependent
-      fieldIDs = nullptr;
-  }
-
-  for (size_t i = 0; i < numValues; i++) {
-    fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
-  }
-
-  if (numDependencies > 0) {
-      depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies);
-      if (depClosures == nullptr) {
-          goto exit;
-      }
-
-      for (size_t i = 0; i < numDependencies; i++) {
-          depClosures[i] = (RsClosure)jDepClosures[i];
-      }
-
-      depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numDependencies);
-      if (depFieldIDs == nullptr) {
-          goto exit;
-      }
-
-      for (size_t i = 0; i < numDependencies; i++) {
-          depFieldIDs[i] = (RsClosure)jDepFieldIDs[i];
-      }
-  } else {
-      // numDependencies == 0
-      // alloca(0) implementation is platform dependent
-      depClosures = nullptr;
-      depFieldIDs = nullptr;
-  }
-
-  ret = (jlong)(uintptr_t)dispatchTab.ClosureCreate(
-      (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
-      fieldIDs, numValues, jValues, numValues,
-      (int*)jSizes, numValues,
-      depClosures, numDependencies,
-      depFieldIDs, numDependencies);
-
-exit:
-
-  _env->ReleaseLongArrayElements(depFieldIDArray, jDepFieldIDs, JNI_ABORT);
-  _env->ReleaseLongArrayElements(depClosureArray, jDepClosures, JNI_ABORT);
-  _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
-  _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
-  _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
-
-  return ret;
-}
-
-static jlong
-nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID,
-                     jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray,
-                     jintArray sizeArray) {
-  jlong ret = 0;
-
-  jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr);
-  jsize jParamLength = _env->GetArrayLength(paramArray);
-  jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
-  jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
-  jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
-  jsize values_length = _env->GetArrayLength(valueArray);
-  jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
-  jsize sizes_length = _env->GetArrayLength(sizeArray);
-
-  size_t numValues;
-  RsScriptFieldID* fieldIDs;
-
-  if (fieldIDs_length != values_length || values_length != sizes_length) {
-      LOG_ERR("Unmatched field IDs, values, and sizes in closure creation.");
-      goto exit;
-  }
-
-  numValues = (size_t) fieldIDs_length;
-
-  if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
-      LOG_ERR("Too many arguments or globals in closure creation");
-      goto exit;
-  }
-
-  fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
-  if (fieldIDs == nullptr) {
-      goto exit;
-  }
-
-  for (size_t i = 0; i < numValues; i++) {
-    fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
-  }
-
-  ret = (jlong)(uintptr_t)dispatchTab.InvokeClosureCreate(
-      (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength,
-      fieldIDs, numValues, jValues, numValues,
-      (int*)jSizes, numValues);
-
-exit:
-
-  _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
-  _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
-  _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
-  _env->ReleaseByteArrayElements(paramArray,      jParams,      JNI_ABORT);
-
-  return ret;
-}
-
-static void
-nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
-               jint index, jlong value, jint size) {
-  // Size is signed with -1 indicating the values is an Allocation
-  dispatchTab.ClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index,
-                  (uintptr_t)value, size);
-}
-
-static void
-nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
-                  jlong fieldID, jlong value, jint size) {
-  // Size is signed with -1 indicating the values is an Allocation
-  dispatchTab.ClosureSetGlobal((RsContext)con, (RsClosure)closureID,
-                     (RsScriptFieldID)fieldID, (int64_t)value, size);
-}
-
-static long
-nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name,
-                    jstring cacheDir, jlongArray closureArray) {
-  jlong ret = 0;
-
-  AutoJavaStringToUTF8 nameUTF(_env, name);
-  AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
-
-  jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr);
-  jsize numClosures = _env->GetArrayLength(closureArray);
-
-  RsClosure* closures;
-
-  if (numClosures > (jsize) RS_SCRIPT_GROUP_MAX_NUMBER_CLOSURES) {
-    LOG_ERR("Too many closures in script group");
-    goto exit;
-  }
-
-  closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures);
-  if (closures == nullptr) {
-      goto exit;
-  }
-
-  for (int i = 0; i < numClosures; i++) {
-    closures[i] = (RsClosure)jClosures[i];
-  }
-
-  ret = (jlong)(uintptr_t)dispatchTab.ScriptGroup2Create(
-      (RsContext)con, nameUTF.c_str(), nameUTF.length(),
-      cacheDirUTF.c_str(), cacheDirUTF.length(),
-      closures, numClosures);
-
-exit:
-
-  _env->ReleaseLongArrayElements(closureArray, jClosures, JNI_ABORT);
-
-  return ret;
-}
-
-static void
-nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) {
-  dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID);
-}
-
-static void
-nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
-{
-    LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
-    dispatchTab.ObjDestroy((RsContext)con, (void *)obj);
-}
-
-
-static void
-nScriptIntrinsicBLAS_Single(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
-                            jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
-                            jfloat alpha, jlong A, jlong B, jfloat beta, jlong C, jint incX, jint incY,
-                            jint KL, jint KU, jboolean mUseInc) {
-    RsBlasCall call;
-    memset(&call, 0, sizeof(call));
-    call.func = (RsBlasFunction)func;
-    call.transA = (RsBlasTranspose)TransA;
-    call.transB = (RsBlasTranspose)TransB;
-    call.side = (RsBlasSide)Side;
-    call.uplo = (RsBlasUplo)Uplo;
-    call.diag = (RsBlasDiag)Diag;
-    call.M = M;
-    call.N = N;
-    call.K = K;
-    call.alpha.f = alpha;
-    call.beta.f = beta;
-    call.incX = incX;
-    call.incY = incY;
-    call.KL = KL;
-    call.KU = KU;
-
-    RsAllocation in_allocs[3];
-    in_allocs[0] = (RsAllocation)A;
-    in_allocs[1] = (RsAllocation)B;
-    in_allocs[2] = (RsAllocation)C;
-
-    if (mUseInc) {
-        dispatchTab.ContextFinish((RsContext)con);
-        dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
-                                          in_allocs, NELEM(in_allocs), nullptr,
-                                          &call, sizeof(call), nullptr, 0);
-    } else {
-        dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
-                                       in_allocs, NELEM(in_allocs), nullptr,
-                                       &call, sizeof(call), nullptr, 0);
-    }
-}
-
-static void
-nScriptIntrinsicBLAS_Double(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
-                            jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
-                            jdouble alpha, jlong A, jlong B, jdouble beta, jlong C, jint incX, jint incY,
-                            jint KL, jint KU, jboolean mUseInc) {
-    RsBlasCall call;
-    memset(&call, 0, sizeof(call));
-    call.func = (RsBlasFunction)func;
-    call.transA = (RsBlasTranspose)TransA;
-    call.transB = (RsBlasTranspose)TransB;
-    call.side = (RsBlasSide)Side;
-    call.uplo = (RsBlasUplo)Uplo;
-    call.diag = (RsBlasDiag)Diag;
-    call.M = M;
-    call.N = N;
-    call.K = K;
-    call.alpha.d = alpha;
-    call.beta.d = beta;
-    call.incX = incX;
-    call.incY = incY;
-    call.KL = KL;
-    call.KU = KU;
-
-    RsAllocation in_allocs[3];
-    in_allocs[0] = (RsAllocation)A;
-    in_allocs[1] = (RsAllocation)B;
-    in_allocs[2] = (RsAllocation)C;
-
-    if (mUseInc) {
-        dispatchTab.ContextFinish((RsContext)con);
-        dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
-                                          in_allocs, NELEM(in_allocs), nullptr,
-                                          &call, sizeof(call), nullptr, 0);
-    } else {
-        dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
-                                        in_allocs, NELEM(in_allocs), nullptr,
-                                        &call, sizeof(call), nullptr, 0);
-    }
-}
-
-static void
-nScriptIntrinsicBLAS_Complex(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
-                             jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
-                             jfloat alphaX, jfloat alphaY, jlong A, jlong B, jfloat betaX,
-                             jfloat betaY, jlong C, jint incX, jint incY, jint KL, jint KU, jboolean mUseInc) {
-    RsBlasCall call;
-    memset(&call, 0, sizeof(call));
-    call.func = (RsBlasFunction)func;
-    call.transA = (RsBlasTranspose)TransA;
-    call.transB = (RsBlasTranspose)TransB;
-    call.side = (RsBlasSide)Side;
-    call.uplo = (RsBlasUplo)Uplo;
-    call.diag = (RsBlasDiag)Diag;
-    call.M = M;
-    call.N = N;
-    call.K = K;
-    call.alpha.c.r = alphaX;
-    call.alpha.c.i = alphaY;
-    call.beta.c.r = betaX;
-    call.beta.c.i = betaY;
-    call.incX = incX;
-    call.incY = incY;
-    call.KL = KL;
-    call.KU = KU;
-
-    RsAllocation in_allocs[3];
-    in_allocs[0] = (RsAllocation)A;
-    in_allocs[1] = (RsAllocation)B;
-    in_allocs[2] = (RsAllocation)C;
-
-
-    if (mUseInc) {
-        dispatchTab.ContextFinish((RsContext)con);
-        dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
-                                          in_allocs, NELEM(in_allocs), nullptr,
-                                          &call, sizeof(call), nullptr, 0);
-    } else {
-        dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
-                                       in_allocs, NELEM(in_allocs), nullptr,
-                                       &call, sizeof(call), nullptr, 0);
-    }
-}
-
-static void
-nScriptIntrinsicBLAS_Z(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
-                       jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
-                       jdouble alphaX, jdouble alphaY, jlong A, jlong B, jdouble betaX,
-                       jdouble betaY, jlong C, jint incX, jint incY, jint KL, jint KU, jboolean mUseInc) {
-    RsBlasCall call;
-    memset(&call, 0, sizeof(call));
-    call.func = (RsBlasFunction)func;
-    call.transA = (RsBlasTranspose)TransA;
-    call.transB = (RsBlasTranspose)TransB;
-    call.side = (RsBlasSide)Side;
-    call.uplo = (RsBlasUplo)Uplo;
-    call.diag = (RsBlasDiag)Diag;
-    call.M = M;
-    call.N = N;
-    call.K = K;
-    call.alpha.z.r = alphaX;
-    call.alpha.z.i = alphaY;
-    call.beta.z.r = betaX;
-    call.beta.z.i = betaY;
-    call.incX = incX;
-    call.incY = incY;
-    call.KL = KL;
-    call.KU = KU;
-
-    RsAllocation in_allocs[3];
-    in_allocs[0] = (RsAllocation)A;
-    in_allocs[1] = (RsAllocation)B;
-    in_allocs[2] = (RsAllocation)C;
-
-
-    if (mUseInc) {
-        dispatchTab.ContextFinish((RsContext)con);
-        dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
-                                          in_allocs, NELEM(in_allocs), nullptr,
-                                          &call, sizeof(call), nullptr, 0);
-    } else {
-        dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
-                                        in_allocs, NELEM(in_allocs), nullptr,
-                                        &call, sizeof(call), nullptr, 0);
-    }
-}
-
-
-static void
-nScriptIntrinsicBLAS_BNNM(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint M, jint N, jint K,
-                          jlong A, jint a_offset, jlong B, jint b_offset, jlong C, jint c_offset,
-                          jint c_mult_int, jboolean mUseInc) {
-    RsBlasCall call;
-    memset(&call, 0, sizeof(call));
-    call.func = RsBlas_bnnm;
-    call.M = M;
-    call.N = N;
-    call.K = K;
-    call.a_offset = a_offset & 0xFF;
-    call.b_offset = b_offset & 0xFF;
-    call.c_offset = c_offset;
-    call.c_mult_int = c_mult_int;
-
-    RsAllocation in_allocs[3];
-    in_allocs[0] = (RsAllocation)A;
-    in_allocs[1] = (RsAllocation)B;
-    in_allocs[2] = (RsAllocation)C;
-
-    if (mUseInc) {
-        dispatchTab.ContextFinish((RsContext)con);
-        dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
-                                          in_allocs, NELEM(in_allocs), nullptr,
-                                          &call, sizeof(call), nullptr, 0);
-    } else {
-        dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
-                                        in_allocs, NELEM(in_allocs), nullptr,
-                                        &call, sizeof(call), nullptr, 0);
-    }
-}
-// ---------------------------------------------------------------------------
-static jlong
-nDeviceCreate(JNIEnv *_env, jobject _this)
-{
-    LOG_API("nDeviceCreate");
-    return (jlong)(uintptr_t)dispatchTab.DeviceCreate();
-}
-
-static void
-nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
-{
-    LOG_API("nDeviceDestroy");
-    return dispatchTab.DeviceDestroy((RsDevice)dev);
-}
-
-static void
-nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
-{
-    LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
-    return dispatchTab.DeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
-}
-
-static jlong
-nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer,
-               jint ct, jstring nativeLibDirJava)
-{
-    LOG_API("nContextCreate");
-    // Access the NativeLibDir in the Java Context.
-    const char * nativeLibDir = _env->GetStringUTFChars(nativeLibDirJava, JNI_FALSE);
-    size_t length = (size_t)_env->GetStringUTFLength(nativeLibDirJava);
-
-    jlong id = (jlong)(uintptr_t)dispatchTab.ContextCreate((RsDevice)dev, ver,
-                                                           sdkVer,
-                                                           (RsContextType)ct, 0);
-    if (dispatchTab.SetNativeLibDir) {
-        dispatchTab.SetNativeLibDir((RsContext)id, nativeLibDir, length);
-    }
-
-    _env->ReleaseStringUTFChars(nativeLibDirJava, nativeLibDir);
-    return id;
-}
-
-
-static void
-nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
-{
-    LOG_API("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
-    dispatchTab.ContextSetPriority((RsContext)con, p);
-}
-
-
-
-static void
-nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
-{
-    LOG_API("nContextDestroy, con(%p)", (RsContext)con);
-    dispatchTab.ContextDestroy((RsContext)con);
-}
-
-static void
-nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
-{
-    LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
-    dispatchTab.ContextDump((RsContext)con, bits);
-}
-
-
-static jstring
-nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
-{
-    LOG_API("nContextGetErrorMessage, con(%p)", (RsContext)con);
-    char buf[1024];
-
-    size_t receiveLen;
-    uint32_t subID;
-    int id = dispatchTab.ContextGetMessage((RsContext)con,
-                                           buf, sizeof(buf),
-                                           &receiveLen, sizeof(receiveLen),
-                                           &subID, sizeof(subID));
-    if (!id && receiveLen) {
-        //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
-        //            "message receive buffer too small.  %zu", receiveLen);
-    }
-    return _env->NewStringUTF(buf);
-}
-
-static jint
-nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
-    jint *ptr = _env->GetIntArrayElements(data, NULL);
-    size_t receiveLen;
-    uint32_t subID;
-    int id = dispatchTab.ContextGetMessage((RsContext)con,
-                                           ptr, len * 4,
-                                           &receiveLen, sizeof(receiveLen),
-                                           &subID, sizeof(subID));
-    if (!id && receiveLen) {
-        //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
-        //            "message receive buffer too small.  %zu", receiveLen);
-    }
-    _env->ReleaseIntArrayElements(data, ptr, 0);
-    return (jint)id;
-}
-
-static jint
-nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
-{
-    LOG_API("nContextPeekMessage, con(%p)", (RsContext)con);
-    jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
-    size_t receiveLen;
-    uint32_t subID;
-    int id = dispatchTab.ContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
-                                  &subID, sizeof(subID));
-    auxDataPtr[0] = (jint)subID;
-    auxDataPtr[1] = (jint)receiveLen;
-    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
-    return (jint)id;
-}
-
-static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
-{
-    LOG_API("nContextInitToClient, con(%p)", (RsContext)con);
-    dispatchTab.ContextInitToClient((RsContext)con);
-}
-
-static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
-{
-    LOG_API("nContextDeinitToClient, con(%p)", (RsContext)con);
-    dispatchTab.ContextDeinitToClient((RsContext)con);
-}
-
-static void
-nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
-{
-    jint *ptr = NULL;
-    jint len = 0;
-    if (data) {
-        len = _env->GetArrayLength(data);
-        ptr = _env->GetIntArrayElements(data, NULL);
-    }
-    LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
-    dispatchTab.ContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
-    if (data) {
-        _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
-    }
-}
-
-
-
-static jlong
-nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind,
-               jboolean norm, jint size)
-{
-    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
-            type, kind, norm, size);
-    return (jlong)(uintptr_t)dispatchTab.ElementCreate((RsContext)con,
-                                                       (RsDataType)type,
-                                                       (RsDataKind)kind,
-                                                       norm, size);
-}
-
-static jlong
-nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
-                jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
-{
-    int fieldCount = _env->GetArrayLength(_ids);
-    LOG_API("nElementCreate2, con(%p)", (RsContext)con);
-
-    jlong *jIds = _env->GetLongArrayElements(_ids, NULL);
-    jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
-
-    RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
-    uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
-
-    for(int i = 0; i < fieldCount; i ++) {
-        ids[i] = (RsElement)jIds[i];
-        arraySizes[i] = (uint32_t)jArraySizes[i];
-    }
-
-    AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
-
-    const char **nameArray = names.c_str();
-    size_t *sizeArray = names.c_str_len();
-
-    jlong id = (jlong)(uintptr_t)dispatchTab.ElementCreate2((RsContext)con, (RsElement *)ids,
-                                                            fieldCount, nameArray,
-                                                            fieldCount * sizeof(size_t),  sizeArray,
-                                                            (const uint32_t *)arraySizes, fieldCount);
-
-    free(ids);
-    free(arraySizes);
-    _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
-    _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
-    return id;
-}
-
-
-
-
-static void
-nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
-                       jlongArray _IDs,
-                       jobjectArray _names,
-                       jintArray _arraySizes)
-{
-    uint32_t dataSize = _env->GetArrayLength(_IDs);
-    LOG_API("nElementGetSubElements, con(%p)", (RsContext)con);
-
-    uintptr_t *ids = (uintptr_t *)malloc(dataSize * sizeof(uintptr_t));
-    const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
-    uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
-
-    dispatchTab.ElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes,
-                                      (uint32_t)dataSize);
-
-    for(uint32_t i = 0; i < dataSize; i++) {
-        const jlong id = (jlong)(uintptr_t)ids[i];
-        const jint arraySize = (jint)arraySizes[i];
-        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
-        _env->SetLongArrayRegion(_IDs, i, 1, &id);
-        _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
-    }
-
-    free(ids);
-    free(names);
-    free(arraySizes);
-}
-
-// -----------------------------------
-
-static jlong
-nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
-            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
-{
-    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
-            (RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv);
-
-    return (jlong)(uintptr_t)dispatchTab.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy,
-                                                    dimz, mips, faces, yuv);
-}
-
-// -----------------------------------
-
-static jlong
-nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage,
-                       jlong pointer)
-{
-    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
-            (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
-    return (jlong)(uintptr_t) dispatchTab.AllocationCreateTyped((RsContext)con, (RsType)type,
-                                                                (RsAllocationMipmapControl)mips,
-                                                                (uint32_t)usage, (uintptr_t)pointer);
-}
-
-static void
-nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
-{
-    LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a, bits);
-    dispatchTab.AllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
-}
-
-static void
-nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
-{
-    ioDispatch.sAllocationSetSurface(_env, _this, (RsContext)con, (RsAllocation)alloc, sur, dispatchTab);
-}
-
-static void
-nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
-{
-    dispatchTab.AllocationIoSend((RsContext)con, (RsAllocation)alloc);
-}
-
-static void
-nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
-{
-    LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
-    dispatchTab.AllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
-}
-
-static size_t GetBitmapSize(JNIEnv *env, jobject jbitmap) {
-    AndroidBitmapInfo info;
-    memset(&info, 0, sizeof(info));
-    AndroidBitmap_getInfo(env, jbitmap, &info);
-    size_t s = info.width * info.height;
-    switch (info.format) {
-        case ANDROID_BITMAP_FORMAT_RGBA_8888: s *= 4; break;
-        case ANDROID_BITMAP_FORMAT_RGB_565: s *= 2; break;
-        case ANDROID_BITMAP_FORMAT_RGBA_4444: s *= 2; break;
-    }
-    return s;
-}
-
-static jlong
-nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
-                            jobject jbitmap, jint usage)
-{
-    jlong id = 0;
-    void *pixels = NULL;
-    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
-
-    if (pixels != NULL) {
-        id = (jlong)(uintptr_t)dispatchTab.AllocationCreateFromBitmap((RsContext)con,
-                                                                      (RsType)type,
-                                                                      (RsAllocationMipmapControl)mip,
-                                                                      pixels,
-                                                                      GetBitmapSize(_env, jbitmap),
-                                                                      usage);
-        AndroidBitmap_unlockPixels(_env, jbitmap);
-    }
-    return id;
-}
-
-static jlong
-nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
-                                        jint mip, jobject jbitmap, jint usage)
-{
-    jlong id = 0;
-    void *pixels = NULL;
-    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
-
-    if (pixels != NULL) {
-        id = (jlong)(uintptr_t)dispatchTab.AllocationCreateTyped((RsContext)con,
-                                                                 (RsType)type,
-                                                                 (RsAllocationMipmapControl)mip,
-                                                                 (uint32_t)usage,
-                                                                 (uintptr_t)pixels);
-        AndroidBitmap_unlockPixels(_env, jbitmap);
-    }
-    return id;
-}
-
-static jlong
-nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type,
-                                jint mip, jobject jbitmap, jint usage)
-{
-    void *pixels = NULL;
-    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
-
-    jlong id = 0;
-    if (pixels != NULL) {
-        id = (jlong)(uintptr_t)dispatchTab.AllocationCubeCreateFromBitmap((RsContext)con,
-                                                                          (RsType)type,
-                                                                          (RsAllocationMipmapControl)mip,
-                                                                          pixels,
-                                                                          GetBitmapSize(_env, jbitmap),
-                                                                          usage);
-        AndroidBitmap_unlockPixels(_env, jbitmap);
-    }
-    return id;
-}
-
-static void
-nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
-{
-    AndroidBitmapInfo info;
-    memset(&info, 0, sizeof(info));
-    AndroidBitmap_getInfo(_env, jbitmap, &info);
-
-    void *pixels = NULL;
-    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
-
-    if (pixels != NULL) {
-        dispatchTab.Allocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0, 0,
-                                     RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, info.width,
-                                     info.height, pixels, GetBitmapSize(_env, jbitmap), 0);
-        AndroidBitmap_unlockPixels(_env, jbitmap);
-    }
-}
-
-static void
-nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
-{
-    AndroidBitmapInfo info;
-    memset(&info, 0, sizeof(info));
-    AndroidBitmap_getInfo(_env, jbitmap, &info);
-
-    void *pixels = NULL;
-    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
-
-    if (pixels != NULL) {
-        dispatchTab.AllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, pixels,
-                                           GetBitmapSize(_env, jbitmap));
-        AndroidBitmap_unlockPixels(_env, jbitmap);
-    }
-    //bitmap.notifyPixelsChanged();
-}
-
-// Copies from the Java object data into the Allocation pointed to by _alloc.
-static void
-nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
-                  jint count, jobject data, jint sizeBytes, jint dataType, jint mSize,
-                  jboolean usePadding)
-{
-    RsAllocation *alloc = (RsAllocation *)_alloc;
-    LOG_API("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
-            "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes,
-            dataType);
-    PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation1DData, true,
-                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
-}
-
-
-static void
-nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint xoff,
-                         jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
-{
-    LOG_API("nAllocationElementData1D, con(%p), alloc(%p), xoff(%i), comp(%i), len(%i), "
-            "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, compIdx,
-            _env->GetArrayLength(data),
-            sizeBytes);
-    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
-    dispatchTab.Allocation1DElementData((RsContext)con, (RsAllocation)alloc, xoff,
-                                        lod, ptr, sizeBytes, compIdx);
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
-}
-
-/*
-static void
-nAllocationElementData(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
-                       jint xoff, jint yoff, jint zoff,
-                       jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocationElementData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
-            "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
-            sizeBytes);
-    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
-    dispatchTab.AllocationElementData((RsContext)con, (RsAllocation)alloc,
-                                      xoff, yoff, zoff,
-                                      lod, ptr, sizeBytes, compIdx);
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
-}
-*/
-
-// Copies from the Java object data into the Allocation pointed to by _alloc.
-static void
-nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
-                  jint w, jint h, jobject data, jint sizeBytes, jint dataType, jint mSize,
-                  jboolean usePadding)
-{
-    RsAllocation *alloc = (RsAllocation *)_alloc;
-    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
-    LOG_API("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
-            "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
-    int count = w * h;
-    PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation2DData, true,
-                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
-}
-
-static void
-nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
-                        jlong dstAlloc, jint dstXoff, jint dstYoff,
-                        jint dstMip, jint dstFace,
-                        jint width, jint height,
-                        jlong srcAlloc, jint srcXoff, jint srcYoff,
-                        jint srcMip, jint srcFace)
-{
-    LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
-            " dstMip(%i), dstFace(%i), width(%i), height(%i),"
-            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
-            (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
-            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
-
-    dispatchTab.AllocationCopy2DRange((RsContext)con,
-                                      (RsAllocation)dstAlloc,
-                                      dstXoff, dstYoff,
-                                      dstMip, dstFace,
-                                      width, height,
-                                      (RsAllocation)srcAlloc,
-                                      srcXoff, srcYoff,
-                                      srcMip, srcFace);
-}
-
-// Copies from the Java object data into the Allocation pointed to by _alloc.
-static void
-nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
-                  jint w, jint h, jint d, jobject data, jint sizeBytes, jint dataType,
-                  jint mSize, jboolean usePadding)
-{
-    RsAllocation *alloc = (RsAllocation *)_alloc;
-    LOG_API("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
-            " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
-            lod, w, h, d, sizeBytes);
-    int count = w * h * d;
-    PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DData, true,
-                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
-}
-
-static void
-nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
-                        jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
-                        jint dstMip,
-                        jint width, jint height, jint depth,
-                        jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
-                        jint srcMip)
-{
-    LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
-            " dstMip(%i), width(%i), height(%i),"
-            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
-            (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
-            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
-
-    dispatchTab.AllocationCopy3DRange((RsContext)con,
-                                      (RsAllocation)dstAlloc,
-                                      dstXoff, dstYoff, dstZoff, dstMip,
-                                      width, height, depth,
-                                      (RsAllocation)srcAlloc,
-                                      srcXoff, srcYoff, srcZoff, srcMip);
-}
-
-// Copies from the Allocation pointed to by _alloc into the Java object data.
-static void
-nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, jint dataType,
-                jint mSize, jboolean usePadding)
-{
-    RsAllocation *alloc = (RsAllocation *)_alloc;
-    LOG_API("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
-    int count = 0;
-    PER_ARRAY_TYPE(0, dispatchTab.AllocationRead, false,
-                   (RsContext)con, alloc, ptr, len * typeBytes);
-}
-
-// Copies from the Allocation pointed to by _alloc into the Java object data.
-static void
-nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
-                  jint count, jobject data, jint sizeBytes, jint dataType,
-                  jint mSize, jboolean usePadding)
-{
-    RsAllocation *alloc = (RsAllocation *)_alloc;
-    LOG_API("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
-              "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType);
-    PER_ARRAY_TYPE(0, dispatchTab.Allocation1DRead, false,
-                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
-}
-
-// Copies from the Element in the Allocation pointed to by _alloc into the Java array data.
-/*
-static void
-nAllocationElementRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc,
-                       jint xoff, jint yoff, jint zoff,
-                       jint lod, jint compIdx, jobject data, jint sizeBytes)
-{
-    jint len = _env->GetArrayLength(data);
-    LOG_API("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
-            "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
-            sizeBytes);
-    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
-    dispatchTab.AllocationElementRead((RsContext)con, (RsAllocation)alloc,
-                                      xoff, yoff, zoff,
-                                      lod, ptr, sizeBytes, compIdx);
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
-}
-*/
-
-// Copies from the Allocation pointed to by _alloc into the Java object data.
-static void
-nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
-                  jint w, jint h, jobject data, jint sizeBytes, jint dataType,
-                  jint mSize, jboolean usePadding)
-{
-    RsAllocation *alloc = (RsAllocation *)_alloc;
-    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
-    LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
-              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
-    int count = w * h;
-    PER_ARRAY_TYPE(0, dispatchTab.Allocation2DRead, false,
-                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
-}
-
-// Copies from the Allocation pointed to by _alloc into the Java object data.
-/*
-static void
-nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
-                  jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
-                  jint mSize, jboolean usePadding)
-{
-    RsAllocation *alloc = (RsAllocation *)_alloc;
-    LOG_API("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
-            " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
-            lod, w, h, d, sizeBytes);
-    int count = w * h * d;
-    PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DRead, false,
-                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
-}
-*/
-
-static jlong
-nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
-{
-    LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
-    return (jlong)(uintptr_t) dispatchTab.AllocationGetType((RsContext)con, (RsAllocation)a);
-}
-
-static void
-nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
-{
-    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
-            (RsAllocation)alloc, dimX);
-    dispatchTab.AllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
-}
-
-// -----------------------------------
-
-static void
-nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot, jboolean mUseInc)
-{
-    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)",
-            (RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
-    if (mUseInc) {
-        dispatchTabInc.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
-    } else {
-        dispatchTab.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
-    }
-}
-
-static void
-nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val, jboolean mUseInc)
-{
-    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
-            (void *)script, slot, val);
-    if (mUseInc) {
-        dispatchTabInc.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
-    } else {
-        dispatchTab.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
-    }
-}
-
-static void
-nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
-{
-    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
-            (void *)script, slot, val);
-    if (mUseInc) {
-        dispatchTabInc.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
-    } else {
-        dispatchTab.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
-    }
-}
-
-static void
-nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
-{
-    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", (RsContext)con,
-            (void *)script, slot, val);
-    if (mUseInc) {
-        dispatchTabInc.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
-    } else {
-        dispatchTab.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
-    }
-}
-
-static void
-nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val, jboolean mUseInc)
-{
-    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con,
-            (void *)script, slot, val);
-    if (mUseInc) {
-        dispatchTabInc.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
-    } else {
-        dispatchTab.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
-    }
-}
-
-static void
-nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val, jboolean mUseInc)
-{
-    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con,
-            (void *)script, slot, val);
-    if (mUseInc) {
-        dispatchTabInc.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
-    } else {
-        dispatchTab.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
-    }
-}
-
-static void
-nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
-{
-    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
-    jint len = _env->GetArrayLength(data);
-    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    if (mUseInc) {
-        dispatchTabInc.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
-    } else {
-        dispatchTab.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
-    }
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
-                jlong elem, jintArray dims, jboolean mUseInc)
-{
-    LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
-    jint len = _env->GetArrayLength(data);
-    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
-    jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
-    if (mUseInc) {
-        dispatchTabInc.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
-                                      (const uint32_t *)dimsPtr, dimsLen);
-    } else {
-        dispatchTab.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
-                                   (const uint32_t *)dimsPtr, dimsLen);
-    }
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
-    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
-}
-
-
-static void
-nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone, jboolean mUseInc)
-{
-    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", (RsContext)con,
-            (void *)script, (const char *)timeZone);
-
-    jint length = _env->GetArrayLength(timeZone);
-    jbyte* timeZone_ptr;
-    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
-    if (mUseInc) {
-        dispatchTabInc.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
-    } else {
-        dispatchTab.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
-    }
-
-    if (timeZone_ptr) {
-        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
-    }
-}
-
-static void
-nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot, jboolean mUseInc)
-{
-    LOG_API("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
-    if (mUseInc) {
-        dispatchTabInc.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
-    } else {
-        dispatchTab.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
-    }
-}
-
-static void
-nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
-{
-    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
-    jint len = _env->GetArrayLength(data);
-    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
-    if (mUseInc) {
-        dispatchTabInc.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
-    } else {
-        dispatchTab.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
-    }
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
-               jlong script, jint slot, jlong ain, jlong aout, jboolean mUseInc)
-{
-    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
-    if (mUseInc) {
-        dispatchTab.ContextFinish((RsContext)con);
-        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
-                                     (RsAllocation)ain, (RsAllocation)aout,
-                                     NULL, 0, NULL, 0);
-    } else {
-        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
-                                  (RsAllocation)ain, (RsAllocation)aout,
-                                  NULL, 0, NULL, 0);
-    }
-}
-
-static void
-nScriptForEachV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
-                jlong script, jint slot, jlong ain, jlong aout, jbyteArray params, jboolean mUseInc)
-{
-    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
-    jint len = _env->GetArrayLength(params);
-    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
-    if (mUseInc) {
-        dispatchTab.ContextFinish((RsContext)con);
-        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
-                                     (RsAllocation)ain, (RsAllocation)aout,
-                                     ptr, len, NULL, 0);
-    } else {
-        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
-                                  (RsAllocation)ain, (RsAllocation)aout,
-                                  ptr, len, NULL, 0);
-    }
-    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
-}
-
-static void
-nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
-                      jlong script, jint slot, jlong ain, jlong aout,
-                      jint xstart, jint xend,
-                      jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
-{
-    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
-    RsScriptCall sc;
-    sc.xStart = xstart;
-    sc.xEnd = xend;
-    sc.yStart = ystart;
-    sc.yEnd = yend;
-    sc.zStart = zstart;
-    sc.zEnd = zend;
-    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
-    sc.arrayStart = 0;
-    sc.arrayEnd = 0;
-    sc.array2Start = 0;
-    sc.array2End = 0;
-    sc.array3Start = 0;
-    sc.array3End = 0;
-    sc.array4Start = 0;
-    sc.array4End = 0;
-    if (mUseInc) {
-        dispatchTab.ContextFinish((RsContext)con);
-        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
-                                     (RsAllocation)ain, (RsAllocation)aout,
-                                     NULL, 0, &sc, sizeof(sc));
-    } else {
-        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
-                                  (RsAllocation)ain, (RsAllocation)aout,
-                                  NULL, 0, &sc, sizeof(sc));
-    }
-}
-
-static void
-nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
-                       jlong script, jint slot, jlong ain, jlong aout,
-                       jbyteArray params, jint xstart, jint xend,
-                       jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
-{
-    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
-    jint len = _env->GetArrayLength(params);
-    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
-    RsScriptCall sc;
-    sc.xStart = xstart;
-    sc.xEnd = xend;
-    sc.yStart = ystart;
-    sc.yEnd = yend;
-    sc.zStart = zstart;
-    sc.zEnd = zend;
-    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
-    sc.arrayStart = 0;
-    sc.arrayEnd = 0;
-    sc.array2Start = 0;
-    sc.array2End = 0;
-    sc.array3Start = 0;
-    sc.array3End = 0;
-    sc.array4Start = 0;
-    sc.array4End = 0;
-    if (mUseInc) {
-        dispatchTab.ContextFinish((RsContext)con);
-        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
-                                     (RsAllocation)ain, (RsAllocation)aout,
-                                     ptr, len, &sc, sizeof(sc));
-    } else {
-        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
-                                  (RsAllocation)ain, (RsAllocation)aout,
-                                  ptr, len, &sc, sizeof(sc));
-    }
-    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
-}
-
-static void
-nScriptForEachMulti(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
-                    jlongArray ains, jlong aout, jbyteArray params,
-                    jintArray limits)
-{
-    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
-
-    jint   in_len = 0;
-    jlong *in_ptr = nullptr;
-
-    RsAllocation *in_allocs = nullptr;
-
-    if (ains != nullptr) {
-        in_len = _env->GetArrayLength(ains);
-        if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
-            LOG_ERR("Too many arguments in kernel launch.");
-            // TODO (b/20758983): Report back to Java and throw an exception
-            return;
-        }
-
-        // TODO (b/20760800): Check in_ptr is not null
-        in_ptr = _env->GetLongArrayElements(ains, nullptr);
-        if (sizeof(RsAllocation) == sizeof(jlong)) {
-            in_allocs = (RsAllocation*)in_ptr;
-
-        } else {
-            // Convert from 64-bit jlong types to the native pointer type.
-
-            in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
-            if (in_allocs == nullptr) {
-                LOG_ERR("Failed launching kernel for lack of memory.");
-                _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
-                return;
-            }
-
-            for (int index = in_len; --index >= 0;) {
-                in_allocs[index] = (RsAllocation)in_ptr[index];
-            }
-        }
-    }
-
-    jint   param_len = 0;
-    jbyte *param_ptr = nullptr;
-
-    if (params != nullptr) {
-        param_len = _env->GetArrayLength(params);
-        param_ptr = _env->GetByteArrayElements(params, nullptr);
-    }
-
-    RsScriptCall sc, *sca = nullptr;
-    uint32_t sc_size = 0;
-
-    jint  limit_len = 0;
-    jint *limit_ptr = nullptr;
-
-    if (limits != nullptr) {
-        limit_len = _env->GetArrayLength(limits);
-        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
-
-        if (limit_len != 6) {
-            LOG_ERR("LaunchOptions cannot be recognized.");
-            goto exit;
-        }
-
-        sc.xStart     = limit_ptr[0];
-        sc.xEnd       = limit_ptr[1];
-        sc.yStart     = limit_ptr[2];
-        sc.yEnd       = limit_ptr[3];
-        sc.zStart     = limit_ptr[4];
-        sc.zEnd       = limit_ptr[5];
-        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
-        sc.arrayStart = 0;
-        sc.arrayEnd = 0;
-        sc.array2Start = 0;
-        sc.array2End = 0;
-        sc.array3Start = 0;
-        sc.array3End = 0;
-        sc.array4Start = 0;
-        sc.array4End = 0;
-
-        sca = &sc;
-    }
-
-    dispatchTabInc.ScriptForEachMulti((RsContext)con, (RsScript)script, slot,
-                                      in_allocs, in_len, (RsAllocation)aout,
-                                      param_ptr, param_len, sca, sc_size);
-
-exit:
-
-    if (ains != nullptr) {
-        _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
-    }
-
-    if (params != nullptr) {
-        _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
-    }
-
-    if (limits != nullptr) {
-        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
-    }
-}
-
-static void
-nScriptReduce(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
-              jlongArray ains, jlong aout, jintArray limits)
-{
-    LOG_API("nScriptReduce, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
-
-    if (ains == nullptr) {
-        LOG_ERR("At least one input required.");
-        // TODO (b/20758983): Report back to Java and throw an exception
-        return;
-    }
-    jint in_len = _env->GetArrayLength(ains);
-    if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
-        LOG_ERR("Too many arguments in kernel launch.");
-        // TODO (b/20758983): Report back to Java and throw an exception
-        return;
-    }
-
-    jlong *in_ptr = _env->GetLongArrayElements(ains, nullptr);
-    if (in_ptr == nullptr) {
-        LOG_ERR("Failed to get Java array elements");
-        // TODO (b/20758983): Report back to Java and throw an exception
-        return;
-    }
-
-    RsAllocation *in_allocs = nullptr;
-    if (sizeof(RsAllocation) == sizeof(jlong)) {
-        in_allocs = (RsAllocation*)in_ptr;
-    } else {
-        // Convert from 64-bit jlong types to the native pointer type.
-
-        in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
-        if (in_allocs == nullptr) {
-            LOG_ERR("Failed launching kernel for lack of memory.");
-            // TODO (b/20758983): Report back to Java and throw an exception
-            _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
-            return;
-        }
-
-        for (int index = in_len; --index >= 0;) {
-            in_allocs[index] = (RsAllocation)in_ptr[index];
-        }
-    }
-
-    RsScriptCall sc, *sca = nullptr;
-    uint32_t sc_size = 0;
-
-    jint  limit_len = 0;
-    jint *limit_ptr = nullptr;
-
-    if (limits != nullptr) {
-        limit_len = _env->GetArrayLength(limits);
-        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
-        if (limit_ptr == nullptr) {
-            LOG_ERR("Failed to get Java array elements");
-            // TODO (b/20758983): Report back to Java and throw an exception
-            _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
-            return;
-        }
-
-        if (limit_len != 6) {
-            LOG_ERR("LaunchOptions cannot be recognized");
-            // TODO (b/20758983): Report back to Java and throw an exception
-            _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
-            return;
-        }
-
-        sc.xStart     = limit_ptr[0];
-        sc.xEnd       = limit_ptr[1];
-        sc.yStart     = limit_ptr[2];
-        sc.yEnd       = limit_ptr[3];
-        sc.zStart     = limit_ptr[4];
-        sc.zEnd       = limit_ptr[5];
-        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
-        sc.arrayStart = 0;
-        sc.arrayEnd = 0;
-        sc.array2Start = 0;
-        sc.array2End = 0;
-        sc.array3Start = 0;
-        sc.array3End = 0;
-        sc.array4Start = 0;
-        sc.array4End = 0;
-
-        sca = &sc;
-        sc_size = sizeof(sc);
-    }
-
-    dispatchTab.ScriptReduce((RsContext)con, (RsScript)script, slot,
-                             in_allocs, in_len, (RsAllocation)aout,
-                             sca, sc_size);
-
-    _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
-
-    if (limits != nullptr) {
-        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
-    }
-}
-
-// -----------------------------------
-
-static jlong
-nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
-               jstring resName, jstring cacheDir,
-               jbyteArray scriptRef, jint length)
-{
-    LOG_API("nScriptCCreate, con(%p)", (RsContext)con);
-
-    AutoJavaStringToUTF8 resNameUTF(_env, resName);
-    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
-    jlong ret = 0;
-    jbyte* script_ptr = NULL;
-    jint _exception = 0;
-    jint remaining;
-    if (!scriptRef) {
-        _exception = 1;
-        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
-        goto exit;
-    }
-    if (length < 0) {
-        _exception = 1;
-        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
-        goto exit;
-    }
-    remaining = _env->GetArrayLength(scriptRef);
-    if (remaining < length) {
-        _exception = 1;
-        //jniThrowException(_env, "java/lang/IllegalArgumentException",
-        //        "length > script.length - offset");
-        goto exit;
-    }
-    script_ptr = (jbyte *)
-        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
-
-    //rsScriptCSetText(con, (const char *)script_ptr, length);
-
-    ret = (jlong)(uintptr_t)dispatchTab.ScriptCCreate((RsContext)con,
-                                                      resNameUTF.c_str(), resNameUTF.length(),
-                                                      cacheDirUTF.c_str(), cacheDirUTF.length(),
-                                                      (const char *)script_ptr, length);
-
-exit:
-    if (script_ptr) {
-        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
-                _exception ? JNI_ABORT: 0);
-    }
-
-    return (jlong)(uintptr_t)ret;
-}
-
-static jlong
-nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid, jboolean mUseInc)
-{
-    LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
-    if (mUseInc) {
-        return (jlong)(uintptr_t)dispatchTabInc.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
-    } else {
-        return (jlong)(uintptr_t)dispatchTab.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
-    }
-}
-
-static jlong
-nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig, jboolean mUseInc)
-{
-    LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
-            (void *)sid, slot, sig);
-    if (mUseInc) {
-        return (jlong)(uintptr_t)dispatchTabInc.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
-                                                                     slot, sig);
-    } else {
-        return (jlong)(uintptr_t)dispatchTab.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
-                                                                  slot, sig);
-    }
-}
-
-static jlong
-nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
-{
-    LOG_API("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i), sig(%i)", con,
-            (void *)sid, slot);
-    return (jlong)dispatchTab.ScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
-}
-
-static jlong
-nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jboolean mUseInc)
-{
-    LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
-    if (mUseInc) {
-        return (jlong)(uintptr_t)dispatchTabInc.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
-    } else {
-        return (jlong)(uintptr_t)dispatchTab.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
-    }
-}
-
-static jlong
-nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
-    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
-{
-    LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con);
-
-    jlong id = 0;
-
-    RsScriptKernelID* kernelsPtr;
-    jint kernelsLen = _env->GetArrayLength(_kernels);
-    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
-
-    RsScriptKernelID* srcPtr;
-    jint srcLen = _env->GetArrayLength(_src);
-    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
-
-    RsScriptKernelID* dstkPtr;
-    jint dstkLen = _env->GetArrayLength(_dstk);
-    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
-
-    RsScriptKernelID* dstfPtr;
-    jint dstfLen = _env->GetArrayLength(_dstf);
-    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
-
-    RsType* typesPtr;
-    jint typesLen = _env->GetArrayLength(_types);
-    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
-
-    if (jKernelsPtr == nullptr) {
-        LOG_ERR("Failed to get Java array elements: kernels");
-        goto cleanup;
-    }
-    if (jSrcPtr == nullptr) {
-        LOG_ERR("Failed to get Java array elements: src");
-        goto cleanup;
-    }
-    if (jDstkPtr == nullptr) {
-        LOG_ERR("Failed to get Java array elements: dstk");
-        goto cleanup;
-    }
-    if (jDstfPtr == nullptr) {
-        LOG_ERR("Failed to get Java array elements: dstf");
-        goto cleanup;
-    }
-    if (jTypesPtr == nullptr) {
-        LOG_ERR("Failed to get Java array elements: types");
-        goto cleanup;
-    }
-
-    kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
-    for(int i = 0; i < kernelsLen; ++i) {
-        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
-    }
-
-    srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
-    for(int i = 0; i < srcLen; ++i) {
-        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
-    }
-
-    dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
-    for(int i = 0; i < dstkLen; ++i) {
-        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
-    }
-
-    dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
-    for(int i = 0; i < dstfLen; ++i) {
-        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
-    }
-
-    typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
-    for(int i = 0; i < typesLen; ++i) {
-        typesPtr[i] = (RsType)jTypesPtr[i];
-    }
-
-    id = (jlong)(uintptr_t) dispatchTab.ScriptGroupCreate((RsContext)con,
-                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
-                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
-                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
-                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
-                               (RsType *)typesPtr, typesLen * sizeof(RsType));
-
-    free(kernelsPtr);
-    free(srcPtr);
-    free(dstkPtr);
-    free(dstfPtr);
-    free(typesPtr);
-
-cleanup:
-    if (jKernelsPtr != nullptr) {
-        _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
-    }
-    if (jSrcPtr != nullptr) {
-        _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
-    }
-    if (jDstkPtr != nullptr) {
-        _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
-    }
-    if (jDstfPtr != nullptr) {
-        _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
-    }
-    if (jTypesPtr != nullptr) {
-        _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
-    }
-
-    return id;
-}
-
-static void
-nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
-{
-    LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
-            (void *)gid, (void *)kid, (void *)alloc);
-    dispatchTab.ScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
-                                    (RsAllocation)alloc);
-}
-
-static void
-nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
-{
-    LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
-            (void *)gid, (void *)kid, (void *)alloc);
-    dispatchTab.ScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
-                                     (RsAllocation)alloc);
-}
-
-static void
-nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
-{
-    LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
-    dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
-}
-
-// ---------------------------------------------------------------------------
-
-static jlong
-nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
-               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
-{
-    LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
-    return (jlong)(uintptr_t)dispatchTab.SamplerCreate((RsContext)con,
-                                                       (RsSamplerValue)magFilter,
-                                                       (RsSamplerValue)minFilter,
-                                                       (RsSamplerValue)wrapS,
-                                                       (RsSamplerValue)wrapT,
-                                                       (RsSamplerValue)wrapR,
-                                                       aniso);
-}
-
-static jint
-nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
-    return (jint)sizeof(void*);
-}
-
-// ---------------------------------------------------------------------------
-// For Incremental Intrinsic Support
-static jboolean nIncLoadSO(JNIEnv *_env, jobject _this, jint deviceApi, jstring libPath) {
-    void* handle = NULL;
-    // For API 9+, dlopen the full path of libRSSupport.
-    if (libPath != NULL) {
-        const char * libPathJni = _env->GetStringUTFChars(libPath, JNI_FALSE);
-        handle = dlopen(libPathJni, RTLD_LAZY | RTLD_LOCAL);
-        _env->ReleaseStringUTFChars(libPath, libPathJni);
-    } else {
-        handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
-    }
-
-    if (handle == NULL) {
-        LOG_ERR("couldn't dlopen %s;  librsjni version: %d", dlerror(), RS_JNI_VERSION);
-        return false;
-    }
-
-    if (loadSymbols(handle, dispatchTabInc, deviceApi) == false) {
-        LOG_ERR("Dispatch Table init failed! librsjni version: %d", RS_JNI_VERSION);
-        dlclose(handle);
-        return false;
-    }
-    dispatchTabInc.AllocationCreateStrided = (AllocationCreateStridedFnPtr)dlsym(handle, "rsAllocationCreateStrided");
-    if (dispatchTabInc.AllocationCreateStrided == NULL) {
-        LOG_ERR("Couldn't initialize dispatchTabInc.AllocationCreateStrided");
-        dlclose(handle);
-        return false;
-    }
-    LOG_API("Successfully loaded compat runtime");
-    return true;
-}
-
-// -----------------------------------
-// To create/destroy a dummy context
-static void
-nIncObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
-{
-    LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
-    dispatchTabInc.ObjDestroy((RsContext)con, (void *)obj);
-}
-
-
-static jlong
-nIncDeviceCreate(JNIEnv *_env, jobject _this)
-{
-    LOG_API("nDeviceCreate");
-    return (jlong)(uintptr_t)dispatchTabInc.DeviceCreate();
-}
-
-static void
-nIncDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
-{
-    LOG_API("nDeviceDestroy");
-    return dispatchTabInc.DeviceDestroy((RsDevice)dev);
-}
-
-static jlong
-nIncContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
-{
-    LOG_API("nContextCreate");
-    //The compat context for incremental support will be synchronous.
-    return (jlong)(uintptr_t)dispatchTabInc.ContextCreate((RsDevice)dev, ver, sdkVer,
-                                                          (RsContextType)ct,
-                                                          RS_CONTEXT_SYNCHRONOUS);
-}
-
-static void
-nIncContextFinish(JNIEnv *_env, jobject _this, jlong con)
-{
-    LOG_API("nContextFinish, con(%p)", (RsContext)con);
-    dispatchTabInc.ContextFinish((RsContext)con);
-}
-
-static void
-nIncContextDestroy(JNIEnv *_env, jobject _this, jlong con)
-{
-    LOG_API("nContextDestroy, con(%p)", (RsContext)con);
-    dispatchTabInc.ContextDestroy((RsContext)con);
-}
-
-// -----------------------------------
-// Create dummy Element
-static jlong
-nIncElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
-{
-    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
-            type, kind, norm, size);
-    return (jlong)(uintptr_t)dispatchTabInc.ElementCreate((RsContext)con, (RsDataType)type,
-                                                          (RsDataKind)kind, norm, size);
-}
-// -----------------------------------
-// Create dummy Type
-static jlong
-nIncTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
-            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
-{
-    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
-            incCon, eid, dimx, dimy, dimz, mips, faces, yuv);
-
-    return (jlong)(uintptr_t)dispatchTabInc.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy,
-                                                       dimz, mips, faces, yuv);
-}
-
-// -----------------------------------
-// Create Allocation from pointer
-static jlong
-nIncAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong alloc, jlong type, jint xBytesSize)
-{
-    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
-            incCon, (RsElement)type, mips, usage, (void *)pointer);
-    size_t strideIn;
-    void* pIn = NULL;
-    RsAllocation ainI = NULL;
-    if (alloc != 0) {
-        pIn = dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
-                                               RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
-                                               &strideIn, sizeof(size_t));
-        /*
-         * By definition stride is a roundup of xBytesSize with requiredAlignment, so requiredAlignment must
-         * be strictly larger than the difference of (stride - xBytesSize).
-         *
-         * We can prove that as long as requiredAlignment satisfies the following two conditions, the
-         * memory layout will be identical :
-         * 1. Smaller or equal than stride;
-         * 2. Larger than minRequiredAlignment.
-         *
-         * In this case we can simply choose the first power of 2 that satisfies both conditions.
-         */
-        size_t requiredAlignment = 16;
-        size_t minRequiredAlignment = strideIn - xBytesSize;
-        while (requiredAlignment <= minRequiredAlignment) {
-            requiredAlignment <<= 1;
-        }
-        ainI = dispatchTabInc.AllocationCreateStrided((RsContext)incCon, (RsType)type,
-                                                      RS_ALLOCATION_MIPMAP_NONE,
-                                                      RS_ALLOCATION_USAGE_INCREMENTAL_SUPPORT | RS_ALLOCATION_USAGE_SHARED,
-                                                      (uintptr_t)pIn, requiredAlignment);
-    }
-    return (jlong)(uintptr_t) ainI;
-}
-
-static jobject
-nAllocationGetByteBuffer(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint xBytesSize, jint dimY, jint dimZ)
-{
-    LOG_API("nAllocationGetByteBuffer, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
-    size_t strideIn = xBytesSize;
-    void* ptr = NULL;
-    if (alloc != 0 && dispatchTab.AllocationGetPointer != nullptr) {
-        ptr = dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
-                                               RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, dimZ, 0,
-                                               &strideIn, sizeof(size_t));
-    }
-    if (ptr != NULL) {
-        size_t bufferSize = strideIn;
-        if (dimY > 0) {
-            bufferSize *= dimY;
-        }
-        if (dimZ > 0) {
-            bufferSize *= dimZ;
-        }
-        jobject byteBuffer = _env->NewDirectByteBuffer(ptr, (jlong) bufferSize);
-        return byteBuffer;
-    } else {
-        return NULL;
-    }
-}
-
-static jlong
-nAllocationGetStride(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
-{
-    LOG_API("nAllocationGetStride, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
-    size_t strideIn = 0;
-    if (alloc != 0 && dispatchTab.AllocationGetPointer != nullptr) {
-        dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
-                                         RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
-                                         &strideIn, sizeof(size_t));
-    }
-    return (jlong)strideIn;
-}
-
-// ---------------------------------------------------------------------------
-
-
-static const char *classPathName = "android/support/v8/renderscript/RenderScript";
-
-static JNINativeMethod methods[] = {
-{"nLoadSO",                        "(ZILjava/lang/String;)Z",                 (bool*)nLoadSO },
-{"nLoadIOSO",                      "()Z",                                     (bool*)nLoadIOSO },
-{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
-{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
-{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
-{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
-{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
-{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
-{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
-{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
-
-
-// All methods below are thread protected in java.
-{"rsnContextCreate",                 "(JIIILjava/lang/String;)J",             (void*)nContextCreate },
-{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
-{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
-{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
-{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
-{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
-{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
-{"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
-{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
-{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
-{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
-
-{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
-{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
-{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
-
-{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
-
-{"rsnAllocationCreateTyped",         "(JJIIJ)J",                              (void*)nAllocationCreateTyped },
-{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
-{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
-{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
-
-{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
-{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
-
-{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
-{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
-{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
-{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
-{"rsnAllocationElementData1D",       "(JJIII[BI)V",                           (void*)nAllocationElementData1D },
-//{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
-{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
-{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
-{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
-{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
-{"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
-{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
-//{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
-{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
-//{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",  (void*)nAllocationRead3D },
-{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
-{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
-{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
-
-{"rsnScriptBindAllocation",          "(JJJIZ)V",                              (void*)nScriptBindAllocation },
-{"rsnScriptSetTimeZone",             "(JJ[BZ)V",                              (void*)nScriptSetTimeZone },
-{"rsnScriptInvoke",                  "(JJIZ)V",                               (void*)nScriptInvoke },
-{"rsnScriptInvokeV",                 "(JJI[BZ)V",                             (void*)nScriptInvokeV },
-{"rsnScriptForEach",                 "(JJJIJJZ)V",                            (void*)nScriptForEach },
-{"rsnScriptForEach",                 "(JJJIJJ[BZ)V",                          (void*)nScriptForEachV },
-{"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEachMulti },
-{"rsnScriptForEachClipped",          "(JJJIJJIIIIIIZ)V",                      (void*)nScriptForEachClipped },
-{"rsnScriptForEachClipped",          "(JJJIJJ[BIIIIIIZ)V",                    (void*)nScriptForEachClippedV },
-{"rsnScriptReduce",                  "(JJI[JJ[I)V",                           (void*)nScriptReduce },
-{"rsnScriptSetVarI",                 "(JJIIZ)V",                              (void*)nScriptSetVarI },
-{"rsnScriptSetVarJ",                 "(JJIJZ)V",                              (void*)nScriptSetVarJ },
-{"rsnScriptSetVarF",                 "(JJIFZ)V",                              (void*)nScriptSetVarF },
-{"rsnScriptSetVarD",                 "(JJIDZ)V",                              (void*)nScriptSetVarD },
-{"rsnScriptSetVarV",                 "(JJI[BZ)V",                             (void*)nScriptSetVarV },
-{"rsnScriptSetVarVE",                "(JJI[BJ[IZ)V",                          (void*)nScriptSetVarVE },
-{"rsnScriptSetVarObj",               "(JJIJZ)V",                              (void*)nScriptSetVarObj },
-
-{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
-{"rsnScriptIntrinsicCreate",         "(JIJZ)J",                               (void*)nScriptIntrinsicCreate },
-{"rsnScriptKernelIDCreate",          "(JJIIZ)J",                              (void*)nScriptKernelIDCreate },
-{"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
-{"rsnScriptFieldIDCreate",           "(JJIZ)J",                               (void*)nScriptFieldIDCreate },
-{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
-{"rsnScriptGroup2Create",            "(JLjava/lang/String;Ljava/lang/String;[J)J", (void*)nScriptGroup2Create },
-{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
-{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
-{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
-{"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
-
-{"rsnScriptIntrinsicBLAS_Single",    "(JJJIIIIIIIIIFJJFJIIIIZ)V",             (void*)nScriptIntrinsicBLAS_Single },
-{"rsnScriptIntrinsicBLAS_Double",    "(JJJIIIIIIIIIDJJDJIIIIZ)V",             (void*)nScriptIntrinsicBLAS_Double },
-{"rsnScriptIntrinsicBLAS_Complex",   "(JJJIIIIIIIIIFFJJFFJIIIIZ)V",           (void*)nScriptIntrinsicBLAS_Complex },
-{"rsnScriptIntrinsicBLAS_Z",         "(JJJIIIIIIIIIDDJJDDJIIIIZ)V",           (void*)nScriptIntrinsicBLAS_Z },
-
-{"rsnScriptIntrinsicBLAS_BNNM",      "(JJJIIIJIJIJIIZ)V",                     (void*)nScriptIntrinsicBLAS_BNNM },
-
-{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
-
-{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
-
-// Entry points for Inc libRSSupport
-{"nIncLoadSO",                       "(ILjava/lang/String;)Z",                (bool*)nIncLoadSO },
-{"nIncDeviceCreate",                 "()J",                                   (void*)nIncDeviceCreate },
-{"nIncDeviceDestroy",                "(J)V",                                  (void*)nIncDeviceDestroy },
-{"rsnIncContextCreate",              "(JIII)J",                               (void*)nIncContextCreate },
-{"rsnIncContextFinish",              "(J)V",                                  (void*)nIncContextFinish },
-{"rsnIncContextDestroy",             "(J)V",                                  (void*)nIncContextDestroy },
-{"rsnIncObjDestroy",                 "(JJ)V",                                 (void*)nIncObjDestroy },
-{"rsnIncElementCreate",              "(JJIZI)J",                              (void*)nIncElementCreate },
-{"rsnIncTypeCreate",                 "(JJIIIZZI)J",                           (void*)nIncTypeCreate },
-{"rsnIncAllocationCreateTyped",      "(JJJJI)J",                              (void*)nIncAllocationCreateTyped },
-{"rsnAllocationGetByteBuffer",       "(JJIII)Ljava/nio/ByteBuffer;",          (void*)nAllocationGetByteBuffer },
-{"rsnAllocationGetStride",           "(JJ)J",                                 (void*)nAllocationGetStride },
-};
-
-// ---------------------------------------------------------------------------
-
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-    JNIEnv* env = NULL;
-    jclass clazz = NULL;
-    jint result = -1;
-
-    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
-        //            "ERROR: GetEnv failed\n");
-        goto bail;
-    }
-    if (env == NULL) {
-        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: env == NULL");
-        goto bail;
-    }
-
-    clazz = env->FindClass(classPathName);
-    if (clazz == NULL) {
-        goto bail;
-    }
-
-    if (env->RegisterNatives(clazz, methods, NELEM(methods)) < 0) {
-        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
-        //            "ERROR: MediaPlayer native registration failed\n");
-        goto bail;
-    }
-
-    /* success -- return valid version number */
-    result = JNI_VERSION_1_4;
-
-bail:
-    return result;
-}
diff --git a/v8/renderscript/jni/android_rscompat_usage_io.cpp b/v8/renderscript/jni/android_rscompat_usage_io.cpp
deleted file mode 100644
index e29be1a..0000000
--- a/v8/renderscript/jni/android_rscompat_usage_io.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <android/log.h>
-#include <android/native_window.h>
-#include <android/native_window_jni.h>
-
-#include <rsEnv.h>
-#include "rsDispatch.h"
-#define LOG_API(...)
-
-extern "C" void AllocationSetSurface(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc, jobject sur, dispatchTable dispatchTab)
-{
-    LOG_API("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)",
-            con, alloc, sur);
-
-    ANativeWindow* s = NULL;
-    if (sur != 0) {
-        s = ANativeWindow_fromSurface(_env, sur);
-    }
-    dispatchTab.AllocationSetSurface(con, alloc, s);
-}
-
diff --git a/v8/renderscript/jni/android_rscompat_usage_io_driver.cpp b/v8/renderscript/jni/android_rscompat_usage_io_driver.cpp
deleted file mode 100644
index 96eb19a..0000000
--- a/v8/renderscript/jni/android_rscompat_usage_io_driver.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-#include <android/native_window.h>
-#include <android/log.h>
-
-#include "rsCompatibilityLib.h"
-
-#include "rsdCore.h"
-#include "rsdAllocation.h"
-#include "rsAllocation.h"
-
-#define LOG_API(...)
-
-using namespace android;
-using namespace android::renderscript;
-
-static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
-    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
-    // Must lock the whole surface
-    if(drv->wndBuffer == NULL) {
-        drv->wndBuffer = new ANativeWindow_Buffer;
-    }
-    int32_t r = ANativeWindow_lock(nw, drv->wndBuffer, NULL);
-    if (r) {
-        LOG_API("Error Locking IO output buffer.");
-        return false;
-    }
-
-    void *dst = drv->wndBuffer->bits;
-    alloc->mHal.drvState.lod[0].mallocPtr = dst;
-    alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes;
-    return true;
-}
-
-extern "C" void rscAllocationSetSurface(RsContext rscR, RsAllocation allocR, ANativeWindow *nw) {
-    Context *rsc = (Context *)rscR;
-    Allocation *alloc = (Allocation *)allocR;
-    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
-
-    // Cleanup old surface if there is one.
-    if (drv->wndSurface) {
-        ANativeWindow *old = drv->wndSurface;
-        ANativeWindow_unlockAndPost(old);
-        drv->wndSurface = NULL;
-        ANativeWindow_release(old);
-        old = NULL;
-    }
-
-    if (nw != NULL) {
-        int32_t r;
-        r = ANativeWindow_setBuffersGeometry(nw, alloc->mHal.drvState.lod[0].dimX,
-                                                 alloc->mHal.drvState.lod[0].dimY,
-                                                 WINDOW_FORMAT_RGBA_8888);
-        if (r) {
-            LOG_API("Error setting IO output buffer geometry.");
-            goto errorcmp;
-        }
-
-        IoGetBuffer(rsc, alloc, nw);
-        drv->wndSurface = nw;
-    }
-
-    return;
-
- errorcmp:
-
-    if (nw) {
-        nw = NULL;
-    }
-
-}
-
-extern "C" void rscAllocationDestroy(const Context *rsc, Allocation *alloc) {
-    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
-    if (alloc->mHal.drvState.lod[0].mallocPtr) {
-        // don't free user-allocated ptrs or IO_OUTPUT buffers
-        if (!(drv->useUserProvidedPtr) &&
-            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) &&
-            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
-                free(alloc->mHal.drvState.lod[0].mallocPtr);
-        }
-        alloc->mHal.drvState.lod[0].mallocPtr = NULL;
-    }
-
-    if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) &&
-        (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
-        ANativeWindow *nw = drv->wndSurface;
-        if (nw) {
-            //If we have an attached surface, need to release it.
-            ANativeWindow_unlockAndPost(nw);
-            drv->wndSurface = NULL;
-            ANativeWindow_release(nw);
-            nw = NULL;
-        }
-    }
-}
-
-extern "C" void rscAllocationIoSend(const Context *rsc, Allocation *alloc) {
-    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
-    ANativeWindow *nw = drv->wndSurface;
-    if (nw) {
-        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
-            int32_t r = ANativeWindow_unlockAndPost(nw);
-            if (r) {
-                LOG_API("Error sending IO output buffer.");
-                return;
-            }
-            IoGetBuffer(rsc, alloc, nw);
-        }
-    } else {
-        LOG_API("Sent IO buffer with no attached surface.");
-        return;
-    }
-}
-
diff --git a/v8/renderscript/rs_support/Android.mk b/v8/renderscript/rs_support/Android.mk
deleted file mode 100644
index de8fae0..0000000
--- a/v8/renderscript/rs_support/Android.mk
+++ /dev/null
@@ -1,189 +0,0 @@
-
-LOCAL_PATH:=frameworks/rs
-rs_base_CFLAGS := -Werror -Wall -Wno-unused-parameter -Wno-unused-variable \
-		  -Wno-overloaded-virtual -DRS_COMPATIBILITY_LIB -std=c++11
-
-ifeq ($(ARCH_ARM_HAVE_NEON),true)
-rs_base_CFLAGS += -DARCH_ARM_HAVE_NEON
-endif
-
-ifeq ($(TARGET_BUILD_PDK), true)
-  rs_base_CFLAGS += -D__RS_PDK__
-endif
-
-# Build rsg-generator ====================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := rsg-generator_support
-
-# These symbols are normally defined by BUILD_XXX, but we need to define them
-# here so that local-intermediates-dir works.
-
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-intermediates := $(local-intermediates-dir)
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES:= \
-    spec.l \
-    rsg_generator.c
-
-LOCAL_CXX_STL := none
-LOCAL_SANITIZE := never
-
-include $(BUILD_HOST_EXECUTABLE)
-
-# TODO: This should go into build/core/config.mk
-RSG_GENERATOR_SUPPORT:=$(LOCAL_BUILT_MODULE)
-
-include $(CLEAR_VARS)
-LOCAL_CLANG := true
-LOCAL_MODULE := libRSSupport
-LOCAL_SDK_VERSION := 9
-
-
-LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-generated_sources_dir := $(call local-generated-sources-dir)
-
-# Generate custom headers
-
-GEN := $(addprefix $(generated_sources_dir)/, \
-            rsgApiStructs.h \
-            rsgApiFuncDecl.h \
-        )
-
-$(GEN) : PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN) : PRIVATE_CUSTOM_TOOL = cat $(PRIVATE_PATH)/rs.spec $(PRIVATE_PATH)/rs_compat.spec | $(RSG_GENERATOR_SUPPORT) $< $@
-$(GEN) : $(RSG_GENERATOR_SUPPORT) $(LOCAL_PATH)/rs.spec $(LOCAL_PATH)/rs_compat.spec
-$(GEN): $(generated_sources_dir)/%.h : $(LOCAL_PATH)/%.h.rsg
-	$(transform-generated-source)
-
-# used in jni/Android.mk
-rs_generated_source += $(GEN)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-# Generate custom source files
-
-GEN := $(addprefix $(generated_sources_dir)/, \
-            rsgApi.cpp \
-            rsgApiReplay.cpp \
-        )
-
-$(GEN) : PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN) : PRIVATE_CUSTOM_TOOL = cat $(PRIVATE_PATH)/rs.spec $(PRIVATE_PATH)/rs_compat.spec | $(RSG_GENERATOR_SUPPORT) $< $@
-$(GEN) : $(RSG_GENERATOR_SUPPORT) $(LOCAL_PATH)/rs.spec $(LOCAL_PATH)/rs_compat.spec
-$(GEN): $(generated_sources_dir)/%.cpp : $(LOCAL_PATH)/%.cpp.rsg
-	$(transform-generated-source)
-
-# used in jni/Android.mk
-rs_generated_source += $(GEN)
-
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-LOCAL_SRC_FILES:= \
-	rsAllocation.cpp \
-	rsApiAllocation.cpp \
-	rsApiContext.cpp \
-	rsApiDevice.cpp \
-	rsApiElement.cpp \
-	rsApiType.cpp \
-	rsClosure.cpp \
-	rsCompatibilityLib.cpp \
-	rsComponent.cpp \
-	rsContext.cpp \
-	rsCppUtils.cpp \
-	rsDevice.cpp \
-	rsDriverLoader.cpp \
-	rsElement.cpp \
-	rsFifoSocket.cpp \
-	rsObjectBase.cpp \
-	rsMatrix2x2.cpp \
-	rsMatrix3x3.cpp \
-	rsMatrix4x4.cpp \
-	rsMutex.cpp \
-	rsSampler.cpp \
-	rsScript.cpp \
-	rsScriptC.cpp \
-	rsScriptC_Lib.cpp \
-	rsScriptGroup.cpp \
-	rsScriptGroup2.cpp \
-	rsScriptIntrinsic.cpp \
-	rsSignal.cpp \
-	rsStream.cpp \
-	rsThreadIO.cpp \
-	rsType.cpp \
-	driver/rsdAllocation.cpp \
-	driver/rsdBcc.cpp \
-	driver/rsdCore.cpp \
-	driver/rsdElement.cpp \
-	driver/rsdRuntimeStubs.cpp \
-	driver/rsdSampler.cpp \
-	driver/rsdScriptGroup.cpp \
-	driver/rsdType.cpp \
-	cpu_ref/rsCpuCore.cpp \
-	cpu_ref/rsCpuExecutable.cpp \
-	cpu_ref/rsCpuScript.cpp \
-	cpu_ref/rsCpuRuntimeMath.cpp \
-	cpu_ref/rsCpuScriptGroup.cpp \
-	cpu_ref/rsCpuScriptGroup2.cpp \
-	cpu_ref/rsCpuIntrinsic.cpp \
-	cpu_ref/rsCpuIntrinsic3DLUT.cpp \
-	cpu_ref/rsCpuIntrinsicBlend.cpp \
-	cpu_ref/rsCpuIntrinsicBlur.cpp \
-	cpu_ref/rsCpuIntrinsicBLAS.cpp \
-	cpu_ref/rsCpuIntrinsicColorMatrix.cpp \
-	cpu_ref/rsCpuIntrinsicConvolve3x3.cpp \
-	cpu_ref/rsCpuIntrinsicConvolve5x5.cpp \
-	cpu_ref/rsCpuIntrinsicHistogram.cpp \
-	cpu_ref/rsCpuIntrinsicLUT.cpp \
-	cpu_ref/rsCpuIntrinsicResize.cpp \
-	cpu_ref/rsCpuIntrinsicYuvToRGB.cpp
-
-ifeq ($(ARCH_ARM_HAVE_ARMV7A),true)
-LOCAL_CFLAGS_arm := -DARCH_ARM_HAVE_VFP -DARCH_ARM_USE_INTRINSICS
-LOCAL_ASFLAGS_arm := -mfpu=neon
-LOCAL_SRC_FILES_arm := \
-    cpu_ref/rsCpuIntrinsics_neon_3DLUT.S \
-    cpu_ref/rsCpuIntrinsics_neon_Blend.S \
-    cpu_ref/rsCpuIntrinsics_neon_Blur.S \
-    cpu_ref/rsCpuIntrinsics_neon_ColorMatrix.S \
-    cpu_ref/rsCpuIntrinsics_neon_Convolve.S \
-    cpu_ref/rsCpuIntrinsics_neon_Resize.S \
-    cpu_ref/rsCpuIntrinsics_neon_YuvToRGB.S
-endif
-
-LOCAL_CFLAGS_arm64 += \
-    -DARCH_ARM_USE_INTRINSICS \
-    -DARCH_ARM64_USE_INTRINSICS \
-    -DARCH_ARM64_HAVE_NEON
-LOCAL_SRC_FILES_arm64 += \
-    cpu_ref/rsCpuIntrinsics_advsimd_3DLUT.S \
-    cpu_ref/rsCpuIntrinsics_advsimd_Blend.S \
-    cpu_ref/rsCpuIntrinsics_advsimd_Blur.S \
-    cpu_ref/rsCpuIntrinsics_advsimd_ColorMatrix.S \
-    cpu_ref/rsCpuIntrinsics_advsimd_Convolve.S \
-    cpu_ref/rsCpuIntrinsics_advsimd_Resize.S \
-    cpu_ref/rsCpuIntrinsics_advsimd_YuvToRGB.S
-
-LOCAL_CFLAGS_x86 += -DARCH_X86_HAVE_SSSE3
-LOCAL_SRC_FILES_x86 += cpu_ref/rsCpuIntrinsics_x86.cpp
-LOCAL_CFLAGS_x86_64 += -DARCH_X86_HAVE_SSSE3
-LOCAL_SRC_FILES_x86_64 += cpu_ref/rsCpuIntrinsics_x86.cpp
-
-LOCAL_REQUIRED_MODULES := libblasV8
-LOCAL_STATIC_LIBRARIES := libbnnmlowpV8
-LOCAL_LDFLAGS += -llog -ldl -Wl,--exclude-libs,libc++_static.a
-LOCAL_NDK_STL_VARIANT := c++_static
-
-LOCAL_C_INCLUDES += external/cblas/include
-LOCAL_C_INCLUDES += external/gemmlowp/eight_bit_int_gemm
-
-LOCAL_CFLAGS += $(rs_base_CFLAGS) -DGEMMLOWP_USE_STLPORT
-
-LOCAL_MODULE:= libRSSupport
-LOCAL_MODULE_TAGS := optional
-
-# TODO: why isn't this picked up from the host GLOBAL_CFLAGS?
-LOCAL_CFLAGS += -D__STDC_FORMAT_MACROS
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/documents-archive/Android.mk b/wearable/Android.mk
similarity index 75%
rename from documents-archive/Android.mk
rename to wearable/Android.mk
index 32ec7d6..56a7b91 100644
--- a/documents-archive/Android.mk
+++ b/wearable/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 The Android Open Source Project
+# Copyright (C) 2016 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.
@@ -18,21 +18,19 @@
 # Applications that use this library must specify
 #
 #   LOCAL_STATIC_ANDROID_LIBRARIES := \
-#       android-support-documents-archive \
-#       android-support-v4 \
-#       android-support-annotations
+#       android-support-wearable \
+#       android-support-core-ui
 #
 # in their makefiles to include the resources and their dependencies in their package.
 include $(CLEAR_VARS)
 LOCAL_USE_AAPT2 := true
-LOCAL_MODULE := android-support-documents-archive
+LOCAL_MODULE := android-support-wearable
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 LOCAL_SHARED_ANDROID_LIBRARIES := \
-    android-support-annotations \
-    android-support-v4
+    android-support-core-ui \
+    android-support-annotations
 LOCAL_JAR_EXCLUDE_FILES := none
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
diff --git a/v7/palette/src/main/AndroidManifest.xml b/wearable/AndroidManifest.xml
similarity index 82%
copy from v7/palette/src/main/AndroidManifest.xml
copy to wearable/AndroidManifest.xml
index 52e90a2..618c69d 100644
--- a/v7/palette/src/main/AndroidManifest.xml
+++ b/wearable/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2016 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.
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.v7.palette">
-    <uses-sdk android:minSdkVersion="9"/>
+          package="android.support.wearable">
+    <uses-sdk android:minSdkVersion="20"/>
     <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
 </manifest>
diff --git a/wearable/README.txt b/wearable/README.txt
new file mode 100644
index 0000000..58f2168
--- /dev/null
+++ b/wearable/README.txt
@@ -0,0 +1 @@
+Library Project including Wearable Support UI Components and associated utilities.
diff --git a/wearable/build.gradle b/wearable/build.gradle
new file mode 100644
index 0000000..627f4ca
--- /dev/null
+++ b/wearable/build.gradle
@@ -0,0 +1,35 @@
+apply plugin: android.support.SupportLibraryPlugin
+archivesBaseName = 'wearable'
+
+dependencies {
+    compile project(':support-annotations')
+    compile project(':support-core-ui')
+
+    androidTestCompile (libs.test_runner) {
+        exclude module: 'support-annotations'
+    }
+    androidTestCompile (libs.espresso_core) {
+        exclude module: 'support-annotations'
+    }
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 20
+    }
+
+    sourceSets {
+        main.java.srcDir 'src'
+        main.res.srcDirs 'res', 'res-public'
+    }
+
+    buildTypes.all {
+        consumerProguardFiles 'proguard-rules.pro'
+    }
+}
+
+supportLibrary {
+    name 'Android Wear Support UI'
+    inceptionYear '2016'
+    description 'Android Wear Support UI'
+}
diff --git a/v8/Android.mk b/wearable/proguard-rules.pro
similarity index 65%
copy from v8/Android.mk
copy to wearable/proguard-rules.pro
index 14ff0aa..c6cd374 100644
--- a/v8/Android.mk
+++ b/wearable/proguard-rules.pro
@@ -1,4 +1,4 @@
-# Copyright (C) 2014 The Android Open Source Project
+# Copyright (C) 2015 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.
@@ -12,5 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH:= $(call my-dir)
-include $(call all-makefiles-under,$(LOCAL_PATH))
+# When layoutManager xml attribute is used, RecyclerView inflates
+# LayoutManagers' constructors using reflection.
+-keep public class * extends android.support.v7.widget.RecyclerView$LayoutManager {
+    public <init>(...);
+}
diff --git a/transition/AndroidManifest-make.xml b/wearable/res-public/values/public_attrs.xml
similarity index 77%
copy from transition/AndroidManifest-make.xml
copy to wearable/res-public/values/public_attrs.xml
index 672e1b1..afb7bfe 100644
--- a/transition/AndroidManifest-make.xml
+++ b/wearable/res-public/values/public_attrs.xml
@@ -13,8 +13,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.support.transition">
-    <uses-sdk android:minSdkVersion="14"/>
-    <application />
-</manifest>
+
+<!-- Definitions of attributes to be exposed as public -->
+<resources>
+    <public type="attr" name="boxedEdges" />
+</resources>
\ No newline at end of file
diff --git a/wearable/res/values/attrs.xml b/wearable/res/values/attrs.xml
new file mode 100644
index 0000000..e52dee9
--- /dev/null
+++ b/wearable/res/values/attrs.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<!-- Formatting note: terminate all comments with a period, to avoid breaking
+     the documentation output. To suppress comment lines from the documentation
+     output, insert an eat-comment element after the comment lines.
+-->
+
+<resources>
+    <!-- Attributes that can be used with any member view of
+        {@link android.support.wearable.view.BoxInsetLayout}.
+        These attributes are specified with the rest of a view's normal attributes
+        (such as {@link android.R.attr#background}, but will be parsed by the view's parent and
+        ignored by the child.
+        <p>The values defined here correspond to the base layout attribute
+        class {@link android.support.wearable.view.BoxInsetLayout.LayoutParams}. -->
+    <declare-styleable name="BoxInsetLayout_Layout">
+        <!-- The types of insets this view can force on its children. The view will respect the
+             defined values of other child attributes such as ones provided by
+             {@link android.view.ViewGroup.MarginLayoutParams}, but it will add an additional inset
+              as requested -->
+        <attr name="boxedEdges">
+            <!-- Default boxing setting. There are no insets forced on the child views. -->
+            <flag name="none" value="0x00" />
+            <!-- The view will force an inset on the left edge of the children. -->
+            <flag name="left" value="0x01" />
+            <!-- The view will force an inset on the top edge of the children. -->
+            <flag name="top" value="0x02" />
+            <!-- The view will force an inset on the right edge of the children. -->
+            <flag name="right" value="0x04" />
+            <!-- The view will force an inset on the bottom edge of the children. -->
+            <flag name="bottom" value="0x08" />
+            <!-- The view will force an inset on all of the edges of the children. -->
+            <flag name="all" value="0x0F" />
+        </attr>
+    </declare-styleable>
+</resources>
diff --git a/wearable/src/android/support/wearable/view/BoxInsetLayout.java b/wearable/src/android/support/wearable/view/BoxInsetLayout.java
new file mode 100644
index 0000000..3dcd10c
--- /dev/null
+++ b/wearable/src/android/support/wearable/view/BoxInsetLayout.java
@@ -0,0 +1,532 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.wearable.view;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.support.annotation.IntDef;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.StyleRes;
+import android.support.annotation.UiThread;
+import android.support.wearable.R;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
+import android.widget.FrameLayout;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * BoxInsetLayout is a screen shape-aware ViewGroup that can box its children in the center
+ * square of a round screen by using the {@code boxedEdges} attribute. The values for this attribute
+ * specify the child's edges to be boxed in: {@code left|top|right|bottom} or {@code all}. The
+ * {@code boxedEdges} attribute is ignored on a device with a rectangular screen.
+ */
+@UiThread
+public class BoxInsetLayout extends ViewGroup {
+
+    private static final float FACTOR = 0.146467f; //(1 - sqrt(2)/2)/2
+    private static final int DEFAULT_CHILD_GRAVITY = Gravity.TOP | Gravity.START;
+
+    private final int mScreenHeight;
+    private final int mScreenWidth;
+
+    private boolean mIsRound;
+    private Rect mForegroundPadding;
+    private Rect mInsets;
+    private Drawable mForegroundDrawable;
+
+    /**
+     * Simple constructor to use when creating a view from code.
+     *
+     * @param context The {@link Context} the view is running in, through which it can access
+     *                the
+     *                current theme, resources, etc.
+     */
+    public BoxInsetLayout(@NonNull Context context) {
+        this(context, null);
+    }
+
+    /**
+     * Constructor that is called when inflating a view from XML. This is called when a view is
+     * being constructed from an XML file, supplying attributes that were specified in the XML
+     * file.
+     * This version uses a default style of 0, so the only attribute values applied are those in
+     * the
+     * Context's Theme and the given AttributeSet.
+     * <p>
+     * <p>
+     * The method onFinishInflate() will be called after all children have been added.
+     *
+     * @param context The {@link Context} the view is running in, through which it can access
+     *                the
+     *                current theme, resources, etc.
+     * @param attrs   The attributes of the XML tag that is inflating the view.
+     */
+    public BoxInsetLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    /**
+     * Perform inflation from XML and apply a class-specific base style from a theme attribute.
+     * This constructor allows subclasses to use their own base style when they are inflating.
+     *
+     * @param context  The {@link Context} the view is running in, through which it can
+     *                 access the
+     *                 current theme, resources, etc.
+     * @param attrs    The attributes of the XML tag that is inflating the view.
+     * @param defStyle An attribute in the current theme that contains a reference to a style
+     *                 resource that supplies default values for the view. Can be 0 to not look for
+     *                 defaults.
+     */
+    public BoxInsetLayout(@NonNull Context context, @Nullable AttributeSet attrs, @StyleRes int
+            defStyle) {
+        super(context, attrs, defStyle);
+        // make sure we have a foreground padding object
+        if (mForegroundPadding == null) {
+            mForegroundPadding = new Rect();
+        }
+        if (mInsets == null) {
+            mInsets = new Rect();
+        }
+        mScreenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
+        mScreenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
+    }
+
+    @Override
+    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        insets = super.onApplyWindowInsets(insets);
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+            final boolean round = insets.isRound();
+            if (round != mIsRound) {
+                mIsRound = round;
+                requestLayout();
+            }
+            mInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
+                    insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
+        }
+        return insets;
+    }
+
+    @Override
+    public void setForeground(Drawable drawable) {
+        super.setForeground(drawable);
+        mForegroundDrawable = drawable;
+        if (mForegroundPadding == null) {
+            mForegroundPadding = new Rect();
+        }
+        if (mForegroundDrawable != null) {
+            drawable.getPadding(mForegroundPadding);
+        }
+    }
+
+    @Override
+    public LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new BoxInsetLayout.LayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+            requestApplyInsets();
+        } else {
+            mIsRound = getResources().getConfiguration().isScreenRound();
+            WindowInsets insets = getRootWindowInsets();
+            mInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
+                    insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int count = getChildCount();
+        // find max size
+        int maxWidth = 0;
+        int maxHeight = 0;
+        int childState = 0;
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+                LayoutParams lp = (BoxInsetLayout.LayoutParams) child.getLayoutParams();
+                int marginLeft = 0;
+                int marginRight = 0;
+                int marginTop = 0;
+                int marginBottom = 0;
+                if (mIsRound) {
+                    // round screen, check boxed, don't use margins on boxed
+                    if ((lp.boxedEdges & LayoutParams.BOX_LEFT) == 0) {
+                        marginLeft = lp.leftMargin;
+                    }
+                    if ((lp.boxedEdges & LayoutParams.BOX_RIGHT) == 0) {
+                        marginRight = lp.rightMargin;
+                    }
+                    if ((lp.boxedEdges & LayoutParams.BOX_TOP) == 0) {
+                        marginTop = lp.topMargin;
+                    }
+                    if ((lp.boxedEdges & LayoutParams.BOX_BOTTOM) == 0) {
+                        marginBottom = lp.bottomMargin;
+                    }
+                } else {
+                    // rectangular, ignore boxed, use margins
+                    marginLeft = lp.leftMargin;
+                    marginTop = lp.topMargin;
+                    marginRight = lp.rightMargin;
+                    marginBottom = lp.bottomMargin;
+                }
+                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
+                maxWidth = Math.max(maxWidth, child.getMeasuredWidth() + marginLeft + marginRight);
+                maxHeight = Math.max(maxHeight,
+                        child.getMeasuredHeight() + marginTop + marginBottom);
+                childState = combineMeasuredStates(childState, child.getMeasuredState());
+            }
+        }
+        // Account for padding too
+        maxWidth += getPaddingLeft() + mForegroundPadding.left + getPaddingRight()
+                + mForegroundPadding.right;
+        maxHeight += getPaddingTop() + mForegroundPadding.top + getPaddingBottom()
+                + mForegroundPadding.bottom;
+
+        // Check against our minimum height and width
+        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
+
+        // Check against our foreground's minimum height and width
+        if (mForegroundDrawable != null) {
+            maxHeight = Math.max(maxHeight, mForegroundDrawable.getMinimumHeight());
+            maxWidth = Math.max(maxWidth, mForegroundDrawable.getMinimumWidth());
+        }
+
+        int measuredWidth = resolveSizeAndState(maxWidth, widthMeasureSpec, childState);
+        int measuredHeight = resolveSizeAndState(maxHeight, heightMeasureSpec,
+                childState << MEASURED_HEIGHT_STATE_SHIFT);
+        setMeasuredDimension(measuredWidth, measuredHeight);
+
+        // determine boxed inset
+        int boxInset = calculateInset();
+        // adjust the the children measures, if necessary
+        for (int i = 0; i < count; i++) {
+            measureChild(widthMeasureSpec, heightMeasureSpec, boxInset, i);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        final int count = getChildCount();
+
+        final int parentLeft = getPaddingLeft() + mForegroundPadding.left;
+        final int parentRight = right - left - getPaddingRight() - mForegroundPadding.right;
+
+        final int parentTop = getPaddingTop() + mForegroundPadding.top;
+        final int parentBottom = bottom - top - getPaddingBottom() - mForegroundPadding.bottom;
+
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+                final int width = child.getMeasuredWidth();
+                final int height = child.getMeasuredHeight();
+
+                int childLeft;
+                int childTop;
+
+                int gravity = lp.gravity;
+                if (gravity == -1) {
+                    gravity = DEFAULT_CHILD_GRAVITY;
+                }
+
+                final int layoutDirection = getLayoutDirection();
+                final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+                final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+                final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+                int desiredInset = calculateInset();
+
+                // If the child's width is match_parent then we can ignore gravity.
+                int leftChildMargin = calculateChildLeftMargin(lp, horizontalGravity, desiredInset);
+                int rightChildMargin = calculateChildRightMargin(lp, horizontalGravity,
+                        desiredInset);
+                if (lp.width == LayoutParams.MATCH_PARENT) {
+                    childLeft = parentLeft + leftChildMargin;
+                } else {
+                    switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+                        case Gravity.CENTER_HORIZONTAL:
+                            childLeft = parentLeft + (parentRight - parentLeft - width) / 2
+                                    + leftChildMargin - rightChildMargin;
+                            break;
+                        case Gravity.RIGHT:
+                            childLeft = parentRight - width - rightChildMargin;
+                            break;
+                        case Gravity.LEFT:
+                        default:
+                            childLeft = parentLeft + leftChildMargin;
+                    }
+                }
+
+                // If the child's height is match_parent then we can ignore gravity.
+                int topChildMargin = calculateChildTopMargin(lp, verticalGravity, desiredInset);
+                int bottomChildMargin = calculateChildBottomMargin(lp, verticalGravity,
+                        desiredInset);
+                if (lp.height == LayoutParams.MATCH_PARENT) {
+                    childTop = parentTop + topChildMargin;
+                } else {
+                    switch (verticalGravity) {
+                        case Gravity.CENTER_VERTICAL:
+                            childTop = parentTop + (parentBottom - parentTop - height) / 2
+                                    + topChildMargin - bottomChildMargin;
+                            break;
+                        case Gravity.BOTTOM:
+                            childTop = parentBottom - height - bottomChildMargin;
+                            break;
+                        case Gravity.TOP:
+                        default:
+                            childTop = parentTop + topChildMargin;
+                    }
+                }
+                child.layout(childLeft, childTop, childLeft + width, childTop + height);
+            }
+        }
+    }
+
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams;
+    }
+
+    @Override
+    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        return new LayoutParams(p);
+    }
+
+    private void measureChild(int widthMeasureSpec, int heightMeasureSpec, int desiredMinInset,
+            int i) {
+        final View child = getChildAt(i);
+        final LayoutParams childLayoutParams = (LayoutParams) child.getLayoutParams();
+
+        int gravity = childLayoutParams.gravity;
+        if (gravity == -1) {
+            gravity = DEFAULT_CHILD_GRAVITY;
+        }
+        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+        final int horizontalGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+
+        int childWidthMeasureSpec;
+        int childHeightMeasureSpec;
+
+        int leftParentPadding = getPaddingLeft() + mForegroundPadding.left;
+        int rightParentPadding = getPaddingRight() + mForegroundPadding.right;
+        int topParentPadding = getPaddingTop() + mForegroundPadding.top;
+        int bottomParentPadding = getPaddingBottom() + mForegroundPadding.bottom;
+
+        // adjust width
+        int totalWidthMargin = leftParentPadding + rightParentPadding + calculateChildLeftMargin(
+                childLayoutParams, horizontalGravity, desiredMinInset) + calculateChildRightMargin(
+                childLayoutParams, horizontalGravity, desiredMinInset);
+
+        // adjust height
+        int totalHeightMargin = topParentPadding + bottomParentPadding + calculateChildTopMargin(
+                childLayoutParams, verticalGravity, desiredMinInset) + calculateChildBottomMargin(
+                childLayoutParams, verticalGravity, desiredMinInset);
+
+        childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, totalWidthMargin,
+                childLayoutParams.width);
+        childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, totalHeightMargin,
+                childLayoutParams.height);
+
+        int maxAllowedWidth = getMeasuredWidth() - totalWidthMargin;
+        int maxAllowedHeight = getMeasuredHeight() - totalHeightMargin;
+        if (child.getMeasuredWidth() > maxAllowedWidth
+                || child.getMeasuredHeight() > maxAllowedHeight) {
+            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+        }
+    }
+
+    private int calculateChildLeftMargin(LayoutParams lp, int horizontalGravity, int
+            desiredMinInset) {
+        if (mIsRound && ((lp.boxedEdges & LayoutParams.BOX_LEFT) != 0)) {
+            if (lp.width == LayoutParams.MATCH_PARENT || horizontalGravity == Gravity.LEFT) {
+                return lp.leftMargin + desiredMinInset;
+            }
+        }
+        return lp.leftMargin;
+    }
+
+    private int calculateChildRightMargin(LayoutParams lp, int horizontalGravity, int
+            desiredMinInset) {
+        if (mIsRound && ((lp.boxedEdges & LayoutParams.BOX_RIGHT) != 0)) {
+            if (lp.width == LayoutParams.MATCH_PARENT || horizontalGravity == Gravity.RIGHT) {
+                return lp.rightMargin + desiredMinInset;
+            }
+        }
+        return lp.rightMargin;
+    }
+
+    private int calculateChildTopMargin(LayoutParams lp, int verticalGravity, int desiredMinInset) {
+        if (mIsRound && ((lp.boxedEdges & LayoutParams.BOX_TOP) != 0)) {
+            if (lp.height == LayoutParams.MATCH_PARENT || verticalGravity == Gravity.TOP) {
+                return lp.topMargin + desiredMinInset;
+            }
+        }
+        return lp.topMargin;
+    }
+
+    private int calculateChildBottomMargin(LayoutParams lp, int verticalGravity, int
+            desiredMinInset) {
+        if (mIsRound && ((lp.boxedEdges & LayoutParams.BOX_BOTTOM) != 0)) {
+            if (lp.height == LayoutParams.MATCH_PARENT || verticalGravity == Gravity.BOTTOM) {
+                return lp.bottomMargin + desiredMinInset;
+            }
+        }
+        return lp.bottomMargin;
+    }
+
+    private int calculateInset() {
+        // TODO: This should take the measured width/height as parameters.
+        int rightEdge = Math.min(getMeasuredWidth(), mScreenWidth);
+        int bottomEdge = Math.min(getMeasuredHeight(), mScreenHeight);
+        return (int) (FACTOR * Math.max(rightEdge, bottomEdge));
+    }
+
+    /**
+     * Per-child layout information for layouts that support margins, gravity and boxedEdges.
+     * See {@link R.styleable#BoxInsetLayout_Layout BoxInsetLayout Layout Attributes} for a list
+     * of all child view attributes that this class supports.
+     *
+     * @attr ref R.styleable#BoxInsetLayout_Layout_boxedEdges
+     */
+    public static class LayoutParams extends FrameLayout.LayoutParams {
+
+        /** @hide */
+        @IntDef({BOX_NONE, BOX_LEFT, BOX_TOP, BOX_RIGHT, BOX_BOTTOM, BOX_ALL})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface BoxedEdges {}
+
+        /** Default boxing setting. There are no insets forced on the child views. */
+        public static final int BOX_NONE = 0x0;
+        /** The view will force an inset on the left edge of the children. */
+        public static final int BOX_LEFT = 0x01;
+        /** The view will force an inset on the top edge of the children. */
+        public static final int BOX_TOP = 0x02;
+        /** The view will force an inset on the right edge of the children. */
+        public static final int BOX_RIGHT = 0x04;
+        /** The view will force an inset on the bottom edge of the children. */
+        public static final int BOX_BOTTOM = 0x08;
+        /** The view will force an inset on all of the edges of the children. */
+        public static final int BOX_ALL = 0x0F;
+
+        /** Specifies the screen-specific insets for each of the child edges. */
+        @BoxedEdges
+        public int boxedEdges = BOX_NONE;
+
+        /**
+         * Creates a new set of layout parameters. The values are extracted from the supplied
+         * attributes set and context.
+         *
+         * @param context the application environment
+         * @param attrs the set of attributes from which to extract the layout parameters' values
+         */
+        @SuppressWarnings("ResourceType")
+        public LayoutParams(@NonNull Context context, @Nullable AttributeSet attrs) {
+            super(context, attrs);
+            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BoxInsetLayout_Layout,
+                    0, 0);
+            boxedEdges = a.getInt(R.styleable.BoxInsetLayout_Layout_boxedEdges, BOX_NONE);
+            a.recycle();
+        }
+
+        /**
+         * Creates a new set of layout parameters with the specified width and height.
+         *
+         * @param width the width, either {@link #MATCH_PARENT},
+         *              {@link #WRAP_CONTENT} or a fixed size in pixels
+         * @param height the height, either {@link #MATCH_PARENT},
+         *               {@link #WRAP_CONTENT} or a fixed size in pixelsy
+         */
+        public LayoutParams(int width, int height) {
+            super(width, height);
+        }
+
+        /**
+         * Creates a new set of layout parameters with the specified width, height
+         * and gravity.
+         *
+         * @param width the width, either {@link #MATCH_PARENT},
+         *              {@link #WRAP_CONTENT} or a fixed size in pixels
+         * @param height the height, either {@link #MATCH_PARENT},
+         *               {@link #WRAP_CONTENT} or a fixed size in pixels
+         * @param gravity the gravity
+         *
+         * @see android.view.Gravity
+         */
+        public LayoutParams(int width, int height, int gravity) {
+            super(width, height, gravity);
+        }
+
+
+        public LayoutParams(int width, int height, int gravity, @BoxedEdges int boxed) {
+            super(width, height, gravity);
+            boxedEdges = boxed;
+        }
+
+        /**
+         * Copy constructor. Clones the width and height of the source.
+         *
+         * @param source The layout params to copy from.
+         */
+        public LayoutParams(@NonNull ViewGroup.LayoutParams source) {
+            super(source);
+        }
+
+        /**
+         * Copy constructor. Clones the width, height and margin values.
+         *
+         * @param source The layout params to copy from.
+         */
+        public LayoutParams(@NonNull ViewGroup.MarginLayoutParams source) {
+            super(source);
+        }
+
+        /**
+         * Copy constructor. Clones the width, height, margin values, and
+         * gravity of the source.
+         *
+         * @param source The layout params to copy from.
+         */
+        public LayoutParams(@NonNull FrameLayout.LayoutParams source) {
+            super(source);
+        }
+
+        /**
+         * Copy constructor. Clones the width, height, margin values, boxedEdges and
+         * gravity of the source.
+         *
+         * @param source The layout params to copy from.
+         */
+        public LayoutParams(@NonNull LayoutParams source) {
+            super(source);
+            this.boxedEdges = source.boxedEdges;
+            this.gravity = source.gravity;
+        }
+    }
+}
diff --git a/documents-archive/tests/Android.mk b/wearable/tests/Android.mk
similarity index 71%
rename from documents-archive/tests/Android.mk
rename to wearable/tests/Android.mk
index 84cc3c3..41e00fb 100644
--- a/documents-archive/tests/Android.mk
+++ b/wearable/tests/Android.mk
@@ -17,13 +17,22 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := tests
+
 LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-test \
-    android-support-documents-archive
-LOCAL_AAPT_FLAGS := --auto-add-overlay -0 zip
-LOCAL_PACKAGE_NAME := AndroidSupportDocumentsArchiveTests
+
+LOCAL_RESOURCE_DIR := \
+    $(LOCAL_PATH)/res \
+    $(LOCAL_PATH)/../res
+
+LOCAL_STATIC_JAVA_LIBRARIES  := \
+        android-support-wearable \
+        android-support-annotations
+
+LOCAL_PACKAGE_NAME := WearableViewTests
+LOCAL_AAPT_FLAGS := \
+        --auto-add-overlay \
+        --extra-packages android.support.wearable.view
 
 include $(BUILD_PACKAGE)
diff --git a/wearable/tests/AndroidManifest.xml b/wearable/tests/AndroidManifest.xml
new file mode 100644
index 0000000..64dbe40
--- /dev/null
+++ b/wearable/tests/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:tools="http://schemas.android.com/tools"
+          package="android.support.wearable.test">
+    <uses-sdk android:minSdkVersion="20"
+              android:targetSdkVersion="23"
+              tools:overrideLibrary="android.support.test,
+                      android.app, android.support.test.rule, android.support.test.espresso,
+                      android.support.test.espresso.idling"/>
+
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+    <application android:supportsRtl="true"
+        android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen">
+        <uses-library android:name="android.test.runner"/>
+        <activity android:name="android.support.wearable.view.LayoutTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+         </activity>
+    </application>
+</manifest>
diff --git a/v8/Android.mk b/wearable/tests/NO_DOCS
similarity index 69%
copy from v8/Android.mk
copy to wearable/tests/NO_DOCS
index 14ff0aa..092a39c 100644
--- a/v8/Android.mk
+++ b/wearable/tests/NO_DOCS
@@ -1,4 +1,4 @@
-# Copyright (C) 2014 The Android Open Source Project
+# Copyright (C) 2016 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.
@@ -12,5 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH:= $(call my-dir)
-include $(call all-makefiles-under,$(LOCAL_PATH))
+Having this file, named NO_DOCS, in a directory will prevent
+Android javadocs from being generated for java files under
+the directory. This is especially useful for test projects.
diff --git a/wearable/tests/res/layout/box_inset_layout_testcase_1.xml b/wearable/tests/res/layout/box_inset_layout_testcase_1.xml
new file mode 100644
index 0000000..3c2bec9
--- /dev/null
+++ b/wearable/tests/res/layout/box_inset_layout_testcase_1.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/box">
+
+    <FrameLayout
+        android:id="@+id/child1"
+        app:boxedEdges="bottom|right"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <TextView
+            android:id="@+id/content1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="bottom|right"
+            android:text="Test Case 1"/>
+    </FrameLayout>
+
+</android.support.wearable.view.BoxInsetLayout>
diff --git a/wearable/tests/res/layout/box_inset_layout_testcase_2.xml b/wearable/tests/res/layout/box_inset_layout_testcase_2.xml
new file mode 100644
index 0000000..839667c
--- /dev/null
+++ b/wearable/tests/res/layout/box_inset_layout_testcase_2.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.wearable.view.BoxInsetLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/box">
+
+    <FrameLayout
+        app:boxedEdges="all"
+        android:id="@+id/child1"
+        android:layout_width="match_parent"
+        android:layout_height="60dp"
+        android:layout_gravity="top">
+        <TextView
+            android:id="@+id/content1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="top|right"
+            android:text="Top Right"/>
+    </FrameLayout>
+
+    <FrameLayout
+        app:boxedEdges="all"
+        android:id="@+id/child2"
+        android:layout_width="match_parent"
+        android:layout_height="60dp"
+        android:layout_gravity="bottom">
+        <TextView
+            android:id="@+id/content2"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="bottom|left"
+            android:text="Bottom Left"/>
+    </FrameLayout>
+
+    <FrameLayout
+        app:boxedEdges="all"
+        android:id="@+id/child3"
+        android:layout_width="wrap_content"
+        android:layout_height="20dp"
+        android:layout_gravity="left|center_vertical">
+        <TextView
+            android:id="@+id/content3"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center_vertical|left"
+            android:text="Left"/>
+    </FrameLayout>
+
+    <FrameLayout
+        app:boxedEdges="all"
+        android:id="@+id/child4"
+        android:layout_width="wrap_content"
+        android:layout_height="20dp"
+        android:layout_gravity="right|center_vertical">
+        <TextView
+            android:id="@+id/content4"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center_vertical|right"
+            android:text="Right"/>
+    </FrameLayout>
+
+
+</android.support.wearable.view.BoxInsetLayout>
diff --git a/wearable/tests/res/layout/box_inset_layout_testcase_3.xml b/wearable/tests/res/layout/box_inset_layout_testcase_3.xml
new file mode 100644
index 0000000..350de13
--- /dev/null
+++ b/wearable/tests/res/layout/box_inset_layout_testcase_3.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.wearable.view.BoxInsetLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/box">
+
+    <FrameLayout
+        app:boxedEdges="all"
+        android:id="@+id/child1"
+        android:layout_gravity="top|left"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <TextView
+            android:id="@+id/content1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="Top Left"/>
+    </FrameLayout>
+
+    <FrameLayout
+        app:boxedEdges="all"
+        android:id="@+id/child2"
+        android:layout_gravity="top|right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <TextView
+            android:id="@+id/content2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="Top Right"/>
+    </FrameLayout>
+
+    <FrameLayout
+        app:boxedEdges="all"
+        android:id="@+id/child3"
+        android:layout_gravity="bottom|right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <TextView
+            android:id="@+id/content3"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="Bottom Right"/>
+    </FrameLayout>
+
+    <FrameLayout
+        app:boxedEdges="all"
+        android:id="@+id/child4"
+        android:layout_gravity="bottom|left"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <TextView
+            android:id="@+id/content4"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="Bottom Left"/>
+    </FrameLayout>
+
+</android.support.wearable.view.BoxInsetLayout>
diff --git a/wearable/tests/res/layout/box_inset_layout_testcase_4.xml b/wearable/tests/res/layout/box_inset_layout_testcase_4.xml
new file mode 100644
index 0000000..a702e4c
--- /dev/null
+++ b/wearable/tests/res/layout/box_inset_layout_testcase_4.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <android.support.wearable.view.BoxInsetLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:id="@+id/child1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Super long text Super long text Super long text Super long text
+            Super long text Super long text Super long text Super long text Super long text
+            Super long text Super long text Super long text Super long text Super long text
+            Super long text Super long text Super long text Super long text Super long text
+            Super long text Super long text Super long text Super long text Super long text
+            Super long text Super long text Super long text Super long text Super long text
+            Super long text Super long text Super long text Super long text Super long text
+            Super long text Super long text Super long text Super long text Super long text
+            Super long text Super long text Super long text Super long text Super long text
+            Super long text Super long text Super long text Super long text Super long text
+            Super long text Super long text "
+            app:boxedEdges="left|right" />
+
+
+    </android.support.wearable.view.BoxInsetLayout>
+
+</ScrollView>
diff --git a/wearable/tests/src/android/support/wearable/view/BoxInsetLayoutTest.java b/wearable/tests/src/android/support/wearable/view/BoxInsetLayoutTest.java
new file mode 100644
index 0000000..b692f2f
--- /dev/null
+++ b/wearable/tests/src/android/support/wearable/view/BoxInsetLayoutTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.wearable.view;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.wearable.view.util.MoreViewAssertions.approximateBottom;
+import static android.support.wearable.view.util.MoreViewAssertions.approximateTop;
+import static android.support.wearable.view.util.MoreViewAssertions.bottom;
+import static android.support.wearable.view.util.MoreViewAssertions.left;
+import static android.support.wearable.view.util.MoreViewAssertions.right;
+import static android.support.wearable.view.util.MoreViewAssertions.screenBottom;
+import static android.support.wearable.view.util.MoreViewAssertions.screenLeft;
+import static android.support.wearable.view.util.MoreViewAssertions.screenRight;
+import static android.support.wearable.view.util.MoreViewAssertions.screenTop;
+import static android.support.wearable.view.util.MoreViewAssertions.top;
+
+import static org.hamcrest.Matchers.closeTo;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.wearable.test.R;
+import android.support.wearable.view.util.WakeLockRule;
+import android.util.DisplayMetrics;
+import android.view.View;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class BoxInsetLayoutTest {
+    private static final float FACTOR = 0.146467f; //(1 - sqrt(2)/2)/2
+
+    @Rule
+    public final WakeLockRule wakeLock = new WakeLockRule();
+
+    @Rule
+    public final ActivityTestRule<LayoutTestActivity> activityRule = new ActivityTestRule<>(
+            LayoutTestActivity.class, true, false);
+
+    @Test
+    public void testCase1() {
+        activityRule.launchActivity(new Intent().putExtra(LayoutTestActivity
+                .EXTRA_LAYOUT_RESOURCE_ID, R.layout.box_inset_layout_testcase_1));
+        DisplayMetrics dm = InstrumentationRegistry.getTargetContext().getResources()
+                .getDisplayMetrics();
+        int boxInset = (int) (FACTOR * Math.min(dm.widthPixels, dm.heightPixels));
+
+        int desiredPadding = 0;
+        if (activityRule.getActivity().getResources().getConfiguration().isScreenRound()) {
+            desiredPadding = boxInset;
+        }
+
+        // Child 1 is match_parent width and height
+        // layout_box=right|bottom
+        // Padding of boxInset should be added to the right and bottom sides only
+        onView(withId(R.id.child1)).check(left(equalTo(0))).check(top(equalTo(0))).check(
+                right(equalTo(dm.widthPixels - desiredPadding))).check(
+                bottom(equalTo(dm.heightPixels - desiredPadding)));
+
+        // Content 1 is is width and height match_parent
+        // The bottom and right sides should be inset by boxInset pixels due to padding
+        // on the parent view
+        onView(withId(R.id.content1)).check(screenLeft(equalTo(0))).check(
+                screenTop(equalTo(0))).check(
+                screenRight(equalTo(dm.widthPixels - desiredPadding))).check(
+                screenBottom(equalTo(dm.heightPixels - desiredPadding)));
+    }
+
+    @Test
+    public void testCase2() {
+        activityRule.launchActivity(
+                new Intent().putExtra(LayoutTestActivity.EXTRA_LAYOUT_RESOURCE_ID,
+                        R.layout.box_inset_layout_testcase_2));
+        DisplayMetrics dm =
+                InstrumentationRegistry.getTargetContext().getResources().getDisplayMetrics();
+        int boxInset = (int) (FACTOR * Math.min(dm.widthPixels, dm.heightPixels));
+
+        int desiredPadding = 0;
+        if (activityRule.getActivity().getResources().getConfiguration().isScreenRound()) {
+            desiredPadding = boxInset;
+        }
+
+        View child1 = activityRule.getActivity().findViewById(R.id.child1);
+        View child2 = activityRule.getActivity().findViewById(R.id.child2);
+        View child3 = activityRule.getActivity().findViewById(R.id.child3);
+        View child4 = activityRule.getActivity().findViewById(R.id.child4);
+        // Child 1 is width match_parent, height=60dp, gravity top
+        // layout_box=all means it should have padding added to left, top and right
+        onView(withId(R.id.child1)).check(left(is(equalTo(desiredPadding)))).check(
+                top(is(equalTo(desiredPadding)))).check(
+                right(is(equalTo(dm.widthPixels - desiredPadding)))).check(
+                bottom(is(equalTo(desiredPadding + child1.getHeight()))));
+
+        // Content 1 is width and height match_parent
+        // the left top and right edges should be inset by boxInset pixels, due to
+        // padding in the parent
+        onView(withId(R.id.content1)).check(screenLeft(equalTo(desiredPadding))).check(
+                screenTop(equalTo(desiredPadding))).check(
+                screenRight(equalTo(dm.widthPixels - desiredPadding)));
+
+        // Child 2 is width match_parent, height=60dp, gravity bottom
+        // layout_box=all means it should have padding added to left, bottom and right
+        onView(withId(R.id.child2)).check(left(is(equalTo(desiredPadding)))).check(
+                top(is(equalTo(dm.heightPixels - desiredPadding - child2.getHeight())))).check(
+                right(is(equalTo(dm.widthPixels - desiredPadding)))).check(
+                bottom(is(equalTo(dm.heightPixels - desiredPadding))));
+
+        // Content 2 is width and height match_parent
+        // the left bottom and right edges should be inset by boxInset pixels, due to
+        // padding in the parent
+        onView(withId(R.id.content2)).check(screenLeft(equalTo(desiredPadding))).check(
+                screenRight(equalTo(dm.widthPixels - desiredPadding))).check(
+                screenBottom(equalTo(dm.heightPixels - desiredPadding)));
+
+        // Child 3 is width wrap_content, height=20dp, gravity left|center_vertical.
+        // layout_box=all means it should have padding added to left
+        // marginLeft be ignored due to gravity and layout_box=all (screenLeft=0)
+        onView(withId(R.id.child3)).check(left(is(equalTo(desiredPadding)))).check(approximateTop(
+                is(closeTo((dm.heightPixels / 2 - child3.getHeight() / 2), 1)))).check(
+                right(is(equalTo(desiredPadding + child3.getWidth())))).check(
+                approximateBottom(is(closeTo((dm.heightPixels / 2 + child3.getHeight() / 2), 1))));
+
+        // Content 3 width and height match_parent
+        // the left edge should be offset from the screen edge by boxInset pixels, due to left on
+        // the parent
+        onView(withId(R.id.content3)).check(screenLeft(equalTo(desiredPadding)));
+
+        // Child 4 is width wrap_content, height=20dp, gravity right|center_vertical.
+        // layout_box=all means it should have padding added to right
+        // it should have marginRight ignored due to gravity and layout_box=all (screenRight=max)
+        onView(withId(R.id.child4)).check(
+                left(is(dm.widthPixels - desiredPadding - child4.getWidth()))).check(approximateTop(
+                is(closeTo((dm.heightPixels / 2 - child3.getHeight() / 2), 1)))).check(
+                right(is(equalTo(dm.widthPixels - desiredPadding)))).check(
+                approximateBottom(is(closeTo((dm.heightPixels / 2 + child4.getHeight() / 2), 1))));
+
+        // Content 4 width and height wrap_content
+        // the right edge should be offset from the screen edge by boxInset pixels, due to
+        // right on the parent
+        onView(withId(R.id.content4)).check(screenRight(equalTo(dm.widthPixels - desiredPadding)));
+    }
+
+    @Test
+    public void testCase3() {
+        activityRule.launchActivity(
+                new Intent().putExtra(LayoutTestActivity.EXTRA_LAYOUT_RESOURCE_ID,
+                        R.layout.box_inset_layout_testcase_3));
+        DisplayMetrics dm =
+                InstrumentationRegistry.getTargetContext().getResources().getDisplayMetrics();
+        int boxInset = (int) (FACTOR * Math.min(dm.widthPixels, dm.heightPixels));
+
+        int desiredPadding = 0;
+        if (activityRule.getActivity().getResources().getConfiguration().isScreenRound()) {
+            desiredPadding = boxInset;
+        }
+
+        View child1 = activityRule.getActivity().findViewById(R.id.child1);
+        View child2 = activityRule.getActivity().findViewById(R.id.child2);
+        View child3 = activityRule.getActivity().findViewById(R.id.child3);
+        View child4 = activityRule.getActivity().findViewById(R.id.child4);
+
+        // Child 1 is width and height wrap_content
+        // gravity is top|left, position should be 0,0 on screen
+        onView(withId(R.id.child1)).check(left(is(equalTo(desiredPadding)))).check(
+                top(is(equalTo(desiredPadding)))).check(
+                right(is(equalTo(desiredPadding + child1.getWidth())))).check(
+                bottom(is(equalTo(desiredPadding + child1.getHeight()))));
+
+        // Content 1 is width and height wrap_content
+        // the left and top edges should be offset from the screen edges by boxInset pixels
+        onView(withId(R.id.content1)).check(screenLeft(equalTo(desiredPadding))).check(
+                screenTop(equalTo(desiredPadding)));
+
+        // Child 2 is width and height wrap_content
+        // gravity is top|right, position should be 0,max on screen
+        onView(withId(R.id.child2)).check(
+                left(is(equalTo(dm.widthPixels - desiredPadding - child2.getWidth())))).check(
+                top(is(equalTo(desiredPadding)))).check(
+                right(is(equalTo(dm.widthPixels - desiredPadding)))).check(
+                bottom(is(equalTo(desiredPadding + child2.getHeight()))));
+
+        // Content 2 is width and height wrap_content
+        // the top and right edges should be offset from the screen edges by boxInset pixels
+        onView(withId(R.id.content2)).check(screenTop(equalTo(desiredPadding))).check(
+                screenRight(equalTo(dm.widthPixels - desiredPadding)));
+
+        // Child 3 is width and height wrap_content
+        // gravity is bottom|right, position should be max,max on screen
+        onView(withId(R.id.child3)).check(
+                left(is(equalTo(dm.widthPixels - desiredPadding - child3.getWidth())))).check(
+                top(is(equalTo(dm.heightPixels - desiredPadding - child3.getHeight())))).check(
+                right(is(equalTo(dm.widthPixels - desiredPadding)))).check(
+                bottom(is(equalTo(dm.heightPixels - desiredPadding))));
+
+        // Content 3 is width and height wrap_content
+        // the right and bottom edges should be offset from the screen edges by boxInset pixels
+        onView(withId(R.id.content3)).check(
+                screenBottom(equalTo(dm.heightPixels - desiredPadding))).check(
+                screenRight(equalTo(dm.widthPixels - desiredPadding)));
+
+        // Child 4 is width and height wrap_content
+        // gravity is bottom|left, position should be max,0 on screen
+        onView(withId(R.id.child4)).check(left(is(equalTo(desiredPadding)))).check(
+                top(is(equalTo(dm.heightPixels - desiredPadding - child4.getHeight())))).check(
+                right(is(equalTo(desiredPadding + child4.getWidth())))).check(
+                bottom(is(equalTo(dm.heightPixels - desiredPadding))));
+
+        // Content 3 is width and height wrap_content
+        // the bottom and left edges should be offset from the screen edges by boxInset pixels
+        onView(withId(R.id.content4)).check(
+                screenBottom(equalTo(dm.heightPixels - desiredPadding))).check(
+                screenLeft(equalTo(desiredPadding)));
+    }
+
+    @Test
+    public void testCase4() {
+        activityRule.launchActivity(new Intent().putExtra(LayoutTestActivity
+                .EXTRA_LAYOUT_RESOURCE_ID, R.layout.box_inset_layout_testcase_4));
+        DisplayMetrics dm = InstrumentationRegistry.getTargetContext().getResources()
+                .getDisplayMetrics();
+        int boxInset = (int) (FACTOR * Math.min(dm.widthPixels, dm.heightPixels));
+
+        int desiredPadding = 0;
+        if (activityRule.getActivity().getResources().getConfiguration().isScreenRound()) {
+            desiredPadding = boxInset;
+        }
+
+        View container = activityRule.getActivity().findViewById(R.id.container);
+        View child1 = activityRule.getActivity().findViewById(R.id.child1);
+        // Child 1 is match_parent width and wrap_content height
+        // layout_box=right|left
+        // Padding of boxInset should be added to the right and bottom sides only
+        onView(withId(R.id.child1)).check(left(equalTo(desiredPadding))).check(
+                top(equalTo(container.getTop()))).check(
+                right(equalTo(dm.widthPixels - desiredPadding))).check(
+                bottom(equalTo(container.getTop() + child1.getHeight())));
+    }
+}
diff --git a/wearable/tests/src/android/support/wearable/view/LayoutTestActivity.java b/wearable/tests/src/android/support/wearable/view/LayoutTestActivity.java
new file mode 100644
index 0000000..3fa7396
--- /dev/null
+++ b/wearable/tests/src/android/support/wearable/view/LayoutTestActivity.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.wearable.view;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class LayoutTestActivity extends Activity {
+    public static final String EXTRA_LAYOUT_RESOURCE_ID = "layout_resource_id";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = getIntent();
+        if (!intent.hasExtra(EXTRA_LAYOUT_RESOURCE_ID)) {
+            throw new IllegalArgumentException(
+                    "Intent extras must contain EXTRA_LAYOUT_RESOURCE_ID");
+        }
+        int layoutId = intent.getIntExtra(EXTRA_LAYOUT_RESOURCE_ID, -1);
+        setContentView(layoutId);
+    }
+}
diff --git a/wearable/tests/src/android/support/wearable/view/util/MoreViewAssertions.java b/wearable/tests/src/android/support/wearable/view/util/MoreViewAssertions.java
new file mode 100644
index 0000000..54fb89f
--- /dev/null
+++ b/wearable/tests/src/android/support/wearable/view/util/MoreViewAssertions.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.wearable.view.util;
+
+import static android.support.test.espresso.matcher.ViewMatchers.assertThat;
+
+import android.support.test.espresso.NoMatchingViewException;
+
+import android.support.test.espresso.ViewAssertion;
+import android.support.test.espresso.util.HumanReadables;
+
+import android.util.Log;
+import android.view.View;
+
+import org.hamcrest.Matcher;
+
+public class MoreViewAssertions {
+
+    public static final String TAG = "bilt";
+
+    public static ViewAssertion left(final Matcher<Integer> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                Log.d(TAG, "l: " + view.getPaddingLeft());
+                assertThat("View left: " + HumanReadables.describe(view), view.getLeft(), matcher);
+            }
+        };
+    }
+
+    public static ViewAssertion approximateTop(final Matcher<Double> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                Log.d(TAG, "t: " + view.getPaddingTop());
+                assertThat("View top: " + HumanReadables.describe(view), ((double) view.getTop()),
+                        matcher);
+            }
+        };
+    }
+
+    public static ViewAssertion top(final Matcher<Integer> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                Log.d(TAG, "t: " + view.getPaddingTop());
+                assertThat("View top: " + HumanReadables.describe(view), view.getTop(), matcher);
+            }
+        };
+    }
+
+    public static ViewAssertion right(final Matcher<Integer> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                Log.d(TAG, "r: " + view.getPaddingRight());
+                assertThat("View right: " + HumanReadables.describe(view), view.getRight(),
+                        matcher);
+            }
+        };
+    }
+
+    public static ViewAssertion bottom(final Matcher<Integer> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                Log.d(TAG, "b: " + view.getBottom());
+                assertThat("View bottom: " + HumanReadables.describe(view), view.getBottom(),
+                        matcher);
+            }
+        };
+    }
+
+    public static ViewAssertion approximateBottom(final Matcher<Double> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                Log.d(TAG, "b: " + view.getBottom());
+                assertThat("View bottom: " + HumanReadables.describe(view), ((double) view
+                        .getBottom()), matcher);
+            }
+        };
+    }
+
+    /**
+     * Returns a new ViewAssertion against a match of the view's left position, relative to the
+     * left
+     * edge of the containing window.
+     *
+     * @param matcher matcher for the left position
+     */
+    public static ViewAssertion screenLeft(final Matcher<Integer> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                int[] screenXy = {0, 0};
+                view.getLocationInWindow(screenXy);
+                assertThat("View screenLeft: " + HumanReadables.describe(view), screenXy[0],
+                        matcher);
+            }
+        };
+    }
+
+    /**
+     * Returns a new ViewAssertion against a match of the view's top position, relative to the top
+     * edge of the containing window.
+     *
+     * @param matcher matcher for the top position
+     */
+    public static ViewAssertion screenTop(final Matcher<Integer> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                int[] screenXy = {0, 0};
+                view.getLocationInWindow(screenXy);
+                assertThat("View screenTop: " + HumanReadables.describe(view), screenXy[1],
+                        matcher);
+            }
+        };
+    }
+
+    /**
+     * Returns a new ViewAssertion against a match of the view's right position, relative to the
+     * left
+     * edge of the containing window.
+     *
+     * @param matcher matcher for the right position
+     */
+    public static ViewAssertion screenRight(final Matcher<Integer> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                int[] screenXy = {0, 0};
+                view.getLocationInWindow(screenXy);
+                assertThat("View screenRight: " + HumanReadables.describe(view),
+                        screenXy[0] + view.getWidth(), matcher);
+            }
+        };
+    }
+
+    /**
+     * Returns a new ViewAssertion against a match of the view's bottom position, relative to the
+     * top
+     * edge of the containing window.
+     *
+     * @param matcher matcher for the bottom position
+     */
+    public static ViewAssertion screenBottom(final Matcher<Integer> matcher) {
+        return new ViewAssertion() {
+            @Override
+            public void check(View view, NoMatchingViewException noViewException) {
+                int[] screenXy = {0, 0};
+                view.getLocationInWindow(screenXy);
+                assertThat("View screenBottom: " + HumanReadables.describe(view),
+                        screenXy[1] + view.getHeight(), matcher);
+            }
+        };
+    }
+}
diff --git a/wearable/tests/src/android/support/wearable/view/util/WakeLockRule.java b/wearable/tests/src/android/support/wearable/view/util/WakeLockRule.java
new file mode 100644
index 0000000..9b806f4
--- /dev/null
+++ b/wearable/tests/src/android/support/wearable/view/util/WakeLockRule.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.wearable.view.util;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Rule which holds a wake lock for the duration of the test.
+ */
+public class WakeLockRule implements TestRule {
+    @SuppressWarnings("deprecation")
+    private static final int WAKELOCK_FLAGS =
+            PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
+
+    @Override
+    public Statement apply(final Statement statement, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                WakeLock wakeLock = createWakeLock();
+                wakeLock.acquire();
+                try {
+                    statement.evaluate();
+                } finally {
+                    wakeLock.release();
+                }
+            }
+        };
+    }
+
+    private WakeLock createWakeLock() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        PowerManager power = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        return power.newWakeLock(WAKELOCK_FLAGS, context.getPackageName());
+    }
+}